How do you quit a Forth environment? - forth

If I am in a Forth environment, how do I leave, and how do I program a word to leave?

There are two ways to 'leave' Forth code, depending on what you need to do.
BYE
The Forth standard defines the word BYE to leave the Forth environment itself.
BYE ( -- )
Return control to the host operating system, if any.
This word gets a lot of creative interpretations when your Forth is not running as a program in an operating system. For example, on some systems where Forth is the operating system, BYE causes the system to restart instead, letting you load another OS.
BYE is part of the Programming-Tools Extensions word set.
QUIT
There is a word in the Core word set called QUIT, but it does not leave the environment. Instead, it leaves execution of a word and returns you back to the interpreter. This is why it is called 'QUIT', it is quitting in another sense.
QUIT ( -- ) ( R: i*x -- )
Empty the return stack, store zero in SOURCE-ID if it is present, make user input device the input source, and enter interpretation state. Do not display a message. Repeat the following:
Accept a line from the input source into the input buffer, set >IN to zero, and interpret.
Display the implementation-defined system prompt if in interpretation state, all processing has been completed, and no ambiguous condition exists.
Rather than defining QUIT as something like "this word returns you to the interpreter", instead QUIT is really defined as the interpreter itself in the Forth standard. In a factored Forth implementation, this makes sense: the word that puts you back in the interpreter and the interpreter itself can be the same word, they both can just clear the return stack and start interpreting.
And QUIT is the word you are more likely to see used in colon definitions, because it is a convenient way to break out of a stack of word executions, leaving the current contents of the data stack as-is, and returning to the interpreter. You can, of course, use BYE in a colon definition, for example in a custom interpreter or environment written in Forth to exit back to the operating system.

Related

Console: abort Read or Readln

The console Read command does not recognize VK_ESCAPE. When using ReadConsoleInput, it is case insensitive. Is there something adequate to Read/Readln, which reports an abort?
The docs on Read() tell you it's for characters, not keys in general. It will also not help you to i.e. recognize PgUp or Print. That's also why it is so similar to Readln(), which unsurprisingly is for text, too, not separate keys being pressed.
A console process does not know by default what "abort" means. Common knowledge (even unbound to Windows) is that Ctrl+C and/or Ctrl+Break terminate the process.
Neither a ReadConsoleInput() nor is its KEY_EVENT record case insensitive: again you get keys, not characters. Which means you have to check if .dwControlKeyState has either SHIFT_PRESSED or CAPSLOCK_ON set to translate all the keys into an appropriate character (i.e. only Shift+S makes it an uppercase S).
It's up to you to decide when to interpret keys and when treating input as text/characters. Yes: recognizing Esc while using Readln() will never work - you'd have to reinvent your own Readln(), i.e. dealing with all the input, including your favorite keys, such as Esc. This will also help you discover which keys (that you type) lead to which VK constants.

Informix 4GL report to screen - Reverse

