interpret: Update documentation

This commit is contained in:
Remko Tronçon 2022-05-31 21:04:19 +02:00
parent caf1f31451
commit 7ffc90eca9

View file

@ -1123,20 +1123,10 @@
;; [6.1.1370](https://forth-standard.org/standard/core/EXECUTE) ;; [6.1.1370](https://forth-standard.org/standard/core/EXECUTE)
(func $EXECUTE (param $tos i32) (result i32) (func $EXECUTE (param $tos i32) (result i32)
(local $xt i32) (call $execute (call $pop (local.get $tos))))
(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))))))
(data (i32.const 0x20510) "\fc\04\02\00" "\07" "EXECUTE" "\60\00\00\00") (data (i32.const 0x20510) "\fc\04\02\00" "\07" "EXECUTE" "\60\00\00\00")
(elem (i32.const 0x60) $EXECUTE) (elem (i32.const 0x60) $EXECUTE)
;; [6.1.1380](https://forth-standard.org/standard/core/EXIT) ;; [6.1.1380](https://forth-standard.org/standard/core/EXIT)
(func $EXIT (param $tos i32) (result i32) (func $EXIT (param $tos i32) (result i32)
(local.get $tos) (local.get $tos)
@ -1913,9 +1903,10 @@
;; Interpreter ;; Interpreter
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;; Interprets the string in the input, until the end of string is reached. ;; Interpret the string in the input buffer word by word, until
;; Returns 0 if processed, 1 if still compiling, or traps if a word ;; the end of the input buffer is reached.
;; was not found. ;;
;; Traps if a word was not found in the dictionary (and isn't a number).
(func $interpret (param $tos i32) (result i32) (func $interpret (param $tos i32) (result i32)
(local $FINDResult i32) (local $FINDResult i32)
(local $FINDToken i32) (local $FINDToken i32)
@ -1927,14 +1918,21 @@
(global.set $tors (i32.const 0x2000 (; = RETURN_STACK_BASE ;))) (global.set $tors (i32.const 0x2000 (; = RETURN_STACK_BASE ;)))
(block $endLoop (block $endLoop
(loop $loop (loop $loop
;; Parse the next name in the input stream
(local.set $wordAddr (local.set $wordLen (call $parseName))) (local.set $wordAddr (local.set $wordLen (call $parseName)))
;; No more input. Break the loop.
(br_if $endLoop (i32.eqz (local.get $wordLen))) (br_if $endLoop (i32.eqz (local.get $wordLen)))
;; Search the name in the dictionary
(local.set $FINDToken (local.set $FINDResult (local.set $FINDToken (local.set $FINDResult
(call $find (local.get $wordAddr) (local.get $wordLen)))) (call $find (local.get $wordAddr) (local.get $wordLen))))
(if (i32.eqz (local.get $FINDResult)) (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))) (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) (local.set $number)
(if (i32.load (i32.const 0x2081c (; = body(STATE) ;))) (if (i32.load (i32.const 0x2081c (; = body(STATE) ;)))
(then (then
@ -1944,26 +1942,49 @@
(else (else
;; We're not compiling. Put the number on the stack. ;; We're not compiling. Put the number on the stack.
(local.set $tos (call $push (local.get $tos) (local.get $number)))))) (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) (drop)
(call $failUndefinedWord (local.get $wordAddr) (local.get $wordLen))))) (call $failUndefinedWord (local.get $wordAddr) (local.get $wordLen)))))
(else ;; Found the word. (else
;; Are we compiling or is it immediate? ;; Name found in the dictionary.
(if ;; Are we compiling and is the word non-immediate?
(i32.or (if (i32.and
(i32.eqz (i32.load (i32.const 0x2081c (; = body(STATE) ;)))) (i32.load (i32.const 0x2081c (; = body(STATE) ;)))
(i32.eq (local.get $FINDResult) (i32.const 1))) (i32.ne (local.get $FINDResult) (i32.const 1)))
(then (then
(local.get $tos) ;; We're compiling a non-immediate.
(call $push (local.get $FINDToken)) ;; Compile the execution of the word into the current compilation body.
(call $EXECUTE) (local.set $tos (call $compileCall (local.get $tos) (local.get $FINDToken))))
(local.set $tos))
(else (else
;; We're compiling a non-immediate ;; We're not compiling, or this is an immediate word
(local.set $tos (call $compileCall (local.get $tos) (local.get $FINDToken))))))) ;; Execute the word.
(local.set $tos (call $execute (local.get $tos) (local.get $FINDToken)))))))
(br $loop))) (br $loop)))
(local.get $tos)) (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) ;; Returns (number, unparsed length)
(func $readNumber (param $addr i32) (param $len i32) (result i32 i32) (func $readNumber (param $addr i32) (param $len i32) (result i32 i32)
(local $restcount i32) (local $restcount i32)