📄 eforth.asm
字号:
$COLON 5,'DIGIT',DIGIT
DW DOLIT,9,OVER,LESS
DW DOLIT,7,ANDD,PLUS
DW DOLIT,'0',PLUS,EXIT
; EXTRACT ( n base -- n c )
; Extract the least significant digit from n.
$COLON 7,'EXTRACT',EXTRC
DW DOLIT,0,SWAP,UMMOD
DW SWAP,DIGIT,EXIT
; <# ( -- )
; Initiate the numeric output process.
$COLON 2,'<#',BDIGS
DW PAD,HLD,STORE,EXIT
; HOLD ( c -- )
; Insert a character into the numeric output string.
$COLON 4,'HOLD',HOLD
DW HLD,AT,DOLIT,1,SUBB
DW DUPP,HLD,STORE,CSTOR,EXIT
; # ( u -- u )
; Extract one digit from u and append the digit to output string.
$COLON 1,'#',DIG
DW BASE,AT,EXTRC,HOLD,EXIT
; #S ( u -- 0 )
; Convert u until all digits are added to the output string.
$COLON 2,'#S',DIGS
DIGS1: DW DIG,DUPP
DW QBRAN,DIGS2
DW BRAN,DIGS1
DIGS2: DW EXIT
; SIGN ( n -- )
; Add a minus sign to the numeric output string.
$COLON 4,'SIGN',SIGN
DW ZLESS
DW QBRAN,SIGN1
DW DOLIT,'-',HOLD
SIGN1: DW EXIT
; #> ( w -- b u )
; Prepare the output string to be TYPE'd.
$COLON 2,'#>',EDIGS
DW DROP,HLD,AT
DW PAD,OVER,SUBB,EXIT
; str ( n -- b u )
; Convert a signed integer to a numeric string.
$COLON 3,'str',STR
DW DUPP,TOR,ABSS
DW BDIGS,DIGS,RFROM
DW SIGN,EDIGS,EXIT
; HEX ( -- )
; Use radix 16 as base for numeric conversions.
$COLON 3,'HEX',HEX
DW DOLIT,16,BASE,STORE,EXIT
; DECIMAL ( -- )
; Use radix 10 as base for numeric conversions.
$COLON 7,'DECIMAL',DECIM
DW DOLIT,10,BASE,STORE,EXIT
;; Numeric input, single precision
; DIGIT? ( c base -- u t )
; Convert a character to its numeric value. A flag indicates success.
$COLON 6,'DIGIT?',DIGTQ
DW TOR,DOLIT,'0',SUBB
DW DOLIT,9,OVER,LESS
DW QBRAN,DGTQ1
DW DOLIT,7,SUBB
DW DUPP,DOLIT,10,LESS,ORR
DGTQ1: DW DUPP,RFROM,ULESS,EXIT
; NUMBER? ( a -- n T | a F )
; Convert a number string to integer. Push a flag on tos.
$COLON 7,'NUMBER?',NUMBQ
DW BASE,AT,TOR,DOLIT,0,OVER,COUNT
DW OVER,CAT,DOLIT,'$',EQUAL
DW QBRAN,NUMQ1
DW HEX,SWAP,DOLIT,1,PLUS
DW SWAP,DOLIT,1,SUBB
NUMQ1: DW OVER,CAT,DOLIT,'-',EQUAL,TOR
DW SWAP,RAT,SUBB,SWAP,RAT,PLUS,QDUP
DW QBRAN,NUMQ6
DW DOLIT,1,SUBB,TOR
NUMQ2: DW DUPP,TOR,CAT,BASE,AT,DIGTQ
DW QBRAN,NUMQ4
DW SWAP,BASE,AT,STAR,PLUS,RFROM
DW DOLIT,1,PLUS
DW DONXT,NUMQ2
DW RAT,SWAP,DROP
DW QBRAN,NUMQ3
DW NEGAT
NUMQ3: DW SWAP
DW BRAN,NUMQ5
NUMQ4: DW RFROM,RFROM,DDROP,DDROP,DOLIT,0
NUMQ5: DW DUPP
NUMQ6: DW RFROM,DDROP
DW RFROM,BASE,STORE,EXIT
;; Basic I/O
; ?KEY ( -- c T | F )
; Return input character and true, or a false if no input.
$COLON 4,'?KEY',QKEY
DW TQKEY,ATEXE,EXIT
; KEY ( -- c )
; Wait for and return an input character.
$COLON 3,'KEY',KEY
KEY1: DW QKEY
DW QBRAN,KEY1
DW EXIT
; EMIT ( c -- )
; Send a character to the output device.
$COLON 4,'EMIT',EMIT
DW TEMIT,ATEXE,EXIT
; NUF? ( -- t )
; Return false if no input, else pause and if CR return true.
$COLON 4,'NUF?',NUFQ
DW QKEY,DUPP
DW QBRAN,NUFQ1
DW DDROP,KEY,DOLIT,CRR,EQUAL
NUFQ1: DW EXIT
; PACE ( -- )
; Send a pace character for the file downloading process.
$COLON 4,'PACE',PACE
DW DOLIT,11,EMIT,EXIT
; SPACE ( -- )
; Send the blank character to the output device.
$COLON 5,'SPACE',SPACE
DW BLANK,EMIT,EXIT
; SPACES ( +n -- )
; Send n spaces to the output device.
$COLON 6,'SPACES',SPACS
DW DOLIT,0,MAX,TOR
DW BRAN,CHAR2
CHAR1: DW SPACE
CHAR2: DW DONXT,CHAR1
DW EXIT
; TYPE ( b u -- )
; Output u characters from b.
$COLON 4,'TYPE',TYPEE
DW TOR
DW BRAN,TYPE2
TYPE1: DW DUPP,CAT,EMIT
DW DOLIT,1,PLUS
TYPE2: DW DONXT,TYPE1
DW DROP,EXIT
; CR ( -- )
; Output a carriage return and a line feed.
$COLON 2,'CR',CR
DW DOLIT,CRR,EMIT
DW DOLIT,LF,EMIT,EXIT
; do$ ( -- a )
; Return the address of a compiled string.
$COLON COMPO+3,'do$',DOSTR
DW RFROM,RAT,RFROM,COUNT,PLUS
DW ALGND,TOR,SWAP,TOR,EXIT
; $"| ( -- a )
; Run time routine compiled by $". Return address of a compiled string.
$COLON COMPO+3,'$"|',STRQP
DW DOSTR,EXIT ;force a call to do$
; ."| ( -- )
; Run time routine of ." . Output a compiled string.
$COLON COMPO+3,'."|',DOTQP
DW DOSTR,COUNT,TYPEE,EXIT
; .R ( n +n -- )
; Display an integer in a field of n columns, right justified.
$COLON 2,'.R',DOTR
DW TOR,STR,RFROM,OVER,SUBB
DW SPACS,TYPEE,EXIT
; U.R ( u +n -- )
; Display an unsigned integer in n column, right justified.
$COLON 3,'U.R',UDOTR
DW TOR,BDIGS,DIGS,EDIGS
DW RFROM,OVER,SUBB
DW SPACS,TYPEE,EXIT
; U. ( u -- )
; Display an unsigned integer in free format.
$COLON 2,'U.',UDOT
DW BDIGS,DIGS,EDIGS
DW SPACE,TYPEE,EXIT
; . ( w -- )
; Display an integer in free format, preceeded by a space.
$COLON 1,'.',DOT
DW BASE,AT,DOLIT,10,XORR ;?decimal
DW QBRAN,DOT1
DW UDOT,EXIT ;no, display unsigned
DOT1: DW STR,SPACE,TYPEE,EXIT ;yes, display signed
; ? ( a -- )
; Display the contents in a memory cell.
$COLON 1,'?',QUEST
DW AT,DOT,EXIT
;; Parsing
; parse ( b u c -- b u delta ; <string> )
; Scan string delimited by c. Return found string and its offset.
$COLON 5,'parse',PARS
DW TEMP,STORE,OVER,TOR,DUPP
DW QBRAN,PARS8
DW DOLIT,1,SUBB,TEMP,AT,BLANK,EQUAL
DW QBRAN,PARS3
DW TOR
PARS1: DW BLANK,OVER,CAT ;skip leading blanks ONLY
DW SUBB,ZLESS,INVER
DW QBRAN,PARS2
DW DOLIT,1,PLUS
DW DONXT,PARS1
DW RFROM,DROP,DOLIT,0,DUPP,EXIT
PARS2: DW RFROM
PARS3: DW OVER,SWAP
DW TOR
PARS4: DW TEMP,AT,OVER,CAT,SUBB ;scan for delimiter
DW TEMP,AT,BLANK,EQUAL
DW QBRAN,PARS5
DW ZLESS
PARS5: DW QBRAN,PARS6
DW DOLIT,1,PLUS
DW DONXT,PARS4
DW DUPP,TOR
DW BRAN,PARS7
PARS6: DW RFROM,DROP,DUPP
DW DOLIT,1,PLUS,TOR
PARS7: DW OVER,SUBB
DW RFROM,RFROM,SUBB,EXIT
PARS8: DW OVER,RFROM,SUBB,EXIT
; PARSE ( c -- b u ; <string> )
; Scan input stream and return counted string delimited by c.
$COLON 5,'PARSE',PARSE
DW TOR,TIB,INN,AT,PLUS ;current input buffer pointer
DW NTIB,AT,INN,AT,SUBB ;remaining count
DW RFROM,PARS,INN,PSTOR,EXIT
; .( ( -- )
; Output following string up to next ) .
$COLON IMEDD+2,'.(',DOTPR
DW DOLIT,')',PARSE,TYPEE,EXIT
; ( ( -- )
; Ignore following string up to next ) . A comment.
$COLON IMEDD+1,'(',PAREN
DW DOLIT,')',PARSE,DDROP,EXIT
; \ ( -- )
; Ignore following text till the end of line.
$COLON IMEDD+1,'\',BKSLA
DW NTIB,AT,INN,STORE,EXIT
; CHAR ( -- c )
; Parse next word and return its first character.
$COLON 4,'CHAR',CHAR
DW BLANK,PARSE,DROP,CAT,EXIT
; TOKEN ( -- a ; <string> )
; Parse a word from input stream and copy it to name dictionary.
$COLON 5,'TOKEN',TOKEN
DW BLANK,PARSE,DOLIT,31,MIN
DW NP,AT,OVER,SUBB,CELLM
DW PACKS,EXIT
; WORD ( c -- a ; <string> )
; Parse a word from input stream and copy it to code dictionary.
$COLON 4,'WORD',WORDD
DW PARSE,HERE,PACKS,EXIT
;; Dictionary search
; NAME> ( na -- ca )
; Return a code address given a name address.
$COLON 5,'NAME>',NAMET
DW CELLM,CELLM,AT,EXIT
; SAME? ( a a u -- a a f \ -0+ )
; Compare u cells in two strings. Return 0 if identical.
$COLON 5,'SAME?',SAMEQ
DW TOR
DW BRAN,SAME2
SAME1: DW OVER,RAT,CELLS,PLUS,AT
DW OVER,RAT,CELLS,PLUS,AT
DW SUBB,QDUP
DW QBRAN,SAME2
DW RFROM,DROP,EXIT ;strings not equal
SAME2: DW DONXT,SAME1
DW DOLIT,0,EXIT ;strings equal
; find ( a va -- ca na | a F )
; Search a vocabulary for a string. Return ca and na if succeeded.
$COLON 4,'find',FIND
DW SWAP,DUPP,CAT
DW DOLIT,CELLL,SLASH,TEMP,STORE
DW DUPP,AT,TOR,CELLP,SWAP
FIND1: DW AT,DUPP
DW QBRAN,FIND6
DW DUPP,AT,DOLIT,MASKK,ANDD,RAT,XORR
DW QBRAN,FIND2
DW CELLP,DOLIT,-1 ;true flag
DW BRAN,FIND3
FIND2: DW CELLP,TEMP,AT,SAMEQ
FIND3: DW BRAN,FIND4
FIND6: DW RFROM,DROP
DW SWAP,CELLM,SWAP,EXIT
FIND4: DW QBRAN,FIND5
DW CELLM,CELLM
DW BRAN,FIND1
FIND5: DW RFROM,DROP,SWAP,DROP
DW CELLM
DW DUPP,NAMET,SWAP,EXIT
; NAME? ( a -- ca na | a F )
; Search all context vocabularies for a string.
$COLON 5,'NAME?',NAMEQ
DW CNTXT,DUPP,DAT,XORR ;?context=also
DW QBRAN,NAMQ1
DW CELLM ;no, start with context
NAMQ1: DW TOR
NAMQ2: DW RFROM,CELLP,DUPP,TOR ;next in search order
DW AT,QDUP
DW QBRAN,NAMQ3
DW FIND,QDUP ;search vocabulary
DW QBRAN,NAMQ2
DW RFROM,DROP,EXIT ;found name
NAMQ3: DW RFROM,DROP ;name not found
DW DOLIT,0,EXIT ;false flag
;; Terminal response
; ^H ( bot eot cur -- bot eot cur )
; Backup the cursor by one character.
$COLON 2,'^H',BKSP
DW TOR,OVER,RFROM,SWAP,OVER,XORR
DW QBRAN,BACK1
DW DOLIT,BKSPP,TECHO,ATEXE,DOLIT,1,SUBB
DW BLANK,TECHO,ATEXE
DW DOLIT,BKSPP,TECHO,ATEXE
BACK1: DW EXIT
; TAP ( bot eot cur c -- bot eot cur )
; Accept and echo the key stroke and bump the cursor.
$COLON 3,'TAP',TAP
DW DUPP,TECHO,ATEXE
DW OVER,CSTOR,DOLIT,1,PLUS,EXIT
; kTAP ( bot eot cur c -- bot eot cur )
; Process a key stroke, CR or backspace.
$COLON 4,'kTAP',KTAP
DW DUPP,DOLIT,CRR,XORR
DW QBRAN,KTAP2
DW DOLIT,BKSPP,XORR
DW QBRAN,KTAP1
DW BLANK,TAP,EXIT
KTAP1: DW BKSP,EXIT
KTAP2: DW DROP,SWAP,DROP,DUPP,EXIT
; accept ( b u -- b u )
; Accept characters to input buffer. Return with actual count.
$COLON 6,'accept',ACCEP
DW OVER,PLUS,OVER
ACCP1: DW DDUP,XORR
DW QBRAN,ACCP4
DW KEY,DUPP
; DW BLANK,SUBB,DOLIT,95,ULESS
DW BLANK,DOLIT,127,WITHI
DW QBRAN,ACCP2
DW TAP
DW BRAN,ACCP3
ACCP2: DW TTAP,ATEXE
ACCP3: DW BRAN,ACCP1
ACCP4: DW DROP,OVER,SUBB,EXIT
; EXPECT ( b u -- )
; Accept input stream and store count in SPAN.
$COLON 6,'EXPECT',EXPEC
DW TEXPE,ATEXE,SPAN,STORE,DROP,EXIT
; QUERY ( -- )
; Accept input stream to terminal input buffer.
$COLON 5,'QUERY',QUERY
DW TIB,DOLIT,80,TEXPE,ATEXE,NTIB,STORE
DW DROP,DOLIT,0,INN,STORE,EXIT
;; Error handling
; CATCH ( ca -- 0 | err# )
; Execute word at ca and set up an error frame for it.
$COLON 5,'CATCH',CATCH
DW SPAT,TOR,HANDL,AT,TOR ;save error frame
DW RPAT,HANDL,STORE,EXECU ;execute
DW RFROM,HANDL,STORE ;restore error frame
DW RFROM,DROP,DOLIT,0,EXIT ;no error
; THROW ( err# -- err# )
; Reset system to current local error frame an update error flag.
$COLON 5,'THROW',THROW
DW HANDL,AT,RPSTO ;restore return stack
DW RFROM,HANDL,STORE ;restore handler frame
DW RFROM,SWAP,TOR,SPSTO ;restore data stack
DW DROP,RFROM,EXIT
; NULL$ ( -- a )
; Return address of a null string with zero count.
$COLON 5,'NULL$',NULLS
DW DOVAR ;emulate CREATE
DW 0
DB 99,111,121,111,116,101
$ALIGN
; ABORT ( -- )
; Reset data stack and jump to QUIT.
$COLON 5,'ABORT',ABORT
DW NULLS,THROW
; abort" ( f -- )
; Run time routine of ABORT" . Abort with a message.
$COLON COMPO+6,'abort"',ABORQ
DW QBRAN,ABOR1 ;text flag
DW DOSTR,THROW ;pass error string
ABOR1: DW DOSTR,DROP,EXIT ;drop error
;; The text interpreter
; $INTERPRET ( a -- )
; Interpret a word. If failed, try to convert it to an integer.
$COLON 10,'$INTERPRET',INTER
DW NAMEQ,QDUP ;?defined
DW QBRAN,INTE1
DW AT,DOLIT,COMPO,ANDD ;?compile only lexicon bits
D$ ABORQ,' compile only'
DW EXECU,EXIT ;execute defined word
INTE1: DW TNUMB,ATEXE ;convert a number
DW QBRAN,INTE2
DW EXIT
INTE2: DW THROW ;error
; [ ( -- )
; Start the text interpreter.
$COLON IMEDD+1,'[',LBRAC
DW DOLIT,INTER,TEVAL,STORE,EXIT
; .OK ( -- )
; Display 'ok' only while interpreting.
$COLON 3,'.OK',DOTOK
DW DOLIT,INTER,TEVAL,AT,EQUAL
DW QBRAN,DOTO1
D$ DOTQP,' ok'
DOTO1: DW CR,EXIT
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -