{"id":17174806,"url":"https://github.com/benhoyt/third","last_synced_at":"2025-08-03T14:34:23.704Z","repository":{"id":6382512,"uuid":"7620127","full_name":"benhoyt/third","owner":"benhoyt","description":"Third, a small Forth compiler for 8086 DOS","archived":false,"fork":false,"pushed_at":"2015-10-01T00:07:41.000Z","size":208,"stargazers_count":80,"open_issues_count":0,"forks_count":7,"subscribers_count":7,"default_branch":"master","last_synced_at":"2025-03-24T21:15:42.636Z","etag":null,"topics":["compiler","dos","forth","x86"],"latest_commit_sha":null,"homepage":null,"language":"Forth","has_issues":false,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"bsd-3-clause","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/benhoyt.png","metadata":{"files":{"readme":"README.md","changelog":"HISTORY.TXT","contributing":null,"funding":null,"license":"LICENSE.TXT","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2013-01-15T06:53:18.000Z","updated_at":"2025-02-21T11:57:24.000Z","dependencies_parsed_at":"2022-07-28T22:39:02.512Z","dependency_job_id":null,"html_url":"https://github.com/benhoyt/third","commit_stats":null,"previous_names":[],"tags_count":0,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benhoyt%2Fthird","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benhoyt%2Fthird/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benhoyt%2Fthird/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/benhoyt%2Fthird/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/benhoyt","download_url":"https://codeload.github.com/benhoyt/third/tar.gz/refs/heads/master","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":248322553,"owners_count":21084335,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["compiler","dos","forth","x86"],"created_at":"2024-10-14T23:54:57.397Z","updated_at":"2025-04-11T00:32:09.260Z","avatar_url":"https://github.com/benhoyt.png","language":"Forth","readme":"Third, a small Forth compiler for 8086 DOS\n==========================================\n\n**Historical note:** I wrote this in 1998 (when I was 16), so I'm just putting\nit up here as a backup and for \"historical interest\". It's still a pretty good\nshow-case for how simple a self-hosting\n[Forth](http://en.wikipedia.org/wiki/Forth_%28programming_language%29)\ncompiler can be.\n\nI wrote it more or less all myself (though parts of the assembler were pretty\nmuch copied, I think :-), but it's loosely based on\n[eForth](http://www.calcentral.com/~forth/forth/) and the Forth compilers my\ndad wrote.\n\nIt still works on current 32-bit Windows systems, but 64-bit Windows systems\ndon't run 16-bit DOS programs anymore, so for those you'll need to use\n[DOSBox](http://www.dosbox.com/) or something similar.\n\nAll the documentation that follows is original.\n\n\nQuick start\n===========\n\nTo jump straight into using Third, execute the batch file MBIG MBER\nMQUICK in that order. Then you can run Big to use Third, or Ber to\nuse Third with Berwyn Hoyt's extensions. Type BYE once you're in\nThird to exit back to DOS. To load a Forth file (source code) type\n\"INCLUDE filename.f\".\n\nGeneral information\n===================\n\nThird was designed and coded by Benjamin Hoyt, with complements to\nthe following people:\n\n    Charles Moore           inventing Forth\n    Bruce Hoyt              coding FE (Forth Editor)\n    Berwyn Hoyt             bug reports and help to make Third clean\n    Bill Muench             eForth\n    Wonyong Koh             hForth\n    Tom Zimmer              F-PC\n    Anton Ertl              gForth\n    ANS committee           creating the ANS Standard\n\nThird tries hard, most of the time, to be a reasonable 16 bit Forth\ncompiler for DOS PCs. It was originally coded to be a very small\nForth as a learning tool for others, but this idea vanished when\nBerwyn and I decided to use it for a cross compiler for the Motorola\n68HC12 CPU. It is now a somewhat stable ANS Forth system with various\nfeatures.\n\nExcepting ENVIRONMENT? Third is a full CORE system just with the bare\nKernel.COM. With Big.F loaded (to make Big.COM) Third is a ANS system\nwith the following wordsets and their extensions implemented:\n\n    CORE DOUBLE EXCEPTION FACILITY FILE TOOLS SEARCH STRING\n\nMissing are BLOCK FLOATING LOCALS MEMORY. Even though the BLOCK\nwordset is supposed to be implemented if the FILE wordset is, I can't\nsee much use for it at the moment. When I need it, I'll code it.\nFLOATING will probably never come into the picture. I've never needed\nor liked LOCALS (to say the least). MEMORY words seem a bit pointless\nfor a small 16 bit Forth with only a 64k address space.\n\nThird also has a clean metacompiler (thanks to Bill Muench's eForth\nmetacompiler), an 8086 assembler, a nice DOS shell routine, a simple\ndecompiler, a fairly nice Quick reference help, and reasonable docs.\n\nThird dictionary structure\n==========================\n\nThird's dictionary is a structure of names and other information\nchained together in a linked list. Each \"record\" in the linked\nstructure contains information about a Forth \"word\" (don't confuse\nwith the CPU-word type meaning). Each record in the linked list\nhas a pointer to the previously defined word, whose link points to\nthe word defined before that, whose link points to ... and so it goes\ntill the link contains a zero (end of linked list).\n\nA wordlist is a list of words chained together in the above way.\n\nEach word in Third's dictionary is composed of three items: the link\nto the previously defined word, a count and flags byte, and a name\nfor use by the Forth dictionary searcher. Directly following the name\nstring in memory is the machine code for that word.\n\nThe link is simply a 16 bit \"cell\" (a cell is the basic unit of\ninformation in any Forth system) which contains a pointer, or zero.\n\nThe count and flags byte is divided into two sections. The five low\nbits is the count: the number of characters in the following Forth\nname, which can be a maximum of 31, for obvious reasons. The three\nhigh bits in this byte are \"flags\", of which only the highest bit\n(bit 7 of the byte) is presently used, for the IMMEDIATE flag.\n\nThe Forth virtual machine\n=========================\n\nThis virtual machine is sort of like a very fast emulated CPU. Its\ninstructions are the CODEd words. NEXT is the instruction processor.\nSI points to the current \"instruction\", and acts like a CPU\ninstruction pointer. Each instruction is a pointer to 80x86 code to\nexecute this instruction, so to execute the instruction we simply\nload a 16 bit word from SI and jump to this address.\n\nLike all Forths, Third has two stacks: the data stack and the return\nstack. It keeps function call return addresses (and at times, various\nother stuff) on the return stack. The return stack is addressed using\nBP as a stack pointer. The data stack, referenced by SP using PUSH\nand POP, holds all function parameters and return values. Yes, with\nthis lovely setup you can more than one return value (unlike some\nlanguages we know of :-).\n\nThe Third virtual machine uses 80x86 CPU registers as follows:\n\n    registers       use\n    -------------------\n    AX              scratch, used for LODSW in NEXT\n    BX              scratch, used for referencing memory and the like\n    CX              scratch, used for counting and loops\n    DX              scratch, used for division and multiplication\n    DI              scratch, used for string instructions\n    SI              the virtual machine instruction pointer\n    BP              the virtual machine return stack pointer\n    SP              the virtual machine data stack pointer\n    CS              80x86 code segment register (never changes)\n    DS              data segment, must stay the same as CS\n    SS              stack segment, must stay the same as CS\n    ES              scratch segment register\n    flags           direction flag is expected to always be clear (CLD)\n\nMemory usage\n============\n\nThird uses one full 80x86 64k segment which is divides up as follows:\n\n    base    limit   description\n    ---------------------------\n    0000    0100    256 byte DOS program segment prefix (PSP)\n    0100    HERE    Forth dictionary: code, name, and data spaces\n    HERE    FDF0    free space (used for PAD buffers and MALLOC)\n    FDF0    FE00    8 element search order (CONTEXT) stack\n    FE00    FF00    128 cell data stack (SP stack)\n    FF00    FFFE    127 cell return stack (BP stack)\n    FFFE    10000   two bytes unused memory :-)\n\nStack diagrams\n==============\n\nStack diagrams or pictures are expressed with the incoming parameters\non the left of the \"--\" and outgoing return values on the right. The\nitem on the top of the stack (abbreviated TOS) is always the left\nmost item in the stack picture.\n\nA '|' (vertical bar) character in a stack picture means \"or this\" and\nis used when a word has varying parameters or return values. A \"..\"\n(two dots) sequence means \"many items could be here\".\n\nPossible double quotes before the \"--\" tells what (if any) input\nbuffer parsing the word does. Parsed text abbreviations are given in\nthe following table:\n\n    abbreviation    description\n    ---------------------------\n    \u003cchar\u003e          a delimiting character marking end of string being parsed\n    \u003cchars\u003e         zero or more occurences of the character char\n    \u003cspace\u003e         a delimiting space character (or any whitespace character)\n    \u003cspaces\u003e        zero or more consecutive spaces (or any whitespace)\n    \u003cquote\u003e         a delimiting double quote '\"'\n    \u003cparen\u003e         a delimiting right parenthesis ')'\n    \u003ceol\u003e           an implied delimiter marking the end of a line\n    ccc             a parsed sequence of arbitrary chars excluding any delimiter\n    name            a token bounded by space, same as ccc\u003cspace\u003e or ccc\u003ceol\u003e\n\nSome examples of stack diagrams follow:\n\n    word            stack picture\n    -----------------------------\n    MY-WORD         stack-before \"parsing\" -- stack-after\n    ROT             x1 x2 x3 -- x2 x3 x1\n    ?DUP            x -- 0 | x x\n    PARSE           char \"ccc\u003cchar\u003e\" -- c-addr u\n    RESTORE-INPUT   xn .. x1 n -- flag\n\nThe meaning of the various stack picture data types are as follows:\n\n    symbol          data type                               # of cells on stack\n    ---------------------------------------------------------------------------\n    flag            boolean flag                            1\n    true            true flag                               1\n    false           false flag                              1\n    xt              execution token                         1\n    addr            address                                 1\n    a-addr          cell aligned address                    1\n    c-addr          character aligned address               1\n    ofs             offset into segment (Third specific)    1\n    seg             segment pointer (Third specific)        1\n    ior             I/O result                              1\n    fam             file access method                      1\n    fileid          file identifier                         1\n    wid             wordlist identifier                     1\n    char            character                               1\n    n               signed single-cell integer              1\n    +n              non-negative single-cell integer        1\n    u               unsigned single-cell integer            1\n    n|u             signed or unsigned single-cell integer  1\n    x               unspecified cell                        1\n    d               signed double-cell integer              2\n    +d              non-negative double-cell integer        2\n    ud              unsigned double-cell integer            2\n    d|ud            signed or unsigned double-cell integer  2\n    xd              unspecified cell pair                   2\n    colon-sys       colon definition compilation            implementation defined\n    do-sys          DO...LOOP structures                    implementation defined\n    case-sys        CASE...ENDCASE structure                implementation defined\n    of-sys          OF...ENDOF structure                    implementation defined\n    orig            control-flow origins                    implementation defined\n    dest            control-flow destinations               implementation defined\n    loop-sys        DO...LOOP control parameters            implementation defined\n    nest-sys        definition calls                        implementation defined\n    i*x, j*x, k*x   indeterminate # of stack items          0 or more\n\nAn execution token is a Forth word identifier that can be EXECUTEd.\nIn Third, an execution token is a pointer to the word's machine code\n(a colon definition xt is a pointer to a CALL instruction).\n\nseg and ofs items are used by Third's far memory operators to make\nuse of the Intel segment and offset architecture.\n\nAn I/O result (used mainly by FILE words) is zero if the operation\nwas successful. If the operation was not successful, the ior is an\nimplementation defined nonzero value that can be THROWn. An end of\nfile condition (for instance, in READ-FILE) gives a zero ior.\n\nIn Third a fileid is the same as the DOS file handle but the Standard\nspecifies that fileid's are implementation dependant.\n\nA wid is a wordlist identifier and contains information about the\ncorresponding wordlist. In Third a wid is a pointer to a three cell\nstructure containing a search chain pointer, the link to the\npreviously defined wordlist, and a pointer to the wordlist's header.\n\nImplementation defined options\n==============================\n\nAddresses need not be cell aligned for @ and ! to function properly.\n\nEMIT (using the default EMIT that sends to DOS standard output)\ndisplays all characters 32 (hex 20) to 126 (hex 7E) using the ASCII\ncharacter set. Values above this range are displayed using the\nextended ASCII character set standard to IBM compatibles. Values\nbelow this range which are not control characters are also displayed\nin standard IBM PC fashion. Control characters are handled as shown\nin the following table:\n\n    value   description\n    -------------------\n    07      sounds a beep and displays nothing\n    08      moves the text cursor left one character\n    09      displays enough spaces to position the cursor at the next tab stop\n    0A      moves the cursor down one line, scrolling the screen if necessary\n    0D      moves the cursor to the start of the current line\n\nAlthough ACCEPT is deferred (and EXPECT calls ACCEPT), the default\nversion exits when the Enter key is pressed and removes the last\ncharacter (from the buffer and the screen) when Backspace is pressed.\n\nA character is eight bits wide and can contain a value in the range\n0 to 255.\n\nAddresses need not be character aligned for C@ and C! to function\nproperly.\n\nThird recognises no extended (eg., accented international characters)\ncharacters as upper or lower case letters.\n\nREFILL converts tab characters to spaces before interpreting. Parsing\nroutines (PARSE and SKIP) recognise only the space character 32 as a\nspace delimiter.\n\nThe control flow stack is kept on the data stack and items are always\none cell wide.\n\nBinary digits from 0 to 9 are converted to the characters '0' to '9'.\nBinary digits from 10 to 35 are converted to the characters\n'A' to 'Z'. Binary digits from 36 onwards are converted to the\ncharacters from 91 (that is, '[') onwards.\n\nThe display is not altered in any way after input terminates in\nACCEPT or EXPECT. The cursor position is not changed.\n\nABORT displays nothing. ABORT\" and other THROW values show the word\nin the source which caused the error and display the error message.\nIf a text file was being interpreted the line number is given. If an\nunknown error (unknown THROW #) is encountered the error message is\n\"Unknown exception # nnn\" where nnn is the unknown THROW number.\n\nThe Enter key terminates line input from the user input device.\n\nThe maximum size of a counted string is 255 chars excluding count.\n\nThe maximum size of a PARSEd string is pretty much infinite. :-)\n\nThe maximum size of a definition name is 31 characters.\n\nThe maximum string length for ENVIRONMENT? is 31 characters.\n\nUser input device can be redirected as DOS allows.\n\nUser output device can be redirected as DOS allows.\n\nThe logical code, data, and name spaces are all organised in one\nphysical segment addressed by HERE.\n\nAn address unit (byte) is eight bits wide.\n\nTwo's complement integer arithmetic is used.\n\nThe ranges for various integer data types are given in the following\ntable:\n\n    data type       allowable range\n    -------------------------------\n    +n              0 to 32,767\n    n               -32,768 to 32,767\n    u               0 to 65,535\n    +d              0 to 2,147,483,647\n    d               -2,147,483,648 to 2,147,483,647\n    ud              0 to 4,294,967,295\n\nThird has no read-only data space regions.\n\nThe buffer used by WORD (at HERE) can hold one count character, 254\nparsed characters, and one space character. PAD is 256 characters\nbeyond HERE.\n\nA cell is sixteen bits wide.\n\nThe keyboard terminal input buffer is 256 characters in size.\n\nThe pictured numeric output string buffer is at least 80 characters\nin size.\n\nThe size of the scratch PAD is 256 characters.\n\nThird is case insensitive by default but can be switched to a case\nsensitive system by executing the word SENSE and back by executing\nthe work NONSENSE. SENSITIVE returns a true flag if the system is in\ncase sensitive mode.\n\nThe system prompt when no error has occured is simply \"ok\".\n\nThe default type of division rounding used is symmetric.\n\nThe value of STATE when true is a Standard true flag, ie., a cell\nwith all bits set.\n\nThe values returned when arithmetic operations have overflowed are\nthe correct values mod MAX-U. In effect, Third uses modulo arithmetic\nwith a divisor of 65,536.\n\nThe current definition cannot be found in the dictionary after DOES\u003e,\nbut only after the final ; (semicolon).\n\nThe system values used by CATCH and THROW are the Standard ones from\n-1 to -58 and system I/O results from -256 to -294. The user should\nnot have to worry about this and should only use positive values.\n\nThe encoding of keyboard events as returned by EKEY are simply the\n16-bit values the BIOS keyboard interrupt (hex 16) functions give.\n\nThe duration of a system clock tick for MS is 55 milliseconds.\n\nA R/O fam is 0, a W/O fam is 1, and a R/W fam is 2. BIN leaves these\nvalues unchanged as DOS doesn't have a READ-LINE function.\n\nThe file line terminators accepted by READ-LINE are either an LF\ncharacter (hex 0A) by itself or a CR,LF sequence (hex 0D,0A). This\nallows for both Unix-style and DOS text files, respectively.\nWRITE-LINE writes the DOS CR,LF sequence.\n\nStandard DOS filenames are used for the file words. Case does not\nmatter. No wildcards are accepted. Filenames of the following formats\nare recognised (where \"filename\" may include an extension):\n\n    filename\n    d:filename\n    d:\\path\\filename\n\nBits in cell x returned FILE-STATUS are as follows:\n\n    bit     description\n    -------------------\n    0       set if file is read-only (protected)\n    1       set if file is hidden\n    2       set if file is a system file\n    3-4     unused\n    5       set if file is an archive file\n    6-15    unused\n\nAfter an exception during interpretation of a text file, the file\nis closed and the line buffer is deallocated. The exception is then\nre-THROWn.\n\nI/O result (ior) values are simply the DOS error code values\nsubtracted from -255. This gives a range from -256 downward.\n\nThe maximum nesting depth for INCLUDE-FILE is probably about 8. There\nis no actual maximum number of nests, but when the return stack is\nfull, you're a goner. :-)\n\nThe maximum length line for READ-LINE and interpretation and parsing\nof text files is basically unlimited except by memory restrictions.\n\nThe BLOCK wordset is not implemented so no block mapping is done.\n\nOnly one string buffer is provided for S\" (have fun with words like\nRENAME-FILE :-). This string buffer is 256 bytes in size.\n\nEnding the sequence of assembler instructions following CODE or ;CODE\nis done with END-CODE.\n\nProcessing assembler instruction following CODE or ;CODE is normal\ninterpreted Forth source code.\n\nThe full SEARCH order wordsets are implemented given ASSEMBLER and\nEDITOR expected results.\n\nSEE decompiles and displays most things, excepting conditional\nconstructs, as they were typed in. LITERALs, POSTPONEd words,\nDO...LOOPs, CREATE DOES\u003e words, and strings (S\" ABORT\" etc.) are\ndecompiled pretty much as they were compiled. Conditional clauses and\nstructures like BEGIN...UNTIL are not simple to reproduce from\nexecutable code. Cconditional branches (IF, WHILE, UNTIL, etc.) are\ndecompiled as \"IF+offset\" for forward branches or \"IF-offset\" for\nbackward branches. Unconditional branches are decompiled with\n\"ELSE+offset\" and \"ELSE-offset\" similarly. A colon definition would\nbe SEEn as in the example below:\n\n    : SPACES  0 MAX 0 ?DO SPACE LOOP ;\n\nThe ; is followed by IMMEDIATE if the word is immediate. Note that\n;CODE in a word to be SEEn is not respected (that is, won't work :-).\nAlso, SEE cannot differentiate between an EXIT and a ; and stops\ndecompiling as soon as it hits any EXIT.\n\nAnything CREATEd, including VARIABLEs, are decompiled as in the\nfollowing:\n\n    CREATE STATE\n\nAny VALUE or CONSTANT is displayed as in the example below:\n\n    32 VALUE BL\n\nA DEFERred word is displayed along with the word it is currently\ndeferred to. An amiguous condition exists if the word it points to\nwas defined with :NONAME. A DEFERred word is SEEn as in the example\nbelow:\n\n    DEFER TYPE IS DTYPE\n\nThe maximum number of word lists allowed in the search order is\neight.\n\nThe minimum search order (as with \"-1 SET-ORDER\" or ONLY) is the\nFORTH-WORDLIST. ONLY is equivalent to \"FORTH-WORDLIST 1 SET-ORDER\".\n\nAction taken upon ambiguous conditions\n======================================\n\nWhen an interpreted name is neither a valid definition nor a valid\nnumber the interpreter aborts with an appropriate error message.\n\nWhen a definition name exceeds the maximum length allowed it is\ntruncated to 31 characters.\n\nThird might crash if values are stored in the code or name space.\n\nNo type checking is performed.\n\nWhen a user uses ' on a definition with undefined interpretation\nsemantics ' returns an xt of that word's compilation semantics.\n\nDivision by zero causes Third to exit to DOS with a \"Divide Error\"\nmessage.\n\nData stack or return stack overflow: probable crash.\n\nInsufficient space for loop control parameters: probable crash.\n\nInsufficent space in the dictionary: probable crash.\n\nWhen a word with undefined interpretation semantics is interpreted\nThird executes that word's compilation semantics.\n\nThe input buffer and string literal regions are read/write.\n\nOverflow of a pictured numeric output string: possible crash.\n\nParsed string overflow (doesn't happen): minutely possible crash.\n\nResult out of range in * or / etc.: good old mod MAX-U arithmetic\ntakes place.\n\nReading values from an empty return stack is near impossible. Reading\nvalues from an empty data stack gives undefined values. Data stack\nunderflow is checked for by the interpreter after each word is\ninterpreted.\n\nUsing a zero length string as a name causes the interpreter to abort\nwith an appropriate error message.\n\n\\\u003eIN greater than the size of the input buffer: probably a -13 THROW.\n\nRECURSE appearing after DOES\u003e: probable crash when word is executed.\n\nRESTORE-INPUT input source different from current input source: input\nsource will probably change, minutely possible crash.\n\nData space containing de-ALLOTed definitions: probably crash.\n\nData space read/write with incorrect alignment: Nothing. Third\ndoesn't worry about alignment.\n\nData space pointer not properly aligned: Nothing. Third doesn't\nworry about alignment.\n\nLess than u+2 stack items with PICK and ROLL: 1 PICK is an OVER.\n0 PICK is a DUP. 1 ROLL is a SWAP. 0 ROLL is a do-nothing.\n\nLoop control parameters not available: wonky results.\n\nMost recent definition does not have a name (for IMMEDIATE): probably\nnothing, possible wonky happenings.\n\nName not defined by VALUE used by TO: Third's TO works with VALUES,\nCREATEd words, VARIABLEs, VALUEs, DEFERs, but probably messes up a\nCODE or colon definition.\n\nName not found (with ' ['] POSTPONE etc.): A -13 THROW.\n\nParameters are not of same type (DO ?DO WITHIN etc.): funny things.\n\nPOSTPONE or [COMPILE] applied to TO: works fine as you would expect.\n\nString longer than counted string returned by WORD: PAD overwritten.\n\nWhen u is greater than or equal to the number of bits in a cell for\nLSHIFT or RSHIFT: unexpected results.\n\n\\\u003eBODY or DOES\u003e applied to a word not defined with CREATE: DOES\u003e will\nprobably work on CONSTANTs, VARIABLEs, DEFERs, but do funny things\nwith colon definitions. \u003eBODY works well on CREATEd words, VARIABLEs,\nVALUEs, and DEFERs.\n\n\\# #S HOLD or SIGN used outside a \u003c# ... #\u003e sequence: you can expect\nweird happenings if you do weird things like this! :-)\n\nWhen d is outside the range of n in D\u003eS: result is truncated.\n\nAT-XY can always be performed on the user output device.\n\nPositioning a file outside the file boundaries causes no error.\nReading from the file after this does not result in an error but zero\ncharacters are read. Writing to the file after this extends the\nlength of the file but the unwritten information in the file is\nundefined.\n\nAttempting to read from file positions not yet written to (for\nexample, creating a new file and immediately executing READ-FILE)\ndoes not cause an error, but zero bytes are read.\n\nAn invalid fileid passed to INCLUDE-FILE THROWs an appropriate\nexception when REFILL is first executed (in INCLUDE-FILE).\n\nWhen an I/O exception is encountered reading or closing a text file\n(in INCLUDE-FILE or INCLUDED) an appropriate exception is THROWn.\n\nWhen a name file passed to INCLUDED cannot be opened the appropriate\nexception is THROWn.\n\nSince the BLOCK wordset is not implemented requesting an unmapped\nblock number does not occur. (Strange, that. :-) Neither does using\nSOURCE-ID when BLK is nonzero.\n\nDeleting the with MARKER or FORGET has no effect until you try to\ncompile a definition when the system will probably crash.\n\nA possible crash will occur if there are less than u+1 items on the\ncontrol flow stack (data stack) when CS-PICK or CS-ROLL are executed.\n\nWhen the name parsed by FORGET cannot be found -13 is THROWn.\n\n;CODE used on a non-CREATEd definition will actually work.\n\nPOSTPONE applied to [IF] seems to work seemlessly. :-)\n\nIf the end of the input file is reached before a matching [ELSE] or\n[THEN] is encountered an un-nesting from all levels of [IF] occurs.\n\nRemoving a needed definition with MARKER or FORGET will probably\ncause a crash.\n\nChanging the compilation wordlist while compiling a definition will\nprobably make the definition unable to be found.\n\nIf FIND (or similar) is executed when the search order is empty, no\nwords will be found. If the search order is empty while interpreting,\n(and kids, don't try this at home!) only numbers will be accepted.\n\nToo many wordlists in the search order may cause a crash.\n\nOther information\n=================\n\nNo non-Standard Third words use the scratch PAD. No Standard words do\neither.\n\nAvailable terminal facilities: AT-XY KEY? PAGE EKEY EKEY\u003eCHAR EKEY?\nEMIT? MS and TIME\u0026DATE.\n\nAvailable data space for programs: given by UNUSED.\n\nReturn stack space available: 127 cells.\n\nData stack space available: 128 cells.\n\nDictionary space used by Third system: given by \"HERE 256 -\".\n","funding_links":[],"categories":[],"sub_categories":[],"project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenhoyt%2Fthird","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbenhoyt%2Fthird","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbenhoyt%2Fthird/lists"}