mirror of
https://github.com/PDP-10/its.git
synced 2026-01-18 09:12:08 +00:00
979 lines
15 KiB
Groff
979 lines
15 KiB
Groff
TITLE TENTH
|
|
|
|
EXPUNGE .SWAP,.BEGIN,.END,.ELSE,.I
|
|
|
|
IFNDEF TS,TS==0
|
|
|
|
X=14 ; pointer into code/parameter field
|
|
PC=15 ; the interpreter's program counter
|
|
PP=16 ; parameter stack pointer
|
|
P=17 ; return stack pointer
|
|
IFE TS,[
|
|
APR=0
|
|
CTYIN=32
|
|
CTYOUT=33
|
|
]
|
|
IFN TS,[
|
|
TYIC==1
|
|
TYOC==2
|
|
]
|
|
|
|
PDLLEN=100
|
|
PDL: .=.+PDLLEN
|
|
PPDL: .=.+PDLLEN
|
|
RSP: -PDLLEN,,PDL-1
|
|
PSP: -PDLLEN,,PPDL-1
|
|
INP: 0
|
|
INBUF: 0 ? .=.+40
|
|
INBUFBP: 440700,,INBUF+1
|
|
WORDBUF: 0 ? .=.+10
|
|
WORDBP: 440700,,WORDBUF+1
|
|
|
|
START:
|
|
IFE TS, SETZM CTYIN
|
|
IFN TS,[
|
|
.OPEN TYIC,[.UAI,,'TTY]
|
|
.LOSE
|
|
.OPEN TYOC,[.UAO,,'TTY]
|
|
.LOSE
|
|
.CALL [ SETZ ; turn off echoing
|
|
SIXBIT /TTYSET/
|
|
MOVEI TYIC
|
|
MOVE [030202,,020202]
|
|
SETZ [030202,,020202] ]
|
|
]
|
|
MOVE P,RSP
|
|
MOVE PP,PSP
|
|
MOVEI PC,[.QUIT]
|
|
JRST NEXT
|
|
|
|
;
|
|
; output
|
|
;
|
|
|
|
; print ASCII character in AC 0 - changes AC 0
|
|
PUTCHAR:
|
|
IFE TS,[
|
|
IORI 0,400 ; valid bit
|
|
MOVEM 0,CTYOUT
|
|
CONO APR,12000 ; 10000 = set flags, 2000 = interrupt flag
|
|
SKIPE CTYOUT ; wait for transmission to complete
|
|
JRST .-1
|
|
]
|
|
IFN TS, .IOT TYOC,0
|
|
CAIE 0,IFE TS,[400\]^J
|
|
POPJ P,
|
|
MOVEI 0,^M
|
|
JRST PUTCHAR
|
|
|
|
; print null-terminated ASCII string in AC 0 - changes AC 0 1
|
|
PUTS:
|
|
MOVE 1,0 ; address
|
|
HRLI 1,440700 ; 7-bit bytes
|
|
ILDB 0,1
|
|
CAIN 0,0
|
|
POPJ P,
|
|
PUSHJ P,PUTCHAR
|
|
JRST .-4
|
|
|
|
; prints a counted ASCII string in AC 0
|
|
PUTSN:
|
|
MOVE 2,@0 ; char count
|
|
AOS 0
|
|
MOVE 1,0
|
|
HRLI 1,440700
|
|
PUTSN1: SOSGE 2
|
|
POPJ P,
|
|
ILDB 0,1
|
|
PUSHJ P,PUTCHAR
|
|
JRST PUTSN1
|
|
|
|
; print 'panic' and halt
|
|
PANIC:
|
|
MOVEI 0,[ ASCIZ "
|
|
panic
|
|
" ]
|
|
PUSHJ P,PUTS
|
|
JRST 4,.
|
|
|
|
BASE: 12
|
|
DIGITS: "0 ? "1 ? "2 ? "3 ? "4 ? "5 ? "6 ? "7 ? "8 ? "9 ? "A ? "B ? "C ? "D ? "E ? "F
|
|
|
|
; print number in AC 1 - changes AC 0 1 2
|
|
PRINTN:
|
|
JUMPGE 1,UPRINTN
|
|
MOVEI 0,"-
|
|
PUSHJ P,PUTCHAR
|
|
MOVM 1,1
|
|
UPRINTN:
|
|
IDIV 1,BASE
|
|
JUMPE 1,UPR1
|
|
PUSH P,2
|
|
PUSHJ P,UPRINTN
|
|
POP P,2
|
|
UPR1:
|
|
MOVE 0,DIGITS(2)
|
|
JRST PUTCHAR
|
|
|
|
; prints number in AC 1 and a space - changes AC 0 1
|
|
PRNTNSP:
|
|
PUSHJ P,PRINTN
|
|
MOVEI 0,40 ; space
|
|
JRST PUTCHAR
|
|
|
|
; reads one character into AC 0
|
|
GETCH:
|
|
IFE TS,[
|
|
CONO APR,12000 ; 10000 = set flags, 2000 = interrupt flag
|
|
MOVE 0,CTYIN
|
|
CAIN 0,0
|
|
JRST .-2
|
|
SETZM CTYIN
|
|
TRZ 0,400
|
|
]
|
|
IFN TS, .IOT TYIC,0
|
|
CAIN 0,^M
|
|
MOVEI 0,^J
|
|
POPJ P,
|
|
|
|
;
|
|
; input
|
|
;
|
|
|
|
; reads one character into AC 0 and echos - changes AC 0 1
|
|
GETCHAR:
|
|
PUSHJ P,GETCH
|
|
MOVE 1,0
|
|
PUSHJ P,PUTCHAR
|
|
MOVE 0,1
|
|
POPJ P,
|
|
|
|
; reads characters into INBUF - changes AC 0 1 2
|
|
GETS:
|
|
SETZM INP
|
|
MOVE 1,INBUFBP
|
|
SETZ 2,
|
|
NEXTC: PUSHJ P,GETCH
|
|
CAIN 0,^J
|
|
JRST GETSNL
|
|
CAIN 0,25
|
|
JRST GETSKL
|
|
CAIN 0,^H
|
|
JRST GETSBS
|
|
IDPB 0,1
|
|
AOS 2
|
|
PUSHJ P,PUTCHAR
|
|
JRST NEXTC
|
|
GETSKL: ; kill line
|
|
MOVEI 0,^J
|
|
PUSHJ P,PUTCHAR
|
|
JRST GETS
|
|
GETSBS: ; backspace
|
|
PUSHJ P,PUTCHAR
|
|
MOVE 1,INBUFBP
|
|
SOSGE 2
|
|
SETZ 2,
|
|
MOVE 0,2
|
|
SOSGE 0
|
|
JRST NEXTC
|
|
IBP 1
|
|
JRST .-3
|
|
GETSNL:
|
|
MOVEI 0,40 ; space
|
|
PUSHJ P,PUTCHAR
|
|
SETZ 0,
|
|
IDPB 0,1
|
|
MOVEM 2,INBUF
|
|
POPJ P,
|
|
|
|
;
|
|
; forth things
|
|
;
|
|
|
|
; Code field values
|
|
ASM:
|
|
AOS X
|
|
JRST (X)
|
|
|
|
DOCON:
|
|
AOS X
|
|
MOVE 0,(X)
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
DOVAR:
|
|
AOS X
|
|
PUSH PP,X
|
|
JRST NEXT
|
|
|
|
DOCOL:
|
|
AOS X
|
|
PUSH P,PC
|
|
MOVE PC,X
|
|
JRST NEXT
|
|
|
|
; counterpart of DOCOL
|
|
..EXIT: 0 ? 0,,4 ? ASCII "EXIT"
|
|
.EXIT: ASM
|
|
POP P,PC
|
|
JRST NEXT
|
|
|
|
; execute forth word at PC and increment PC
|
|
NEXT: MOVE X,(PC)
|
|
AOS PC
|
|
MOVE 1,(X)
|
|
JRST (1)
|
|
|
|
; Dictionary
|
|
LATEST: .LATEST
|
|
HERE: END1
|
|
|
|
; parses one word from the input stream into the word buffer
|
|
; skips if a word was read
|
|
PARSEWORD:
|
|
SETZM WORDBUF
|
|
MOVE 0,INP
|
|
MOVE 1,INBUFBP
|
|
SOSGE 0
|
|
JRST .+3
|
|
IBP 1
|
|
JRST .-3
|
|
POP PP,2 ; terminator
|
|
MOVE 0,INP
|
|
PWDELIM:
|
|
ILDB 3,1
|
|
AOS 0
|
|
CAMLE 0,INBUF ; check length
|
|
JRST PWEND
|
|
CAMN 3,2 ; check for delimiter
|
|
JRST PWDELIM
|
|
MOVEM 0,INP ; save beginning of word
|
|
MOVE 4,WORDBP
|
|
PWCHAR:
|
|
IDPB 3,4
|
|
ILDB 3,1
|
|
AOS 0
|
|
CAMLE 0,INBUF ; check length
|
|
JRST .+3
|
|
CAME 3,2 ; check for delimiter
|
|
JRST PWCHAR
|
|
MOVE 1,INP
|
|
SUB 1,0
|
|
MOVMM 1,WORDBUF
|
|
PWEND:
|
|
MOVEM 0,INP
|
|
SKIPE WORDBUF ; skip one instruction if we have a word
|
|
AOS (P)
|
|
POPJ P,
|
|
|
|
; find word AC 1 in dictionary, skip if found at return it in AC 1
|
|
FIND:
|
|
MOVE 2,LATEST
|
|
SKIPA
|
|
FINDNEXT:
|
|
MOVE 2,(2)
|
|
SKIPN 2
|
|
POPJ P, ; not found
|
|
HRRZ 0,1(2) ; length
|
|
CAME 0,(1)
|
|
JRST FINDNEXT
|
|
MOVEI 3,1(1) ; byte pointer of word to look up
|
|
HRLI 3,440700
|
|
MOVEI 4,2(2) ; byte pointer of word in dictionary
|
|
HRLI 4,440700
|
|
FINDLOOP:
|
|
ILDB 5,3
|
|
ILDB 6,4
|
|
CAME 5,6
|
|
JRST FINDNEXT
|
|
SOJG 0,FINDLOOP
|
|
; found
|
|
MOVE 1,2
|
|
AOS (P)
|
|
POPJ P,
|
|
|
|
; go from dictionary entry AC 1 to code field
|
|
TCFA:
|
|
HRRZ 0,1(1) ; length
|
|
MOVEI 2,2(1) ; byte pointer
|
|
HRLI 2,440700
|
|
IBP 2
|
|
SOJG 0,.-1
|
|
HRRZ 1,4 ; get word address from byte pointer
|
|
HLRZ 0,4
|
|
CAIE 0,440700 ; go to next word unless we're already there
|
|
AOS 1
|
|
POPJ P,
|
|
|
|
; parse number in string AC 1, skip if number and return it in AC 0
|
|
CHECKNUM:
|
|
SETZ 0,
|
|
MOVE 2,(1) ; length
|
|
AOS 1
|
|
HRLI 1,440700 ; byte pointer
|
|
SETZ 4, ; sign
|
|
ILDB 3,1
|
|
CAIE 3,"-
|
|
JRST .+5
|
|
SOSN 2
|
|
POPJ P,
|
|
AOS 4
|
|
NUM1: ILDB 3,1
|
|
CAIGE 3,"0
|
|
POPJ P,
|
|
CAILE 3,"9
|
|
JRST .+3
|
|
SUBI 3,"0
|
|
JRST NUM2
|
|
CAIGE 3,"A
|
|
POPJ P,
|
|
CAILE 3,"F
|
|
JRST .+3
|
|
SUBI 3,"A
|
|
JRST NUM2
|
|
CAIGE 3,"a
|
|
POPJ P,
|
|
CAILE 3,"f
|
|
POPJ P,
|
|
SUBI 3,"a
|
|
NUM2: IMUL 0,BASE
|
|
ADD 0,3
|
|
SOJG 2,NUM1
|
|
SKIPE 4 ; negate if sign is set
|
|
MOVN 0,0
|
|
AOS (P)
|
|
POPJ P,
|
|
|
|
STATE: 0 ; interpreter state (0 = interpreting, else compiling)
|
|
|
|
..INTERPRET: ..EXIT ? 0,,9 ? ASCII "INTERPRET"
|
|
.INTERPRET: ASM
|
|
SKIPN INBUF
|
|
PUSHJ P,GETS
|
|
NEXTW: MOVEI 0,40 ; space
|
|
PUSH PP,0
|
|
PUSHJ P,PARSEWORD
|
|
JRST OK ; end of line
|
|
MOVEI 1,WORDBUF
|
|
PUSHJ P,FIND
|
|
JRST NUMBER
|
|
HLR X,1(1) ; get flags
|
|
PUSHJ P,TCFA
|
|
JUMPN X,.+3 ; immediate
|
|
SKIPE STATE
|
|
JRST COMPW ; compile word
|
|
MOVE X,1 ; interpret word
|
|
MOVE 1,(X)
|
|
JRST (1)
|
|
COMPW: MOVE 2,HERE
|
|
MOVEM 1,(2)
|
|
AOS HERE
|
|
JRST NEXTW
|
|
NUMBER: MOVEI 1,WORDBUF
|
|
PUSHJ P,CHECKNUM
|
|
JRST PANIC
|
|
SKIPE STATE
|
|
JRST COMPN ; compile number
|
|
PUSH PP,0 ; interpret number
|
|
JRST NEXTW
|
|
COMPN: MOVE 1,HERE
|
|
MOVEI 2,.LITERAL
|
|
MOVEM 2,(1)
|
|
MOVEM 0,1(1)
|
|
AOS HERE
|
|
AOS HERE
|
|
JRST NEXTW
|
|
OK: SKIPE STATE
|
|
JRST .+3
|
|
MOVEI 0,[ASCIZ " ok
|
|
"]
|
|
JRST .+2
|
|
MOVEI 0,[ASCIZ " compiled
|
|
"]
|
|
PUSHJ P,PUTS
|
|
JRST NEXTW-1
|
|
|
|
..QUIT: ..INTERPRET ? 0,,4 ? ASCII "QUIT"
|
|
.QUIT: DOCOL
|
|
[ ASM ? MOVE P,RSP ? JRST NEXT ]
|
|
.INTERPRET
|
|
.BRANCH
|
|
-2
|
|
|
|
..ABORT: ..QUIT ? 0,,5 ? ASCII "ABORT"
|
|
.ABORT: DOCOL
|
|
[ ASM ? MOVE PP,PSP ? JRST NEXT ]
|
|
.QUIT
|
|
|
|
..CREATE: ..ABORT ? 0,,6 ? ASCII "CREATE"
|
|
.CREATE: ASM
|
|
PUSHJ P,CREATE
|
|
JRST NEXT
|
|
|
|
CREATE:
|
|
MOVEI 0,40 ; space
|
|
PUSH PP,0
|
|
PUSHJ P,PARSEWORD
|
|
JRST PANIC
|
|
MOVE 1,LATEST
|
|
MOVE 2,HERE
|
|
MOVEM 1,(2) ; link into dict
|
|
MOVEM 2,LATEST
|
|
MOVEI 1,WORDBUF ; copy word
|
|
HRRZ 0,0(1) ; length
|
|
MOVEM 0,1(2)
|
|
MOVEI 3,1(1) ; byte pointer of word buffer
|
|
HRLI 3,440700
|
|
MOVEI 4,2(2) ; byte pointer of word in dictionary
|
|
HRLI 4,440700
|
|
ILDB 5,3 ; copy chars
|
|
IDPB 5,4
|
|
SOJG 0,.-2
|
|
HRRZ 1,4 ; get word address from byte pointer
|
|
HLRZ 0,4
|
|
CAIE 0,440700 ; go to next word unless we're already there
|
|
AOS 1
|
|
MOVEM 1,HERE
|
|
POPJ P,
|
|
|
|
..COLON: ..CREATE ? 0,,1 ? ASCII ":"
|
|
.COLON: DOCOL
|
|
.CREATE
|
|
.LITERAL ? DOCOL ? .COMMA
|
|
.RBRK
|
|
.EXIT
|
|
|
|
..SEMICOLON: ..COLON ? 1,,1 ? ASCII ";"
|
|
.SEMICOLON: DOCOL
|
|
.LITERAL ? .EXIT ? .COMMA
|
|
.LBRK
|
|
.EXIT
|
|
|
|
..CONST: ..SEMICOLON ? 0,,8 ? ASCII "CONSTANT"
|
|
.CONST: DOCOL
|
|
.CREATE
|
|
.LITERAL ? DOCON ? .COMMA
|
|
.COMMA
|
|
.EXIT
|
|
|
|
..VAR: ..CONST ? 0,,8 ? ASCII "VARIABLE"
|
|
.VAR: DOCOL
|
|
.CREATE
|
|
.LITERAL ? DOVAR ? .COMMA
|
|
.LITERAL ? 0 ? .COMMA
|
|
.EXIT
|
|
|
|
..BRANCH: ..VAR ? 0,,6 ? ASCII "BRANCH"
|
|
.BRANCH: ASM
|
|
MOVE 0,(PC)
|
|
ADD PC,0
|
|
JRST NEXT
|
|
|
|
..ZBRANCH: ..BRANCH ? 0,,7 ? ASCII "0BRANCH"
|
|
.ZBRANCH: ASM
|
|
POP PP,1
|
|
SKIPE 1
|
|
JRST .+4
|
|
MOVE 0,(PC)
|
|
ADD PC,0
|
|
JRST NEXT
|
|
AOS PC
|
|
JRST NEXT
|
|
|
|
..LITERAL: ..ZBRANCH ? 0,,9 ? ASCII "(LITERAL)"
|
|
.LITERAL: ASM
|
|
MOVE 0,(PC)
|
|
AOS PC
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..COMMA: ..LITERAL ? 0,,1 ? ASCII ","
|
|
.COMMA: ASM
|
|
MOVE 1,HERE
|
|
POP PP,0
|
|
MOVEM 0,(1)
|
|
AOS HERE
|
|
JRST NEXT
|
|
|
|
..LBRK: ..COMMA ? 0,,1 ? ASCII "["
|
|
.LBRK: ASM
|
|
SETZM STATE
|
|
JRST NEXT
|
|
|
|
..RBRK: ..LBRK ? 0,,1 ? ASCII "]"
|
|
.RBRK: ASM
|
|
MOVEI 0,1
|
|
MOVEM 0,STATE
|
|
JRST NEXT
|
|
|
|
..IMMED: ..RBRK ? 0,,9 ? ASCII "IMMEDIATE"
|
|
.IMMED: ASM
|
|
MOVE 1,LATEST
|
|
MOVS 0,1
|
|
XORM 0,1(1)
|
|
JRST NEXT
|
|
|
|
..DOT: ..IMMED ? 0,,1 ? ASCII "."
|
|
.DOT: ASM
|
|
POP PP,1
|
|
PUSHJ P,PRNTNSP
|
|
JRST NEXT
|
|
|
|
..DOTS: ..DOT ? 0,,2 ? ASCII ".S"
|
|
.DOTS: ASM
|
|
MOVEI 0,"<
|
|
PUSHJ P,PUTCHAR
|
|
HRRZ 1,PP
|
|
SUBI 1,PPDL-1
|
|
MOVN 3,1 ; loop counter
|
|
PUSHJ P,PRINTN
|
|
MOVEI 0,">
|
|
PUSHJ P,PUTCHAR
|
|
SKIPN 3
|
|
JRST NEXT ; empty stack
|
|
MOVS 3,3 ; put counter in left word
|
|
HRRI 3,PPDL
|
|
MOVEI 0,40
|
|
PUSHJ P,PUTCHAR
|
|
MOVE 1,(3)
|
|
PUSHJ P,PRNTNSP
|
|
AOBJN 3,.-2
|
|
JRST NEXT
|
|
|
|
..DROP: ..DOTS ? 0,,4 ? ASCII "DROP"
|
|
.DROP: ASM
|
|
POP PP,0
|
|
JRST NEXT
|
|
|
|
..SWAP: ..DROP ? 0,,4 ? ASCII "SWAP"
|
|
.SWAP: ASM
|
|
POP PP,0
|
|
EXCH 0,(PP)
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..DUP: ..SWAP ? 0,,3 ? ASCII "DUP"
|
|
.DUP: ASM
|
|
PUSH PP,(PP)
|
|
JRST NEXT
|
|
|
|
..QDUP: ..DUP ? 0,,4 ? ASCII "?DUP"
|
|
.QDUP: ASM
|
|
SKIPE (PP)
|
|
PUSH PP,(PP)
|
|
JRST NEXT
|
|
|
|
..OVER: ..QDUP ? 0,,4 ? ASCII "OVER"
|
|
.OVER: ASM
|
|
PUSH PP,-1(PP)
|
|
JRST NEXT
|
|
|
|
..ROT: ..OVER ? 0,,3 ? ASCII "ROT"
|
|
.ROT: ASM
|
|
POP PP,0
|
|
POP PP,1
|
|
POP PP,2
|
|
PUSH PP,1
|
|
PUSH PP,0
|
|
PUSH PP,2
|
|
JRST NEXT
|
|
|
|
..NROT: ..ROT ? 0,,4 ? ASCII "-ROT"
|
|
.NROT: ASM
|
|
POP PP,0
|
|
POP PP,1
|
|
POP PP,2
|
|
PUSH PP,0
|
|
PUSH PP,2
|
|
PUSH PP,1
|
|
JRST NEXT
|
|
|
|
..TOR: ..NROT ? 0,,2 ? ASCII ">R"
|
|
.TOR: ASM
|
|
POP PP,0
|
|
PUSH P,0
|
|
JRST NEXT
|
|
|
|
..FROMR: ..TOR ? 0,,2 ? ASCII "R>"
|
|
.FROMR: ASM
|
|
POP P,0
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..FTCH: ..FROMR ? 0,,2 ? ASCII "R@"
|
|
.FTCHR: ASM
|
|
MOVE 0,(P)
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..RSP: ..FTCH ? 0,,4 ? ASCII "RSP@"
|
|
.RSP: ASM
|
|
PUSH PP,P
|
|
JRST NEXT
|
|
|
|
..INCR: ..RSP ? 0,,2 ? ASCII "1+"
|
|
.INCR: ASM
|
|
AOS (PP)
|
|
JRST NEXT
|
|
|
|
..DECR: ..INCR ? 0,,2 ? ASCII "1-"
|
|
.DECR: ASM
|
|
SOS (PP)
|
|
JRST NEXT
|
|
|
|
..PLUS: ..DECR ? 0,,1 ? ASCII "+"
|
|
.PLUS: ASM
|
|
POP PP,0
|
|
ADDM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..MINUS: ..PLUS ? 0,,1 ? ASCII "-"
|
|
.MINUS: ASM
|
|
POP PP,0
|
|
POP PP,1
|
|
SUB 1,0
|
|
PUSH PP,1
|
|
JRST NEXT
|
|
|
|
..MUL: ..MINUS ? 0,,1 ? ASCII "*"
|
|
.MUL: ASM
|
|
POP PP,0
|
|
IMULM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..DIVMOD: ..MUL ? 0,,4 ? ASCII "/MOD"
|
|
.DIVMOD: ASM
|
|
POP PP,1
|
|
POP PP,0
|
|
IDIV 0,1
|
|
PUSH PP,1
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..DIV: ..DIVMOD ? 0,,1 ? ASCII "/"
|
|
.DIV: ASM
|
|
POP PP,1
|
|
POP PP,0
|
|
IDIV 0,1
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..MOD: ..DIV ? 0,,3 ? ASCII "MOD"
|
|
.MOD: ASM
|
|
POP PP,1
|
|
POP PP,0
|
|
IDIV 0,1
|
|
PUSH PP,1
|
|
JRST NEXT
|
|
|
|
..EQU: ..MOD ? 0,,1 ? ASCII "="
|
|
.EQU: ASM
|
|
POP PP,0
|
|
CAME 0,(PP)
|
|
JRST FALSE
|
|
TRUE: SETOM (PP)
|
|
JRST NEXT
|
|
FALSE: SETZM (PP)
|
|
JRST NEXT
|
|
|
|
..NEQU: ..EQU ? 0,,2 ? ASCII "<>"
|
|
.NEQU: ASM
|
|
POP PP,0
|
|
CAMN 0,(PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..LT: ..NEQU ? 0,,1 ? ASCII "<"
|
|
.LT: ASM
|
|
POP PP,0
|
|
CAMG 0,(PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..LE: ..LT ? 0,,2 ? ASCII "<="
|
|
.LE: ASM
|
|
POP PP,0
|
|
CAMGE 0,(PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..GT: ..LE ? 0,,1 ? ASCII ">"
|
|
.GT: ASM
|
|
POP PP,0
|
|
CAML 0,(PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..GE: ..GT ? 0,,2 ? ASCII ">="
|
|
.GE: ASM
|
|
POP PP,0
|
|
CAMLE 0,(PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZEQU: ..GE ? 0,,2 ? ASCII "0="
|
|
.ZEQU: ASM
|
|
SKIPE (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZNEQU: ..ZEQU ? 0,,3 ? ASCII "0<>"
|
|
.ZNEQU: ASM
|
|
SKIPN (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZLT: ..ZNEQU ? 0,,2 ? ASCII "0<"
|
|
.ZLT: ASM
|
|
SKIPL (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZLE: ..ZLT ? 0,,3 ? ASCII "0<="
|
|
.ZLE: ASM
|
|
SKIPLE (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZGT: ..ZLE ? 0,,2 ? ASCII "0>"
|
|
.ZGT: ASM
|
|
SKIPG (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ZGE: ..ZGT ? 0,,3 ? ASCII "0>="
|
|
.ZGE: ASM
|
|
SKIPGE (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..AND: ..ZGE ? 0,,3 ? ASCII "AND"
|
|
.AND: ASM
|
|
POP PP,0
|
|
ANDM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..OR: ..AND ? 0,,2 ? ASCII "OR"
|
|
.OR: ASM
|
|
POP PP,0
|
|
IORM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..XOR: ..OR ? 0,,3 ? ASCII "XOR"
|
|
.XOR: ASM
|
|
POP PP,0
|
|
XORM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..NOT: ..XOR ? 0,,3 ? ASCII "NOT"
|
|
.NOT: ASM ; same as 0=
|
|
SKIPE (PP)
|
|
JRST FALSE
|
|
JRST TRUE
|
|
|
|
..ABS: ..NOT ? 0,,3 ? ASCII "ABS"
|
|
.ABS: ASM
|
|
MOVM 0,(PP)
|
|
MOVEM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..NEG: ..ABS ? 0,,6 ? ASCII "NEGATE"
|
|
.NEG: ASM
|
|
MOVN 0,(PP)
|
|
MOVEM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..MIN: ..NEG ? 0,,3 ? ASCII "MIN"
|
|
.MIN: ASM
|
|
POP PP,0
|
|
CAMGE 0,(PP)
|
|
MOVEM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..MAX: ..MIN ? 0,,3 ? ASCII "MAX"
|
|
.MAX: ASM
|
|
POP PP,0
|
|
CAMLE 0,(PP)
|
|
MOVEM 0,(PP)
|
|
JRST NEXT
|
|
|
|
..WORD: ..MAX ? 0,,4 ? ASCII "WORD"
|
|
.WORD: ASM
|
|
PUSHJ P,PARSEWORD
|
|
JRST .+1
|
|
PUSH PP,WORDBUF
|
|
JRST NEXT
|
|
|
|
..STORE: ..WORD ? 0,,1 ? ASCII "!"
|
|
.STORE: ASM
|
|
POP PP,1
|
|
POP PP,0
|
|
MOVEM 0,(1)
|
|
JRST NEXT
|
|
|
|
..PSTORE: ..STORE ? 0,,2 ? ASCII "+!"
|
|
.PSTORE: ASM
|
|
POP PP,1
|
|
POP PP,0
|
|
ADDM 0,(1)
|
|
JRST NEXT
|
|
|
|
..FETCH: ..PSTORE ? 0,,1 ? ASCII "@"
|
|
.FETCH: ASM
|
|
MOVE 1,(PP)
|
|
MOVE 1,(1)
|
|
MOVEM 1,(PP)
|
|
JRST NEXT
|
|
|
|
..HERE: ..FETCH ? 0,,4 ? ASCII "HERE"
|
|
.HERE: DOCON ? HERE
|
|
|
|
..STATE: ..HERE ? 0,,5 ? ASCII "STATE"
|
|
.STATE: DOCON ? STATE
|
|
|
|
..BASE: ..STATE ? 0,,4 ? ASCII "BASE"
|
|
.BASE: DOCON ? BASE
|
|
|
|
..INP: ..BASE ? 0,,3 ? ASCII ">IN"
|
|
.INP: DOCON ? INP
|
|
|
|
..IF: ..INP ? 1,,2 ? ASCII "IF"
|
|
.IF: DOCOL
|
|
.LITERAL ? .ZBRANCH ? .COMMA
|
|
.HERE ? .FETCH
|
|
.LITERAL ? 0 ? .COMMA
|
|
.EXIT
|
|
|
|
..THEN: ..IF ? 1,,4 ? ASCII "THEN"
|
|
.THEN: DOCOL
|
|
.DUP
|
|
.HERE ? .FETCH ? .SWAP ? .MINUS
|
|
.SWAP ? .STORE
|
|
.EXIT
|
|
|
|
..ELSE: ..THEN ? 1,,4 ? ASCII "ELSE"
|
|
.ELSE: DOCOL
|
|
.LITERAL ? .BRANCH ? .COMMA
|
|
.HERE ? .FETCH
|
|
.LITERAL ? 0 ? .COMMA
|
|
.SWAP
|
|
.DUP
|
|
.HERE ? .FETCH ? .SWAP ? .MINUS
|
|
.SWAP ? .STORE
|
|
.EXIT
|
|
|
|
..BEGIN: ..ELSE ? 1,,5 ? ASCII "BEGIN"
|
|
.BEGIN: DOCOL
|
|
.HERE ? .FETCH
|
|
.EXIT
|
|
|
|
..AGAIN: ..BEGIN ? 1,,5 ? ASCII "AGAIN"
|
|
.AGAIN: DOCOL
|
|
.LITERAL ? .BRANCH ? .COMMA
|
|
.HERE ? .FETCH ? .MINUS ? .COMMA
|
|
.EXIT
|
|
|
|
..UNTIL: ..AGAIN ? 1,,5 ? ASCII "UNTIL"
|
|
.UNTIL: DOCOL
|
|
.LITERAL ? .ZBRANCH ? .COMMA
|
|
.HERE ? .FETCH ? .MINUS ? .COMMA
|
|
.EXIT
|
|
|
|
; same as IF really
|
|
..WHILE: ..UNTIL ? 1,,5 ? ASCII "WHILE"
|
|
.WHILE: DOCOL
|
|
.LITERAL ? .ZBRANCH ? .COMMA
|
|
.HERE ? .FETCH
|
|
.LITERAL ? 0 ? .COMMA
|
|
.EXIT
|
|
|
|
..REPEAT: ..WHILE ? 1,,6 ? ASCII "REPEAT"
|
|
.REPEAT: DOCOL
|
|
.LITERAL ? .BRANCH ? .COMMA
|
|
.SWAP
|
|
.HERE ? .FETCH ? .MINUS ? .COMMA
|
|
.DUP
|
|
.HERE ? .FETCH ? .SWAP ? .MINUS
|
|
.SWAP ? .STORE
|
|
.EXIT
|
|
|
|
..DO: ..REPEAT ? 1,,2 ? ASCII "DO"
|
|
.DO: DOCOL
|
|
.LITERAL ? .SWAP ? .COMMA
|
|
.LITERAL ? .TOR ? .COMMA
|
|
.LITERAL ? .TOR ? .COMMA
|
|
.HERE ? .FETCH
|
|
.EXIT
|
|
|
|
; remove index and limit from return stack
|
|
..UNLOOP: ..DO ? 0,,6 ? ASCII "UNLOOP"
|
|
.UNLOOP: ASM
|
|
POP P,0
|
|
POP P,0
|
|
JRST NEXT
|
|
|
|
..LOOP: ..UNLOOP ? 1,,4 ? ASCII "LOOP"
|
|
.LOOP: DOCOL
|
|
.LITERAL ? .FROMR ? .COMMA ; index
|
|
.LITERAL ? .INCR ? .COMMA
|
|
.LITERAL ? .DUP ? .COMMA
|
|
.LITERAL ? .FTCHR ? .COMMA ; limit
|
|
.LITERAL ? .GE ? .COMMA ; branch back if i >= limit is false
|
|
.LITERAL ? .SWAP ? .COMMA ; put index back on return stack
|
|
.LITERAL ? .TOR ? .COMMA
|
|
.LITERAL ? .ZBRANCH ? .COMMA
|
|
.HERE ? .FETCH ? .MINUS ? .COMMA
|
|
.LITERAL ? .UNLOOP ? .COMMA
|
|
.EXIT
|
|
|
|
..PLULOOP: ..LOOP ? 1,,5 ? ASCII "+LOOP"
|
|
.PLUSLOOP: DOCOL
|
|
.LITERAL ? .FROMR ? .COMMA ; index
|
|
.LITERAL ? .PLUS ? .COMMA ; only difference to above code
|
|
.LITERAL ? .DUP ? .COMMA
|
|
.LITERAL ? .FTCHR ? .COMMA ; limit
|
|
.LITERAL ? .GE ? .COMMA ; branch back if i >= limit is false
|
|
.LITERAL ? .SWAP ? .COMMA ; put index back on return stack
|
|
.LITERAL ? .TOR ? .COMMA
|
|
.LITERAL ? .ZBRANCH ? .COMMA
|
|
.HERE ? .FETCH ? .MINUS ? .COMMA
|
|
.LITERAL ? .UNLOOP ? .COMMA
|
|
.EXIT
|
|
|
|
..I: ..PLULOOP ? 0,,1 ? ASCII "I"
|
|
.I: ASM
|
|
MOVE 0,(P)
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..J: ..I ? 0,,1 ? ASCII "J"
|
|
.J: ASM
|
|
MOVE 0,2(P)
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..EMIT: ..J ? 0,,4 ? ASCII "EMIT"
|
|
.EMIT: ASM
|
|
POP PP,0
|
|
PUSHJ P,PUTCHAR
|
|
JRST NEXT
|
|
|
|
..KEY: ..EMIT ? 0,,3 ? ASCII "KEY"
|
|
.KEY: ASM
|
|
PUSHJ P,GETCH
|
|
PUSH PP,0
|
|
JRST NEXT
|
|
|
|
..CR: ..KEY ? 0,,2 ? ASCII "CR"
|
|
.CR: DOCOL
|
|
.LITERAL ? ^J
|
|
.EMIT
|
|
.EXIT
|
|
|
|
.LATEST:
|
|
..SP: ..KEY ? 0,,5 ? ASCII "SPACE"
|
|
.SP: DOCOL
|
|
.LITERAL ? 40
|
|
.EMIT
|
|
.EXIT
|
|
|
|
END1:
|
|
|
|
END START
|