NAME
     forth - the Forth interpreter

SYNOPSIS
     forth

DESCRIPTION
     Forth starts pForth on the console and gives you its interpreter.  It is
     the deck's own programming environment: a language that lives on the
     machine, compiles on the machine, and can be edited on the machine with
     nothing else attached.

     Forth reads words separated by spaces and either runs them or, between :
     and ;, compiles them into a new word.  Arguments go on a stack and are
     written before the word that uses them.

          2 3 + .             prints 5
          : SQUARED ( n -- n2 ) DUP * ;
          7 SQUARED .         prints 49

     BYE returns you to the shell.  Words you defined stay defined: the next
     forth resumes the same dictionary.

     The first start is slow -- ten or twenty seconds -- because the interpreter
     is compiling its own source.  pForth's kernel knows only a few dozen
     primitives; everything else, including \, S", and the file words, is
     Forth text in system.fth that has to be read and compiled.  Frst.fth
     follows it.  Subsequent starts are immediate.

     Frst.fth is the deck's own vocabulary and it is a file you are meant to
     edit:

          sam /n/local/forth/frst.fth

     Reload it without rebooting, as often as you like:

          S" frst.fth" INCLUDED

     Nothing about that file is privileged.  The words below are its contents,
     not the interpreter's, and a word you do not like is a word you can
     rewrite.

WORDS
     The primitives are C, compiled into the firmware; they are the whole of
     what Forth can reach outside itself.  Each returns an ior which is 0 on
     success and negative on failure.

     ZRC ( a u -- ior )
          Run one shell command line.  The string goes through the rc(1)
          parser, quirks and all.

     ENV@ ( name u buf u1 -- u2 )
          Read a shell variable into buf; returns its length, or -1 if it is
          unset.

     ENV! ( val u name u -- ior )
          Set a shell variable.

     NS-MOUNT ( dial u path u -- ior )
          Mount a 9P server on path.

     NS-BIND ( new u old u flags -- ior )
          Bind new over old.  Flags: 0 replace, 1 before, 2 after.

     NS-UNMOUNT ( path u -- ior )
          Undo a mount.

     NS-CWD! ( path u -- ior )
          Change directory.

     NS-STAT ( path u buf u1 -- u2 )
          Stat path, leaving the text "[d]length mtime" in buf; returns its
          length.  The leading d means a directory.

     The rest are Forth, defined in frst.fth.

     ?IOR ( ior -- )
          Print a negative ior and abort; discard it otherwise.  Every word
          below checks its calls with this.

     SH ( cmd... -- )
          Run the rest of the input line as a shell command: SH ls /net.
          Built on REST-OF-LINE (-- a u), which takes the remainder of the
          line and consumes it.

     CAT ( a u -- )
          Type a file: S" /n/local/readme.txt" CAT.

     CD ( path -- )
          Change directory, taking the next word from the input line.

     CTL! ( cmd u path u -- )
          Write one command to a control file -- the idiom most of the deck's
          devices are driven by.

     ENV. ( name u -- )
          Print a shell variable, or (unset) if there is none.

     WIFI-CONNECT ( ssid u pass u -- )
          Join a network.  It is three lines of Forth around a CTL!, because
          that is genuinely all it is.

     WHO ( -- )
          The mesh roster; see who(1).

     PEERS ( -- )
          List /net/aether/peers.

     Screen control, which the terminal interprets natively.

     AT-XY ( col row -- )
          Move the cursor; the top left is 0 0.

     PAGE ( -- )
          Clear the screen and home the cursor.

     ERASE-EOL ( -- )
          Clear from the cursor to the end of the line.

     INVERSE ( -- ) , NORMAL ( -- )
          Reverse video on and off.

     Two scratch areas are there for building strings: IOBUF (128 bytes), used
     by CAT and ENV., and CMDBUF (160 bytes) with CMD0, CMD+ ( a u -- ), CMD-
     SPACE, and CMD@ ( -- a u ), which is how WIFI-CONNECT assembles its line.

EXAMPLES
     Drive a device from Forth:

          S" connect homenet hunter2" S" /net/wifi/ctl" CTL!

     Mount a server and look at it:

          S" tcp!bbs.frstcomputer.net!564" S" /n/dc" NS-MOUNT ?IOR
          S" ls /n/dc" ZRC ?IOR

     A word of your own, using the shell for the part the shell is better at:

          : STATUS ( -- )  PAGE INVERSE ." deck" NORMAL CR
              S" who" ZRC ?IOR ;

     Edit the vocabulary, then pick up the change:

          SH sam /n/local/forth/frst.fth
          S" frst.fth" INCLUDED

FILES
     /n/local/forth
          The interpreter's working directory, which is why INCLUDED takes
          bare filenames.

     /n/local/forth/system.fth
          pForth's own ANSI layer, compiled at first start.

     /n/local/forth/frst.fth
          The FRST vocabulary.  Yours.

     /dev/cons
          Where the interpreter reads and writes.

SOURCE
     src/forth_frst.c
          The primitives and their registration.

SEE ALSO
     rc(1), who(1), aether(3)

NOTES
     There is one interpreter and it runs on the shell thread that started it,
     so forth cannot be started from inside itself: S" forth" ZRC declines
     rather than corrupting the dictionary.

     Strings handed to ZRC are parsed by the shell, so the shell's parser
     quirks are yours too -- !  inside quotes, and comments inside { }.

     A definition made at the keyboard lives until the deck reboots.  To keep
     it, put it in frst.fth.

FRST Computer                                                         FORTH(1)
