mirror of
https://github.com/remko/waforth
synced 2024-12-27 09:59:29 +01:00
interpret: Update documentation
This commit is contained in:
parent
caf1f31451
commit
7ffc90eca9
1 changed files with 51 additions and 30 deletions
|
@ -1123,17 +1123,7 @@
|
|||
|
||||
;; [6.1.1370](https://forth-standard.org/standard/core/EXECUTE)
|
||||
(func $EXECUTE (param $tos i32) (result i32)
|
||||
(local $xt i32)
|
||||
(local $body i32)
|
||||
(local.get $tos)
|
||||
(local.set $body (call $body (local.tee $xt (call $pop))))
|
||||
(if (param i32) (result i32) (i32.and (i32.load8_u (i32.add (local.get $xt) (i32.const 4)))
|
||||
(i32.const 0x40 (; = F_DATA ;)))
|
||||
(then
|
||||
(call_indirect (type $dataWord) (i32.add (local.get $body) (i32.const 4))
|
||||
(i32.load (local.get $body))))
|
||||
(else
|
||||
(call_indirect (type $word) (i32.load (local.get $body))))))
|
||||
(call $execute (call $pop (local.get $tos))))
|
||||
(data (i32.const 0x20510) "\fc\04\02\00" "\07" "EXECUTE" "\60\00\00\00")
|
||||
(elem (i32.const 0x60) $EXECUTE)
|
||||
|
||||
|
@ -1913,9 +1903,10 @@
|
|||
;; Interpreter
|
||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||
|
||||
;; Interprets the string in the input, until the end of string is reached.
|
||||
;; Returns 0 if processed, 1 if still compiling, or traps if a word
|
||||
;; was not found.
|
||||
;; Interpret the string in the input buffer word by word, until
|
||||
;; the end of the input buffer is reached.
|
||||
;;
|
||||
;; Traps if a word was not found in the dictionary (and isn't a number).
|
||||
(func $interpret (param $tos i32) (result i32)
|
||||
(local $FINDResult i32)
|
||||
(local $FINDToken i32)
|
||||
|
@ -1927,14 +1918,21 @@
|
|||
(global.set $tors (i32.const 0x2000 (; = RETURN_STACK_BASE ;)))
|
||||
(block $endLoop
|
||||
(loop $loop
|
||||
;; Parse the next name in the input stream
|
||||
(local.set $wordAddr (local.set $wordLen (call $parseName)))
|
||||
|
||||
;; No more input. Break the loop.
|
||||
(br_if $endLoop (i32.eqz (local.get $wordLen)))
|
||||
|
||||
;; Search the name in the dictionary
|
||||
(local.set $FINDToken (local.set $FINDResult
|
||||
(call $find (local.get $wordAddr) (local.get $wordLen))))
|
||||
(if (i32.eqz (local.get $FINDResult))
|
||||
(then ;; Not in the dictionary. Is it a number?
|
||||
(then
|
||||
;; Name is not in the dictionary. Is it a number?
|
||||
(if (param i32) (i32.eqz (call $readNumber (local.get $wordAddr) (local.get $wordLen)))
|
||||
(then ;; It's a number. Are we compiling?
|
||||
;; It's a number. Are we compiling?
|
||||
(then
|
||||
(local.set $number)
|
||||
(if (i32.load (i32.const 0x2081c (; = body(STATE) ;)))
|
||||
(then
|
||||
|
@ -1944,26 +1942,49 @@
|
|||
(else
|
||||
;; We're not compiling. Put the number on the stack.
|
||||
(local.set $tos (call $push (local.get $tos) (local.get $number))))))
|
||||
(else ;; It's not a number.
|
||||
;; It's not a number either. Fail.
|
||||
(else
|
||||
(drop)
|
||||
(call $failUndefinedWord (local.get $wordAddr) (local.get $wordLen)))))
|
||||
(else ;; Found the word.
|
||||
;; Are we compiling or is it immediate?
|
||||
(if
|
||||
(i32.or
|
||||
(i32.eqz (i32.load (i32.const 0x2081c (; = body(STATE) ;))))
|
||||
(i32.eq (local.get $FINDResult) (i32.const 1)))
|
||||
(else
|
||||
;; Name found in the dictionary.
|
||||
;; Are we compiling and is the word non-immediate?
|
||||
(if (i32.and
|
||||
(i32.load (i32.const 0x2081c (; = body(STATE) ;)))
|
||||
(i32.ne (local.get $FINDResult) (i32.const 1)))
|
||||
(then
|
||||
(local.get $tos)
|
||||
(call $push (local.get $FINDToken))
|
||||
(call $EXECUTE)
|
||||
(local.set $tos))
|
||||
;; We're compiling a non-immediate.
|
||||
;; Compile the execution of the word into the current compilation body.
|
||||
(local.set $tos (call $compileCall (local.get $tos) (local.get $FINDToken))))
|
||||
(else
|
||||
;; We're compiling a non-immediate
|
||||
(local.set $tos (call $compileCall (local.get $tos) (local.get $FINDToken)))))))
|
||||
;; We're not compiling, or this is an immediate word
|
||||
;; Execute the word.
|
||||
(local.set $tos (call $execute (local.get $tos) (local.get $FINDToken)))))))
|
||||
(br $loop)))
|
||||
(local.get $tos))
|
||||
|
||||
;; Execute the given execution token
|
||||
(func $execute (param $tos i32) (param $xt i32) (result i32)
|
||||
(local $body i32)
|
||||
|
||||
;; Get the table index of the dictionary entry
|
||||
(local.set $body (call $body (local.get $xt)))
|
||||
|
||||
;; Perform an indirect call to the table index
|
||||
(if (result i32) (i32.and
|
||||
(i32.load8_u (i32.add (local.get $xt) (i32.const 4)))
|
||||
(i32.const 0x40 (; = F_DATA ;)))
|
||||
(then
|
||||
;; A data word gets the pointer to the dictionary entry's data field
|
||||
;; as extra parameter
|
||||
(call_indirect
|
||||
(type $dataWord)
|
||||
(local.get $tos)
|
||||
(i32.add (local.get $body) (i32.const 4))
|
||||
(i32.load (local.get $body))))
|
||||
(else
|
||||
(call_indirect (type $word) (local.get $tos) (i32.load (local.get $body))))))
|
||||
|
||||
;; Returns (number, unparsed length)
|
||||
(func $readNumber (param $addr i32) (param $len i32) (result i32 i32)
|
||||
(local $restcount i32)
|
||||
|
|
Loading…
Reference in a new issue