commit - 305019da86442226c04b49bf66604da174f04eee
commit + c7d7ae29540cc0db3c92e246d5f34fe9f0fe9eff
blob - 780481aeb4b53f4b4757ad58ed97b0df295f7cf4
blob + 77b5b47b823c52ab40b9107d6aa2ff60165c070f
--- rvforth.S
+++ rvforth.S
.quad (\label - .)
.endm
+.macro GOTONZ, label
+ .quad EQZ
+ .quad ZBRANCH
+ .quad (\label - .)
+.endm
+
.section .text
.global DOCOL
.type DOCOL, @function
_KEY:
j getchar
.size _KEY, . - _KEY
-
-// a0 - str
-// a1 - len
-_NUMBER:
- mv t0, zero
- beq a1, zero, 2f
- li a2, 1
-
- lbu t1, 0(a0)
- li t2, '-'
- bne t1, t2, 1f
-
- li a2, -1
- addi a0, a0, 1
- addi a1, a1, -1
-1:
- lbu t1, 0(a0)
-
- li t2, '0'
- bltu t1, t2, 2f
- li t2, '9'
- bgt t1, t2, 2f
-
- li t2, 10
- mul t0, t0, t2
- add t0, t0, t1
- addi t0, t0, -'0'
-
- addi a0, a0, 1
- addi a1, a1, -1
-
-3:
- bne a1, zero, 1b
- li a0, -1
- //mv a1, t0
- mul a1, t0, a2
- jr ra
-
-2: // not a digit
- mv a0, zero
- jr ra
-
-.size _NUMBER, . - _NUMBER
-
_COMMA:
la t0, var_HERE
ld t1, 0(t0)
PUSH t0
NEXT
-defcode "KEY", 3, KEY, EQZ
+// ( x y -- b )
+defword "=", 1, EQ, EQZ
+ .quad SUB
+ .quad EQZ
+ .quad EXIT
+
+// ( x y -- b )
+defcode "<", 1, LT, EQ
+ POP t0
+ POP t1
+ sltu t0, t0, t1
+ PUSH t0
+ NEXT
+
+defcode "KEY", 3, KEY, LT
jal _KEY
PUSH a0
NEXT
.quad EXIT
-defcode "NUMBER", 6, NUMBER, CREATE
- POP a0
- POP a1
- jal _NUMBER
- PUSH a1
- PUSH a0
- NEXT
+// ( str len -- err val )
+defword "NUMBER", 6, NUMBER, CREATE
+ .quad OVER // ( len str len )
+ GOTOZ 1f // ( str len )
+ .quad DUP // ( str str len )
+ .quad FETCHBYTE // ( ch str len )
+ .quad LIT, '-' // ( '-' ch str len )
+ .quad EQ // ( eql str len )
+ GOTOZ 2f // ( str len )
+
+ .quad LIT, -1 // ( -1 str len )
+ .quad TOR // ( str len -- -1 )
+ .quad INC // ( str+1 len -- -1 )
+ .quad SWAP // ( len str+1 -- -1 )
+ .quad DEC // ( len-1 str+1 -- -1 )
+ .quad SWAP // ( str+1 len -- -1 )
+ .quad OVER // ( len str+1 len -- -1 )
+ .quad EQZ // ( !len str+1 len -- -1 )
+ GOTOZ 3f // ( str+1 len -- -1 )
+
+ .quad RDROP // ( str len )
+ GOTO 1f // noreturn
+
+2:
+ .quad LIT, 1 // ( 1 str len )
+ .quad TOR // ( str len -- 1 )
+
+3:
+ .quad LIT, 0 // ( 0 str len -- neg )
+ .quad TOR // ( str len -- 0 neg )
+
+4: // ( str len -- 0 neg )
+ .quad DUP // ( str str len -- val neg )
+ .quad FETCHBYTE // ( ch str len -- val neg )
+ .quad LIT, '0' // ( '0' ch str len -- val neg )
+ .quad OVER // ( ch '0' ch str len -- val neg )
+ .quad LT // ( lt ch str len -- val neg )
+ GOTONZ 5f // ( ch str len -- val neg )
+
+ // ( ch str len -- val neg )
+ .quad DUP // ( ch ch str len -- val neg )
+ .quad LIT, '9' // ( '9' ch ch str len -- val neg )
+ .quad LT // ( lt ch str len -- val neg )
+ GOTONZ 5f // ( ch str len -- val neg )
+
+ .quad LIT, '0' // ( '0' ch str len -- val neg )
+ .quad SUB // ( dig str len -- val neg )
+ .quad FROMR // ( val dig str len -- neg )
+ .quad LIT, 10 // ( 10 val dig str len -- neg )
+ .quad MUL // ( val dig str len -- neg )
+ .quad ADD // ( val str len -- neg )
+ .quad TOR // ( str len -- val neg )
+
+ .quad INC // ( str+1 len -- val neg )
+ .quad SWAP // ( len str+1 -- val neg )
+ .quad DEC // ( len-1 str+1 -- val neg )
+ .quad SWAP // ( str+1 len-1 -- val neg )
+ .quad OVER // ( len-1 str+1 len-1 -- val neg )
+ GOTONZ 4b // ( str+1 len-1 -- val neg )
+
+ .quad TDROP // ( -- val neg )
+ .quad FROMR // ( val -- neg )
+ .quad FROMR // ( neg val )
+ .quad MUL // ( val )
+ .quad LIT, -1 // ( -1 val )
+ .quad EXIT
+
+5: // invalid char ( ch str len -- val neg )
+ .quad DROP // ( str len -- val neg )
+ .quad RDROP // ( str len -- neg )
+ .quad RDROP // ( str len )
+ GOTO 1f // noreturn
+
+1: // empty string ( str len )
+ .quad TDROP // ( )
+ .quad LIT, 0 // ( 0 )
+ .quad DUP // ( 0 0 )
+ .quad EXIT // noreturn
+
+
defcode "ERROR", 5, ERROR, NUMBER
la a0, .Lerr
jal puts