Huge speed improvement, several fixes.

master
Novatux 2013-07-04 19:36:53 +02:00
parent f4f6589050
commit 4086e1fc80
3 changed files with 53 additions and 13 deletions

22
f.py
View File

@ -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

View File

@ -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 ;

View File

@ -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