Huge speed improvement, several fixes.
parent
f4f6589050
commit
4086e1fc80
22
f.py
22
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
|
||||
|
|
|
@ -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 ;
|
15
forth3.py
15
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
|
||||
|
|
Loading…
Reference in New Issue