diff --git a/f.py b/f.py index 67b3548..7994242 100644 --- a/f.py +++ b/f.py @@ -1,9 +1,25 @@ -f = open('forth2.f','r') +f = open('forth2.fth','r') lf = f.readlines() f.close() df = {} -"""for i in lf: +def is_int(x): + if x[:2]=="0x": + try: + a=int(x[2:],16) + return True + except: + return False + try: + a=int(x) + return True + except: + return False + +print("Missing words:") +for i in lf: k = i.split() + if len(k)>=1 and k[0] == "\\": + continue if len(k)>=3 and k[1] == "CONSTANT" and k[0]!=":": df[k[2]] = [k[0]] elif len(k)>=3: @@ -21,7 +37,7 @@ for l in df.values(): for i in l: if df.get(i, None)==None and not is_int(i) and i not in lcore and i not in k and i[:2]!="0x": k.append(i) - print(i)""" + print(i) def setmemory(addr, value): memory[addr] = value&0xff diff --git a/forth2.f b/forth2.fth similarity index 82% rename from forth2.f rename to forth2.fth index 597836c..e1fa304 100644 --- a/forth2.f +++ b/forth2.fth @@ -145,13 +145,18 @@ FORTH : EXIT-IF-END SOURCE NIP >IN @ = IF SOURCE + 0 R> DROP THEN ; : PARSE-LIMITS SOURCE OVER + SWAP >IN @ + ; : >IN-END SOURCE NIP >IN ! ; +: COUNTED-STRING DUP HERE C! HERE 1+ -ROT OVER + SWAP DO I C@ OVER C! 1+ LOOP DROP HERE ; : PARSE-WORD EXIT-IF-END PARSE-LIMITS SKIP-WHITE 2DUP = IF >IN-END DROP 0 EXIT THEN DUP >R BEGIN DUP C@ 32 > WHILE 1+ 2DUP = IF >IN-END DROP R@ - R> SWAP EXIT THEN REPEAT NIP DUP SOURCE DROP - 1+ >IN ! R@ - R> SWAP ; -: PARSE EXIT-IF-END PARSE-LIMITS DUP >R ROT >R BEGIN DUP C@ R@ <> WHILE 1+ 2DUP = IF R> DROP >IN-END DROP R@ - R> SWAP EXIT THEN REPEAT R> DROP NIP DUP SOURCE DROP - 1+ >IN ! R@ - R> SWAP ; +: PARSE SOURCE NIP >IN @ = IF DROP SOURCE + 0 EXIT THEN PARSE-LIMITS DUP >R ROT >R BEGIN DUP C@ R@ <> WHILE 1+ 2DUP = IF R> DROP >IN-END DROP R@ - R> SWAP EXIT THEN REPEAT R> DROP NIP DUP SOURCE DROP - 1+ >IN ! R@ - R> SWAP ; + +\ TODO: Fix WORD not skipping leading delimiters +: WORD SOURCE NIP >IN @ = IF DROP 0 HERE C! HERE EXIT THEN PARSE-LIMITS DUP >R ROT >R BEGIN DUP C@ R@ <> WHILE 1+ 2DUP = IF R> DROP >IN-END DROP R@ - R> SWAP EXIT THEN REPEAT R> DROP NIP DUP SOURCE DROP - 1+ >IN ! R@ - R> SWAP COUNTED-STRING ; + : HEADER PARSE-WORD TUCK 0 C, OVER + SWAP DO I C@ C, LOOP LATEST @ , C, ; : : HEADER HERE DUP LT ! 42 C, ] ; : UNUSED HERE NEGATE ; : NCHAR DUP C@ DUP 58 < IF 48 - ELSE DUP 97 < IF 55 - ELSE 87 - THEN THEN ; -: >NUMBER DUP >R 0 DO NCHAR DUP BASE @ < OVER 0< INVERT AND IF 2SWAP BASE @ * 0 ROT BASE @ M* D+ ROT 0 D+ ROT 1+ ELSE DROP I UNLOOP R> - EXIT THEN LOOP R> DROP 0 ; +: >NUMBER DUP >R 0 DO NCHAR DUP BASE @ < OVER 0< INVERT AND IF 2SWAP BASE @ * 0 SWAP ROT BASE @ UM* D+ ROT 0 D+ ROT 1+ ELSE DROP I UNLOOP R> SWAP - EXIT THEN LOOP R> DROP 0 ; : NUMBER 0 0 2SWAP OVER C@ 45 = IF SWAP 1+ SWAP 1- >NUMBER 2SWAP DROP NEGATE -ROT ELSE >NUMBER ROT DROP THEN ; : SAVE-INPUT >IN @ 1 ; : RESTORE-INPUT DUP 1 = IF DROP >IN ! FALSE ELSE 0 ?DO DROP LOOP TRUE THEN ; @@ -171,7 +176,9 @@ FORTH : POSTPONE ' DUP 1- C@ 128 AND IF , ELSE ['] (lit) , , ['] , , THEN ; IMMEDIATE \ : LITERAL [ ' (lit) , ] , , ; IMMEDIATE : LITERAL ['] (lit) , , ; IMMEDIATE -: DOES> LATEST @ HERE OVER 1+ DUP ['] (branch) , ! CELL+ TUCK ! 4 + POSTPONE LITERAL ] ; +\ : DOES> LATEST @ HERE OVER 1+ DUP ['] (branch) ! CELL+ TUCK ! 4 + POSTPONE LITERAL ] ; +: (dodoes) ['] (branch) LATEST @ 1+ ! LATEST @ 7 + R@ CELL+ ! R> LATEST @ 3 + ! ; +: DOES> ['] (dodoes) , ['] (lit) , 0 , ; IMMEDIATE : ['] ' POSTPONE LITERAL ; IMMEDIATE : [COMPILE] ' , ; IMMEDIATE : ; ['] EXIT , LATEST ! POSTPONE [ ; IMMEDIATE @@ -185,10 +192,14 @@ FORTH : UNTIL ['] (0branch) , , ; IMMEDIATE : REPEAT ['] (branch) , , HERE SWAP ! ; IMMEDIATE : WHILE ['] (0branch) , HERE SWAP 0 , ; IMMEDIATE -: S" 34 PARSE ['] (branch) , HERE 0 , -ROT 2DUP OVER + SWAP DO I C@ C, LOOP NIP SWAP DUP HERE SWAP ! 2 + POSTPONE LITERAL POSTPONE LITERAL ; IMMEDIATE +: CASE 0 ; IMMEDIATE +: ENDCASE ['] DROP , BEGIN DUP 0<> WHILE HERE SWAP ! REPEAT DROP ; IMMEDIATE +: OF ['] OVER , ['] = , ['] (0branch) , HERE 0 , ['] DROP , ; IMMEDIATE +: ENDOF ['] (branch) , HERE 0 , HERE ROT ! ; IMMEDIATE +: S" 34 PARSE ['] (branch) , HERE 0 , -ROT 2DUP OVER + SWAP ?DO I C@ C, LOOP NIP SWAP DUP HERE SWAP ! 2 + POSTPONE LITERAL POSTPONE LITERAL ; IMMEDIATE : PAD HERE 36 + ; : VALUE HEADER HERE LATEST ! 77 C, , 33 C, 41 C, ; -: TO PARSE-WORD FIND-WORD 1+ STATE @ IF ['] ! , ELSE ! THEN ; IMMEDIATE +: TO PARSE-WORD FIND-WORD 1+ STATE @ IF POSTPONE LITERAL ['] ! , ELSE ! THEN ; IMMEDIATE : COMPILE, , ; : AGAIN ['] (branch) , , ; : ABORT EMPTYS QUIT ; @@ -203,12 +214,12 @@ FORTH : # BASE @ UDM/MOD ROT DUP 9 > IF 55 + ELSE 48 + THEN HOLD ; : #S BEGIN # 2DUP D0= UNTIL ; : ." POSTPONE S" ['] TYPE , ; IMMEDIATE -: C" 34 PARSE ['] (branch) , HERE 0 , -ROT DUP C, OVER SWAP 2DUP OVER + SWAP DO I C@ C, LOOP ROT HERE SWAP ! SWAP POSTPONE LITERAL ; IMMEDIATE +: C" 34 PARSE ['] (branch) , HERE 0 , -ROT HERE -ROT DUP C, OVER + SWAP ?DO I C@ C, LOOP SWAP HERE SWAP ! POSTPONE LITERAL ; IMMEDIATE : <# PAD HERE ! ; : #> 2DROP HERE @ PAD OVER - ; : SIGN 0< IF 45 HOLD THEN ; : CONVERT -1 >NUMBER DROP ; -: MOVE -ROT 2DUP > IF ROT 0 DO OVER @ OVER ! CELL+ SWAP CELL+ LOOP ELSE 2 PICK CELLS TUCK + -ROT + SWAP ROT 0 DO CELL- SWAP CELL- SWAP OVER @ OVER ! LOOP THEN ; +: MOVE DUP 0= IF DROP 2DROP EXIT THEN -ROT 2DUP U> IF ROT 0 DO OVER C@ OVER C! 1+ SWAP 1+ SWAP LOOP ELSE 2 PICK TUCK + -ROT + SWAP ROT 0 DO 1- SWAP 1- SWAP OVER C@ OVER C! LOOP THEN 2DROP ; : . DUP >R ABS 0 <# BL HOLD #S R> SIGN #> TYPE ; : U. 0 <# BL HOLD #S #> TYPE ; : .R >R DUP >R ABS 0 <# BL HOLD #S R> SIGN #> R> OVER - SPACES TYPE ; @@ -225,14 +236,18 @@ FORTH \ : +LOOP ['] (+loop) , BEGIN DUP INVERT IF HERE CELL+ ROT ! THEN 0= WHILE REPEAT , ; IMMEDIATE : +LOOP ['] (+loop) , , HERE SWAP ! ; IMMEDIATE : ACCEPT OVER SWAP OVER + 1- SWAP BEGIN RAWKEY DUP 9 = IF DROP 32 THEN DUP 31 > IF DUP 0x7f = IF EMIT 1- ELSE DUP EMIT OVER C! 1+ OVER MIN THEN ELSE 10 = IF NIP SWAP - EXIT ELSE WAIT THEN THEN AGAIN ; +\ : ACCEPT OVER SWAP OVER + 1- SWAP BEGIN RAWKEY DUP 9 = IF DROP 32 THEN DUP 31 > IF DUP 0x7f = IF DROP 1- ELSE OVER C! 1+ OVER MIN THEN ELSE 10 = IF NIP SWAP - EXIT ELSE WAIT THEN THEN AGAIN ; : EXPECT ACCEPT SPAN ! ; : QUERY 0 >IN ! 0 SOURCE-ID ! TIB DUP 80 ACCEPT SPACE (source) 2! ; : REFILL SOURCE-ID @ IF FALSE ELSE 0 >IN ! TIB DUP 80 ACCEPT SPACE (source) 2! TRUE THEN ; +\ : REFILL SOURCE-ID @ IF FALSE ELSE 0 >IN ! TIB DUP 80 ACCEPT (source) 2! TRUE THEN ; : INTERPRET-WORD 2DUP FIND-WORD ?DUP IF -ROT 2DROP EXECUTE ELSE 2DUP NUMBER 0= IF DROP -ROT 2DROP ELSE 2DROP TYPE SPACE 63 EMIT ABORT THEN THEN ; : EVALUATE SOURCE 2>R >IN @ >R SOURCE-ID @ >R -1 SOURCE-ID ! 0 >IN ! (source) 2! BEGIN PARSE-WORD ?DUP WHILE STATE @ IF COMPILE-WORD ELSE INTERPRET-WORD THEN REPEAT DROP R> SOURCE-ID ! R> >IN ! 2R> (source) 2! ; : QUIT EMPTYR CR BEGIN REFILL WHILE BEGIN PARSE-WORD ?DUP WHILE STATE @ IF COMPILE-WORD ELSE INTERPRET-WORD THEN REPEAT DROP SPACE 79 EMIT 75 EMIT DEBUG CR REPEAT ; +\ : QUIT EMPTYR CR BEGIN REFILL WHILE BEGIN PARSE-WORD ?DUP WHILE STATE @ IF COMPILE-WORD ELSE INTERPRET-WORD THEN REPEAT DROP REPEAT ; : (abort") ROT IF TYPE ABORT THEN 2DROP ; : ABORT" POSTPONE S" ['] (abort") , ; IMMEDIATE : DABS DUP 0< IF OVER NEGATE ROT IF SWAP INVERT ELSE SWAP NEGATE THEN THEN ; : SM/REM OVER >R 2DUP XOR >R ABS >R DABS R> UM/MOD R> 0< IF NEGATE THEN SWAP R> 0< IF NEGATE THEN SWAP ; +: KEY BEGIN RAWKEY DUP 31 > OVER 127 < AND IF EXIT THEN DROP AGAIN ; : COLD 82 EMIT 101 EMIT 97 EMIT 100 EMIT 121 EMIT QUIT ; diff --git a/forth3.py b/forth3.py index 208ac34..4ef9bef 100644 --- a/forth3.py +++ b/forth3.py @@ -127,6 +127,14 @@ ITABLE = { 0x52: "print(self.X, self.Y, self.Z, self.I, self.SP)", } +def indent(s): + return '\n'.join([" "+i for i in s.split("\n")]) + +for i in ITABLE.keys(): + d={} + exec("def f(self):\n"+indent(ITABLE[i]),globals(),d) + ITABLE[i] = d["f"] + class ForthVM: def __init__(self): self.memory = [0]*0x10000 @@ -146,11 +154,11 @@ class ForthVM: self.memory[addr]=value&0xff def read(self,addr): - return self.memory[addr]+(self.memory[addr+1]<<8) + return self.memory[addr]+(self.memory[u16(addr+1)]<<8) def write(self,addr,value): self.memory[addr]=value&0xff - self.memory[addr+1]=(value>>8)&0xff + self.memory[u16(addr+1)]=(value>>8)&0xff def push(self,value): self.SP+=2 @@ -188,7 +196,8 @@ class ForthVM: self.printstack()#""" instr = self.memory[self.PC] self.PC += 1 - exec(ITABLE[instr]) + #exec(ITABLE[instr]) + ITABLE[instr](self) if self.paused: time.sleep(0.01) self.paused=False