ff - A Simple FORTH System========================== Introduction------------ This is `ff`, an implementation of the Forth programming language for 32-bit CPUs on Linux and Plan 9. `ff` is indirect-threaded and currently available for x86 and ARM processors. It is kept intentionally simple to reduce size and complexity to a minimum. Floating-point math and double-precision numbers are not supported and only very limited I/O facilities are provided. On the other hand, the machine-code portion is small and it should be very easy to port `ff` to other architectures. Installation------------ `ff` is available in pre-compiled, binary form and requires no additional libraries, so it is not necessary to build it to get going. The following files are included in the distribution: ff-i386 x86 executable ff-arm ARM executable ff-i386-plan9 x86 executable for Plan 9 README This file ff-i386.s Assembler sources for x86 (NASM syntax) ff-arm.s Assembler sources for ARM (GAS syntax) primitives.s Primitive dictionary words-nasm.s Bootstrapping core dictionary (NASM syntax) words-gas.s Bootstrapping core dictionary (GAS syntax) core.f Core dictionary sources meta.f Meta-compiler sources meta-install.f Meta-compiler installation elf.f Meta-compiler (elf binary generation) cross.f Meta-compiler (Plan 9 a.out binary generation) stuff.f Miscellaneous words blocks.f Block- and buffer words ed.f Block-editor sources robots.f A simple game forth Tcl/Tk frontend x-i386.f Settings for cross-compilation to x86 x-arm.f Settings for cross-compilation to ARM x-i386-plan9.f Settings for cross-compilation to x86 on Plan 9 In case you want to build `ff-*` yourself you will need an assembler - [NASM][1] for the x86 version and [GNU as][2] for ARM, the latter being usually available on an ARM-based linux with development tools installed. ARM `ff` can also easily be cross-assembled from a non-ARM Linux system. The necessary build-commands look like this: nasm -f elf ff-i386.s -o ff-i386.o ld ff-i386.o -o ff-i386 # add "-m elf_i386" on an x86_64 system Or, for an ARM based system: as ff-arm.s -o ff-arm.o ld ff-arm.o -o ff-arm Note that this creates only a minimal Forth system, sufficient to run the metacompiler. To generate or re-generate a complete binary, start the initial executable and enter: include meta.f include elf.f include meta-install.f include core.f <ARCH> msave ff bye where `<ARCH>` should be either `i386` or `arm`, depending on the system this is running on. On Plan 9, re-compilation is slightly different: include meta.f include a.out.f include meta-install.f include core.f msave ff bye The C library (`libc`) is not used, `ff` directly invokes Linux or Plan 9 system-calls. Cross-compilation is similar, but needs an additional file with hard-codedaddresses, together with binaries containing the target-specific machine codeof the kernel in the `boot` directory. So, assuming `ff-arm` is available as `boot/ff-arm`: include meta.f 0 target-endianness \ if target and host have different byte-order \ 0 = big, 1 = little include elf.f include x-arm.f \ or "include x-i386.f" include meta-install.f include core.f arm msave ff \ or "i386 msave ff" bye Again, replace `elf.f` with `a.out.f` and drop the argument to `msave` onPlan 9. Note that ARM/Plan 9 is currently not supported. Porting to other platforms should be straightforward, since the assembler portion is quite small. Porting the system to embedded systems should also don't present any problems - just add or remove primitive words in `ff-*.s` as necessary and metacompile. Some additional files and scripts for building and cross-compilation areavaialble in the [`ff` development repository][5]. Usage----- `ff` reads Forth commands from stdin, interpreting words as they are parsed. A subset of the [Forth ANSI standard][3] is supported, see below for a description of all words that are available. All input is parsed case-sensitively, and the base dictionary contains lowercase words. If one or more command-line arguments are given, then the first argument is loaded as an image-file (using `bload`.) The `forth` script implements a simple text-based front-end for `ff`, and is written in Tcl/Tk. It provides a very basic *terminal* and implements basic text-editing functionality. It defaults to invoking a binary named `ff` which should be in the `PATH` (if it isn't copy or symlink the `ff-*` binary for your architecture) Command-line options that the `forth` script accepts: -background COLORNAME select background color -foreground COLORNAME select foreground color -fontname FONTNAME select font -fontsize FONTSIZE select fontsize -execute FILENAME load Tcl source from FILENAME at startup -ff FILENAME run FILENAME instead of the default "ff" -cd DIRECTORY change working directory to DIRECTORY -init STRING Forth code to be executed on startup -image FILENAME Load image-file on startup (uses "-init") Output from `ff` is appended to any text in the window. The character `^L` (ASCII 12) is handled specially and clears the window. `RETURN` will send the current selection to the Forth interpreter, or the current line if no text is currently selected. Pressing the `Insert` key will enter *hold* mode, which means `RETURN` will just insert a newline, without executing any code. Pressing `Insert` again will send all text beginning from the location where `Insert` was first pressed up to the current cursor position and disable hold mode. Pressing the right mouse button on a word in the window will execute the Forth statement `command <word>`. `command` is a deferred word defined in `stuff.f` that can be used to implement a poor man's menu system by just right-clicking words in the window. Pressing `Escape` terminates the Forth interpreter, pressing it again exitsthe front-end. The function keys can be bound to text that is either inserted at the currentposition, or (if it ends with a newline) immediately executed. To bind a key toa particular sequence, select the text you want to bind and press `Control-F<n>`,where `F<n>` is the function key you want to change. `Control-Up` and `Control-Down` move the currently shown screen, when theblock and editor extensions are loaded. If a file called `.forth` exists in the `HOME` directory, it is loaded before startup and can be used to customize the front-end. Study the source code for `forth` to learn more about it. If the Forth system crashes, the background color turns to black and a message is printed. Press `RETURN` to restart. Unicode support--------------- Partial UTF-8 support is provided: `emit`, `char` and `[char]` encode and decode UTF-8 sequences correctly. `key` does not. The front-end allows entering unicode code-points using the `Delete` key, which accepts either a hexadecimal code-point or a named character. The latter can be defined in your `~/.forth` file by adding a definition for the `snippets` variable, holding lists of 2-element lists: set snippets { {alpha "\u03b1"} ... } Builtin words------------- - Standard words (ANS) Defined in the core system: `!` `#` `#>` `<#` `#s` `'` `(` `*` `+` `+!` `+loop` `,` `-` `.` `."` `.r` `/` `/mod` `0<` `0<>` `0=` `0>` `1+` `1-` `2*` `2/` `2drop` `2dup` `:` `;` `<` `<#` `<>` `=` `>` `>body` `>in` `>r` `?do` `?dup` `@` `[` `[']` `[char]` `\` `]` `abort` `abort"` `abs` `accept` `again` `align` `aligned` `allot` `and` `base` `begin` `bl` `blk` `c!` `c,` `c@` `cell+` `cells` `char` `clear` `close-file` `cmove` `cmove>` `compare` `constant` `count` `cr` `create` `decimal` `defer` `depth` `do` `drop` `dup` `else` `emit` `erase` `execute` `exit` `false` `fill` `find` `h` `here` `hex` `hold` `i` `if` `immediate` `include` `included` `invert` `is` `j` `key` `list` `literal` `load` `loop` `lshift` `max` `min` `mod` `negate` `nip` `off` `on` `open-file` `or` `over` `pad` `page` `pick` `quit` `r/o` `r/w` `r>` `r@` `read-file` `recurse` `refill` `repeat` `reposition-file` `reset` `restore-input` `rot` `rshift` `s"` `save-input` `scr` `search` `sign` `sliteral` `space` `spaces` `state` `string` `swap` `then` `tib` `true` `tuck` `type` `u.` `u.r` `unloop` `until` `unused` `variable` `w/o` `while` `within` `word` `write-file` `xor` `does>` `current` Defined in the source files `stuff.f` and `blocks.f`: `2@` `2!` `2>r` `2r>` `?` `-trailing` `.s` `:noname` `/string` `also` `block` `buffer` `buffer:` `case` `context` `current` `definitions` `dump` `empty-buffers` `endcase` `endof` `forget` `forth` `list` `load` `marker` `of` `only` `order` `postpone` `previous` `scr` `thru` `update` `vocabulary` `words` - Notes: - `while` is only allowed once inside a `begin`/`repeat` construct. - `<#`, `#`, `#s` and `#>` only handle single-precision numbers. - There are no "state-smart" words. `is`, `."` and `s"` are intended to be used inside colon definitions. - Non-standard core words `2nip ( x y -- y )` Drops the 2nd item on the stack. `<builds ( | <word> -- )` Compile-time part of `<builds ... does>` pair. In other Forth systems `create` is normally used for this. `>limit ( -- a )` Variable holding the end-index in the text-input-buffer (TIB). `?stack ( -- )` Aborts on stack-underflow. `(.) ( n1 -- a n2 )` Convert signed number to string and return address and length. `_start ( -- a )` Pushes address of machine-code entry-point. `_end ( -- a )` Pushes end-address of machine-code section. `args ( ... -- )` Pushes a pointer to an array of cells, holding the number of command line arguments, followed by pointers to zero-terminated strings, one for each command-line argument (including the program name), terminated by 0. `boot ( ... -- )` Completely reinitializes the system and invokes `cold`. `bload ( a n -- )` Loads a memory-image from `<filename>` restoring the state at which the image was last saved with `save-image`. Note that image-files are not portable and depend on the executable being exactly the same at both save- and load-time. After loading the image, the deferred word `startup` is invoked. `bye ( -- )` Terminates `ff`. `c" ( | ..." -- a )` Stores a counted string in the dictionary and pushes its address. To be used in interpreted mode. `cas ( a1 x y -- f )` Perform an atomic _compare and swap_ operation on address `a1`, i.e. compares the contents of the given address with `x` and, if it is equal, replaces the stored value with `y`, atomically. Pushes a flag indicating whether the operation succeeded. `cold ( ... -- )` Performs a "cold" start, completely re-initializing the system. `crash ( ... -- )` Called when an uninitialized deferred word is invoked. `halt ( n -- )` Terminate with exit-code `n`. `heaptop ( -- a )` Variable holding the address of the top of the available heap. `interpret ( | ... -- )` Interprets words from the text-input-buffer (TIB). `load-image ( | <filename> -- )` Invokes `bload` with the given filename. `mmap ( a1 -- a2 )` Invokes the Linux `mmap` system call. `a1` should be the address of an `mmap_arg_struct` holding the parameters. See [this page][4] for more details. This word is a no-op on Plan 9. `number ( a n1 -- n2 -1 | a n1 0 )` Parses number given by string and either pushes the parsed number and `true` or keeps the argument items, pushing `false`, if the number is not a valid integer. `parse ( c | ... -- a )` Reads the next characters in the input-stream until character `c` is encountered and returns the address of a counted string. Note that this word is not ANSI compatible (it returns a counted string.) `prompt ( -- )` A deferred word that prints the prompt that is shown when the interpreter waits for input. The default prints ` ok` and advances to a new line. `query ( -- )` Reads a new line from stdin into the TIB. `reveal ( -- )` Exposes the most recent item in the dictionary (see also `smudge`.) `rshifta ( n1 n2 -- n3 )` Performs an arithmetic shift of `n1` by `n2` bits. `s0 ( -- a )` Variable holding the initial stack-pointer. `s@ ( -- a )` Pushes the current stack-pointer. `save-image ( | <filename> -- )` Saves the current dictionary to `<filename>`. `signum ( n1 -- n2 )` Pushes -1, 0 or 1, depending on whether `n1` is negative, zero or positive. `smudge ( -- )` Hides the most recent dictionary entry. `startup ( -- )` Invoked after a binary image is loaded. The default behaviour is to print `"ok "` and invoke `abort`. `u/mod ( u1 u2 -- u3 u4 )` Like `/mod`, but treats arguments as unsigned numbers. `utfdecode ( a1 -- a2 c )` Decodes the UTF-8 byte sequence at address `a1` and returns the address directly after the byte sequence and the unicode code-point. `utfencode ( a c -- a n )` Encodes the unicode code-point `c` as an UTF-8 byte sequence at address `a`, and returns the target address and the number of bytes. - Optional words Some additional words are available in the source files `stuff.f`. Read that file to learn more about what's included. The Block-file Editor--------------------- The system includes an optional simple command-based block-editor inthe file `ed.f`. See below for a list of available editorcommands. Blocks are stored in a file called `blockfile`, which mustreside in the current working directory. Note that the editor needsthe words in `blocks.f`. To create a blockfile, use the following commands # creates a blank file of 1024 blocks: dd if=/dev/zero bs=1024 count=1024 | tr '\000' ' ' >blockfile The editor maintains two buffers, together with the current editedblock (`scr`): the *insertion-buffer* and the *find-buffer*. Theformer is used in commands that add or insert text, the latter holdstext that is searched. The editor is provided in source form in the file `ed.f`. TheANS block- and buffer-related words can be found in `blocks.f`. All editor words exist in the `editor` vocabulary, so execute `editor`before using them. - Editor commands: `b ( -- )` List previous screen. `copy ( n1 n2 -- )` Copies contents of block `n1` to block `n2`. `cut ( -- )` Deletes everything on the line, starting from the current position. `d ( [| ...] -- )` Deletes given text (or last found text). `e ( -- )` Deletes last found text. `f ( [| ...] -- )` Searches given text (or contents of the find-buffer) in current line. `i ( [| ...] -- )` Inserts given text (or contents of the insert-buffer) at current position. `index ( n1 n2 -- )` Shows first lines of blocks in given range. `k ( -- )` Swaps contents of insert- and find-buffer. `l ( -- )` Clears window and lists current screen. `n ( -- )` Lists next screen. `p ( [| ...] -- )` Replaces current line with given text (or contents of the insert-buffer). `r ( [| ...] -- )` Replaces last found text with given text (or contents of the insert-buffer). `s ( n [| ...] -- n )` Searches given text (or contents of find-buffer) in current screen and all blocks up to and including `n`. Lines 1–500 of 1058. Load more
ff - A Simple FORTH System ========================== Introduction ------------ This is `ff`, an implementation of the Forth programming language for 32-bit CPUs on Linux and Plan 9. `ff` is indirect-threaded and currently available for x86 and ARM processors. It is kept intentionally simple to reduce size and complexity to a minimum. Floating-point math and double-precision numbers are not supported and only very limited I/O facilities are provided. On the other hand, the machine-code portion is small and it should be very easy to port `ff` to other architectures. Installation ------------ `ff` is available in pre-compiled, binary form and requires no additional libraries, so it is not necessary to build it to get going. The following files are included in the distribution: ff-i386 x86 executable ff-arm ARM executable ff-i386-plan9 x86 executable for Plan 9 README This file ff-i386.s Assembler sources for x86 (NASM syntax) ff-arm.s Assembler sources for ARM (GAS syntax) primitives.s Primitive dictionary words-nasm.s Bootstrapping core dictionary (NASM syntax) words-gas.s Bootstrapping core dictionary (GAS syntax) core.f Core dictionary sources meta.f Meta-compiler sources meta-install.f Meta-compiler installation elf.f Meta-compiler (elf binary generation) cross.f Meta-compiler (Plan 9 a.out binary generation) stuff.f Miscellaneous words blocks.f Block- and buffer words ed.f Block-editor sources robots.f A simple game forth Tcl/Tk frontend x-i386.f Settings for cross-compilation to x86 x-arm.f Settings for cross-compilation to ARM x-i386-plan9.f Settings for cross-compilation to x86 on Plan 9 In case you want to build `ff-*` yourself you will need an assembler - [NASM][1] for the x86 version and [GNU as][2] for ARM, the latter being usually available on an ARM-based linux with development tools installed. ARM `ff` can also easily be cross-assembled from a non-ARM Linux system. The necessary build-commands look like this: nasm -f elf ff-i386.s -o ff-i386.o ld ff-i386.o -o ff-i386 # add "-m elf_i386" on an x86_64 system Or, for an ARM based system: as ff-arm.s -o ff-arm.o ld ff-arm.o -o ff-arm Note that this creates only a minimal Forth system, sufficient to run the metacompiler. To generate or re-generate a complete binary, start the initial executable and enter: include meta.f include elf.f include meta-install.f include core.f <ARCH> msave ff bye where `<ARCH>` should be either `i386` or `arm`, depending on the system this is running on. On Plan 9, re-compilation is slightly different: include meta.f include a.out.f include meta-install.f include core.f msave ff bye The C library (`libc`) is not used, `ff` directly invokes Linux or Plan 9 system-calls. Cross-compilation is similar, but needs an additional file with hard-coded addresses, together with binaries containing the target-specific machine code of the kernel in the `boot` directory. So, assuming `ff-arm` is available as `boot/ff-arm`: include meta.f 0 target-endianness \ if target and host have different byte-order \ 0 = big, 1 = little include elf.f include x-arm.f \ or "include x-i386.f" include meta-install.f include core.f arm msave ff \ or "i386 msave ff" bye Again, replace `elf.f` with `a.out.f` and drop the argument to `msave` on Plan 9. Note that ARM/Plan 9 is currently not supported. Porting to other platforms should be straightforward, since the assembler portion is quite small. Porting the system to embedded systems should also don't present any problems - just add or remove primitive words in `ff-*.s` as necessary and metacompile. Some additional files and scripts for building and cross-compilation are avaialble in the [`ff` development repository][5]. Usage ----- `ff` reads Forth commands from stdin, interpreting words as they are parsed. A subset of the [Forth ANSI standard][3] is supported, see below for a description of all words that are available. All input is parsed case-sensitively, and the base dictionary contains lowercase words. If one or more command-line arguments are given, then the first argument is loaded as an image-file (using `bload`.) The `forth` script implements a simple text-based front-end for `ff`, and is written in Tcl/Tk. It provides a very basic *terminal* and implements basic text-editing functionality. It defaults to invoking a binary named `ff` which should be in the `PATH` (if it isn't copy or symlink the `ff-*` binary for your architecture) Command-line options that the `forth` script accepts: -background COLORNAME select background color -foreground COLORNAME select foreground color -fontname FONTNAME select font -fontsize FONTSIZE select fontsize -execute FILENAME load Tcl source from FILENAME at startup -ff FILENAME run FILENAME instead of the default "ff" -cd DIRECTORY change working directory to DIRECTORY -init STRING Forth code to be executed on startup -image FILENAME Load image-file on startup (uses "-init") Output from `ff` is appended to any text in the window. The character `^L` (ASCII 12) is handled specially and clears the window. `RETURN` will send the current selection to the Forth interpreter, or the current line if no text is currently selected. Pressing the `Insert` key will enter *hold* mode, which means `RETURN` will just insert a newline, without executing any code. Pressing `Insert` again will send all text beginning from the location where `Insert` was first pressed up to the current cursor position and disable hold mode. Pressing the right mouse button on a word in the window will execute the Forth statement `command <word>`. `command` is a deferred word defined in `stuff.f` that can be used to implement a poor man's menu system by just right-clicking words in the window. Pressing `Escape` terminates the Forth interpreter, pressing it again exits the front-end. The function keys can be bound to text that is either inserted at the current position, or (if it ends with a newline) immediately executed. To bind a key to a particular sequence, select the text you want to bind and press `Control-F<n>`, where `F<n>` is the function key you want to change. `Control-Up` and `Control-Down` move the currently shown screen, when the block and editor extensions are loaded. If a file called `.forth` exists in the `HOME` directory, it is loaded before startup and can be used to customize the front-end. Study the source code for `forth` to learn more about it. If the Forth system crashes, the background color turns to black and a message is printed. Press `RETURN` to restart. Unicode support --------------- Partial UTF-8 support is provided: `emit`, `char` and `[char]` encode and decode UTF-8 sequences correctly. `key` does not. The front-end allows entering unicode code-points using the `Delete` key, which accepts either a hexadecimal code-point or a named character. The latter can be defined in your `~/.forth` file by adding a definition for the `snippets` variable, holding lists of 2-element lists: set snippets { {alpha "\u03b1"} ... } Builtin words ------------- - Standard words (ANS) Defined in the core system: `!` `#` `#>` `<#` `#s` `'` `(` `*` `+` `+!` `+loop` `,` `-` `.` `."` `.r` `/` `/mod` `0<` `0<>` `0=` `0>` `1+` `1-` `2*` `2/` `2drop` `2dup` `:` `;` `<` `<#` `<>` `=` `>` `>body` `>in` `>r` `?do` `?dup` `@` `[` `[']` `[char]` `\` `]` `abort` `abort"` `abs` `accept` `again` `align` `aligned` `allot` `and` `base` `begin` `bl` `blk` `c!` `c,` `c@` `cell+` `cells` `char` `clear` `close-file` `cmove` `cmove>` `compare` `constant` `count` `cr` `create` `decimal` `defer` `depth` `do` `drop` `dup` `else` `emit` `erase` `execute` `exit` `false` `fill` `find` `h` `here` `hex` `hold` `i` `if` `immediate` `include` `included` `invert` `is` `j` `key` `list` `literal` `load` `loop` `lshift` `max` `min` `mod` `negate` `nip` `off` `on` `open-file` `or` `over` `pad` `page` `pick` `quit` `r/o` `r/w` `r>` `r@` `read-file` `recurse` `refill` `repeat` `reposition-file` `reset` `restore-input` `rot` `rshift` `s"` `save-input` `scr` `search` `sign` `sliteral` `space` `spaces` `state` `string` `swap` `then` `tib` `true` `tuck` `type` `u.` `u.r` `unloop` `until` `unused` `variable` `w/o` `while` `within` `word` `write-file` `xor` `does>` `current` Defined in the source files `stuff.f` and `blocks.f`: `2@` `2!` `2>r` `2r>` `?` `-trailing` `.s` `:noname` `/string` `also` `block` `buffer` `buffer:` `case` `context` `current` `definitions` `dump` `empty-buffers` `endcase` `endof` `forget` `forth` `list` `load` `marker` `of` `only` `order` `postpone` `previous` `scr` `thru` `update` `vocabulary` `words` - Notes: - `while` is only allowed once inside a `begin`/`repeat` construct. - `<#`, `#`, `#s` and `#>` only handle single-precision numbers. - There are no "state-smart" words. `is`, `."` and `s"` are intended to be used inside colon definitions. - Non-standard core words `2nip ( x y -- y )` Drops the 2nd item on the stack. `<builds ( | <word> -- )` Compile-time part of `<builds ... does>` pair. In other Forth systems `create` is normally used for this. `>limit ( -- a )` Variable holding the end-index in the text-input-buffer (TIB). `?stack ( -- )` Aborts on stack-underflow. `(.) ( n1 -- a n2 )` Convert signed number to string and return address and length. `_start ( -- a )` Pushes address of machine-code entry-point. `_end ( -- a )` Pushes end-address of machine-code section. `args ( ... -- )` Pushes a pointer to an array of cells, holding the number of command line arguments, followed by pointers to zero-terminated strings, one for each command-line argument (including the program name), terminated by 0. `boot ( ... -- )` Completely reinitializes the system and invokes `cold`. `bload ( a n -- )` Loads a memory-image from `<filename>` restoring the state at which the image was last saved with `save-image`. Note that image-files are not portable and depend on the executable being exactly the same at both save- and load-time. After loading the image, the deferred word `startup` is invoked. `bye ( -- )` Terminates `ff`. `c" ( | ..." -- a )` Stores a counted string in the dictionary and pushes its address. To be used in interpreted mode. `cas ( a1 x y -- f )` Perform an atomic _compare and swap_ operation on address `a1`, i.e. compares the contents of the given address with `x` and, if it is equal, replaces the stored value with `y`, atomically. Pushes a flag indicating whether the operation succeeded. `cold ( ... -- )` Performs a "cold" start, completely re-initializing the system. `crash ( ... -- )` Called when an uninitialized deferred word is invoked. `halt ( n -- )` Terminate with exit-code `n`. `heaptop ( -- a )` Variable holding the address of the top of the available heap. `interpret ( | ... -- )` Interprets words from the text-input-buffer (TIB). `load-image ( | <filename> -- )` Invokes `bload` with the given filename. `mmap ( a1 -- a2 )` Invokes the Linux `mmap` system call. `a1` should be the address of an `mmap_arg_struct` holding the parameters. See [this page][4] for more details. This word is a no-op on Plan 9. `number ( a n1 -- n2 -1 | a n1 0 )` Parses number given by string and either pushes the parsed number and `true` or keeps the argument items, pushing `false`, if the number is not a valid integer. `parse ( c | ... -- a )` Reads the next characters in the input-stream until character `c` is encountered and returns the address of a counted string. Note that this word is not ANSI compatible (it returns a counted string.) `prompt ( -- )` A deferred word that prints the prompt that is shown when the interpreter waits for input. The default prints ` ok` and advances to a new line. `query ( -- )` Reads a new line from stdin into the TIB. `reveal ( -- )` Exposes the most recent item in the dictionary (see also `smudge`.) `rshifta ( n1 n2 -- n3 )` Performs an arithmetic shift of `n1` by `n2` bits. `s0 ( -- a )` Variable holding the initial stack-pointer. `s@ ( -- a )` Pushes the current stack-pointer. `save-image ( | <filename> -- )` Saves the current dictionary to `<filename>`. `signum ( n1 -- n2 )` Pushes -1, 0 or 1, depending on whether `n1` is negative, zero or positive. `smudge ( -- )` Hides the most recent dictionary entry. `startup ( -- )` Invoked after a binary image is loaded. The default behaviour is to print `"ok "` and invoke `abort`. `u/mod ( u1 u2 -- u3 u4 )` Like `/mod`, but treats arguments as unsigned numbers. `utfdecode ( a1 -- a2 c )` Decodes the UTF-8 byte sequence at address `a1` and returns the address directly after the byte sequence and the unicode code-point. `utfencode ( a c -- a n )` Encodes the unicode code-point `c` as an UTF-8 byte sequence at address `a`, and returns the target address and the number of bytes. - Optional words Some additional words are available in the source files `stuff.f`. Read that file to learn more about what's included. The Block-file Editor --------------------- The system includes an optional simple command-based block-editor in the file `ed.f`. See below for a list of available editor commands. Blocks are stored in a file called `blockfile`, which must reside in the current working directory. Note that the editor needs the words in `blocks.f`. To create a blockfile, use the following commands # creates a blank file of 1024 blocks: dd if=/dev/zero bs=1024 count=1024 | tr '\000' ' ' >blockfile The editor maintains two buffers, together with the current edited block (`scr`): the *insertion-buffer* and the *find-buffer*. The former is used in commands that add or insert text, the latter holds text that is searched. The editor is provided in source form in the file `ed.f`. The ANS block- and buffer-related words can be found in `blocks.f`. All editor words exist in the `editor` vocabulary, so execute `editor` before using them. - Editor commands: `b ( -- )` List previous screen. `copy ( n1 n2 -- )` Copies contents of block `n1` to block `n2`. `cut ( -- )` Deletes everything on the line, starting from the current position. `d ( [| ...] -- )` Deletes given text (or last found text). `e ( -- )` Deletes last found text. `f ( [| ...] -- )` Searches given text (or contents of the find-buffer) in current line. `i ( [| ...] -- )` Inserts given text (or contents of the insert-buffer) at current position. `index ( n1 n2 -- )` Shows first lines of blocks in given range. `k ( -- )` Swaps contents of insert- and find-buffer. `l ( -- )` Clears window and lists current screen. `n ( -- )` Lists next screen. `p ( [| ...] -- )` Replaces current line with given text (or contents of the insert-buffer). `r ( [| ...] -- )` Replaces last found text with given text (or contents of the insert-buffer). `s ( n [| ...] -- n )` Searches given text (or contents of find-buffer) in current screen and all blocks up to and including `n`.