I have a generated report in Informix 4GL that prints to the screen.
I need to have one column displayed in reverse format.
I tried the following:
print line_image attribute(reverse)
But that doesn't work. Is this possible at all?
Adding on to the previous answer, you can try the following
print "\033[7mHello \033[0mWorld"
\033[7m means to print in reverse. And, \033[0m means to go back to standard.
If you mean "is there any way at all to do it", the answer's "yes". If you mean "is there a nice easy built-in way to do it", the answer's "no".
What you'll need to do is:
Determine the character sequence that switches to 'reverse' video — store the characters in a string variable brv (begin reverse video; choose your own name if you don't like mine).
Determine the character sequence that switches to 'normal' video — store the characters in a string variable erv (end reverse video).
Arrange for your printing to use:
PRINT COLUMN 1, first_lot_of_data,
COLUMN 37, brv, reverse_data,
COLUMN 52, erv,
COLUMN 56, next_lot_of_data
There'll probably be 3 or 4 characters needed to switch. Those characters will be counted by the column-counting code in the report.
Different terminal types will have different sequences. These days, the chances are your not dealing with the huge variety of actual green-screen terminals that were prevalent in the mid-80s, so you may be able to hardwire your findings for the brv and erv strings. OTOH, you may have to do some fancy footwork to find the correct sequences for different terminals at runtime. Shout if you need more information on this.
A simple way which might allow you to discover the relevant sequences is to run a program such as (this hasn't been anywhere near an I4GL compiler — there are probably syntax errors in it):
MAIN
DISPLAY "HI" AT 1,1
DISPLAY "REVERSE" AT 1,4 ATTRIBUTE(REVERSE)
DISPLAY "LO" AT 1, 12
SLEEP 2
END MAIN
Compile that into terminfo.4ge and run:
./terminfo.4ge # So you know what the screen looks like
./terminfo.4ge > out.file
There's a chance that won't use the display attributes. You'd see that if you run cat out.file and don't see the reverse flash up, then we have to work harder.
You could also look at the terminal entry in the termcap file or from the terminfo entry. Use infocmp $TERM (with the correct terminal type set in the environment variable) and look for the smso (enter standout mode) and rmso (exit standout mode) capabilities. Decipher those (I have rmso=\E[27m and smso=\E[7m for an xterm-256color terminal; the \E is ASCII ESC or \033) and use them in the brv and erv strings. Note that rmso is 5 characters long.

Ragel - how to return one token at a time

I want to build a one-token-per-call ragel grammar / thing.
I'm relatively new to Ragel (but not new to compilers, etc).
I've written a grammar for a json-like notation (three levels deep). It emits C code.
My input comes in complete strings (no need to cross buffer boundaries).
I want to call my grammar with the input string, have the grammar return one token. Then call it again and have it return the next token and so on. Until end of string. Then, call again with a new string.
One would think that a state machine would be perfectly suited to this kind of behaviour, but I haven't yet been able to figure how to accomplish this in Ragel.
Your best bet is probably to call fbreak after each token, then call the machine again without re-initializing p or cs.
From the (Ragel 6.9) manual:
fbreak; – Advance p, save the target state to cs and immediately break out of the execute loop. This statement is useful in conjunction with the noend write option. Rather than process input until pe is arrived at, the fbreak statement can be used to stop processing from an action. After an fbreak statement the p variable will point to the next character in the input. The current state will be the target of the current transition. Note that fbreak causes the target state’s to-state actions to be skipped.
Note that you don't actually need the noend option. That option is for ignoring pe, which is probably not what you want to do in this case, since you want the parser to be able to detect the end of the string it's parsing.

How to "disable" a file output stream

I'm working on some legacy code in which there are a lot of WriteLn(F, '...') commands scattered pretty much all over the place. There is some useful information in these commands (what information variables contain, etc), so I'd prefer not to delete it or comment it out, but I want to stop the program from writing the file.
Is there any way that I can assign the F variable so that anything written to it is ignored? We use the console output, so that's not an option.
Going back a long long time to the good old days of DOS - If you assign 'f' to the device 'nul', then there should be no output.
assign (f, 'nul')
I don't know whether this still works in Windows.
Edit:
You could also assign 'f' to a file - assignfile (f, 'c:\1.txt') - for example.
Opening the null device and letting output go there would probably work. Under DOS, the performance of the NUL device was astonishingly bad IIRC (from what I understand, it wasn't buffered, so the system had to look up NUL in the device table when processing each byte) but I would not be at all surprised if it's improved under newer systems. In any case, that's probably the easiest thing you can do unless you really need to maximize performance. If performance is critical, it might in theory be possible to override the WriteLn function so it does nothing for certain files, but unfortunately I believe it allows syntax forms that were not permissible for any user-defined functions.
Otherwise, I would suggest doing a regular-expression find/replace to comment out the WriteLn statements in a fashion that can be mechanically restored.

Tex command which affects the next complete word

Is it possible to have a TeX command which will take the whole next word (or the next letters up to but not including the next punctuation symbol) as an argument and not only the next letter or {} group?
I’d like to have a \caps command on certain acronyms but don’t want to type curly brackets over and over.
First of all create your command, for example
\def\capsimpl#1{{\sc #1}}% Your main macro
The solution to catch a space or punctuation:
\catcode`\#=11
\def\addtopunct#1{\expandafter\let\csname punct#\meaning#1\endcsname\let}
\addtopunct{ }
\addtopunct{.} \addtopunct{,} \addtopunct{?}
\addtopunct{!} \addtopunct{;} \addtopunct{:}
\newtoks\capsarg
\def\caps{\capsarg{}\futurelet\punctlet\capsx}
\def\capsx{\expandafter\ifx\csname punct#\meaning\punctlet\endcsname\let
\expandafter\capsend
\else \expandafter\continuecaps\fi}
\def\capsend{\expandafter\capsimpl\expandafter{\the\capsarg}}
\def\continuecaps#1{\capsarg=\expandafter{\the\capsarg#1}\futurelet\punctlet\capsx}
\catcode`\#=12
#Debilski - I wrote something similar to your active * code for the acronyms in my thesis. I activated < and then \def<#1> to print the acronym, as well as the expansion if it's the first time it's encountered. I also went a bit off the deep end by allowing defining the expansions in-line and using the .aux files to send the expansions "back in time" if they're used before they're declared, or to report errors if an acronym is never declared.
Overall, it seemed like it would be a good idea at the time - I rarely needed < to be catcode 12 in my actual text (since all my macros were in a separate .sty file), and I made it behave in math mode, so I couldn't foresee any difficulties. But boy was it brittle... I don't know how many times I accidentally broke my build by changing something seemingly unrelated. So all that to say, be very careful activating characters that are even remotely commonly-used.
On the other hand, with XeTeX and higher unicode characters, it's probably a lot safer, and there are generally easy ways to type these extra characters, such as making a multi (or compose) key (I usually map either numlock or one of the windows keys to this), so that e.g. multi-!-! produces ¡). Or if you're running in emacs, you can use C-\ to switch into TeX input mode briefly to insert unicode by typing the TeX command for it (though this is a pain for actually typing TeX documents, since it intercepts your actual \'s, and please please don't try defining your own escape character!)
Regarding whitespace after commands: see package xspace, and TeX FAQ item Commands gobble following space.
Now why this is very difficult: as you noted yourself, things like that can only be done by changing catcodes, it seems. Catcodes are assigned to characters when TeX reads them, and TeX reads one line at a time, so you can not do anything with other spaces on the same line, IMHO. There might be a way around this, but I do not see it.
Dangerous code below!
This code will do what you want only at the end of the line, so if what you want is more "fluent" typing without brackets, but you are willing to hit 'return' after each acronym (and not run any auto-indent later), you can use this:
\def\caps{\begingroup\catcode`^^20 =11\mcaps}
\def\mcaps#1{\def\next##1 {\sc #1##1\catcode`^^20 =10\endgroup\ }\next}
One solution might be setting another character as active and using this one for escaping. This does not remove the need for a closing character but avoids typing the \caps macro, thus making it overall easier to type.
Therefore under very special circumstances, the following works.
\catcode`\*=\active
\def*#1*{\textsc{\MakeTextLowercase{#1}}}
Now follows an *Acronym*.
Unfortunately, this makes uses of \section*{} impossible without additional macro definitions.
In Xetex, it seems to be possible to exploit unicode characters for this, so one could define
\catcode`\•=\active
\def•#1•{\textsc{\MakeTextLowercase{#1}}}
Now follows an •Acronym•.
Which should reduce the effects on other commands but of course needs to have the character ‘•’ mapped to the keyboard somewhere to be of use.

Resources