fn evaluate functions: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr value-stack) { var line/eax: (addr line) <- copy scratch var word-ah/eax: (addr handle word) <- get line, data var curr/eax: (addr word) <- lookup *word-ah var curr-stream-storage: (stream byte 0x10) var curr-stream/edi: (addr stream byte) <- address curr-stream-storage clear-value-stack out $evaluate:loop: { # precondition (should never hit) compare curr, 0 break-if-= # update curr-stream emit-word curr, curr-stream #? print-string-to-real-screen "eval: " #? print-stream-to-real-screen curr-stream #? print-string-to-real-screen "\n" $evaluate:process-word: { ### if curr-stream is an operator, perform it ## numbers { var add?/eax: boolean <- stream-data-equal? curr-stream, "+" compare add?, 0 break-if-= var _b/xmm0: float <- pop-number-from-value-stack out var b/xmm1: float <- copy _b var a/xmm0: float <- pop-number-from-value-stack out a <- add b push-number-to-value-stack out, a break $evaluate:process-word } { var sub?/eax: boolean <- stream-data-equal? curr-stream, "-" compare sub?, 0 break-if-= var _b/xmm0: float <- pop-number-from-value-stack out var b/xmm1: float <- copy _b var a/xmm0: float <- pop-number-from-value-stack out a <- subtract b push-number-to-value-stack out, a break $evaluate:process-word } { var mul?/eax: boolean <- stream-data-equal? curr-stream, "*" compare mul?, 0 break-if-= var _b/xmm0: float <- pop-number-from-value-stack out var b/xmm1: float <- copy _b var a/xmm0: float <- pop-number-from-value-stack out a <- multiply b push-number-to-value-stack out, a break $evaluate:process-word } { var div?/eax: boolean <- stream-data-equal? curr-stream, "/" compare div?, 0 break-if-= var _b/xmm0: float <- pop-number-from-value-stack out var b/xmm1: float <- copy _b var a/xmm0: float <- pop-number-from-value-stack out a <- divide b push-number-to-value-stack out, a break $evaluate:process-word } { var sqrt?/eax: boolean <- stream-data-equal? curr-stream, "sqrt" compare sqrt?, 0 break-if-= var a/xmm0: float <- pop-number-from-value-stack out a <- square-root a push-number-to-value-stack out, a break $evaluate:process-word } ## strings/arrays { var len?/eax: boolean <- stream-data-equal? curr-stream, "len" compare len?, 0 break-if-= #? print-string 0, "is len\n" # pop target-val from out var out2/esi: (addr value-stack) <- copy out var top-addr/ecx: (addr int) <- get out2, top compare *top-addr, 0 break-if-<= #? print-string 0, "stack has stuff\n" var data-ah/eax: (addr handle array value) <- get out2, data var data/eax: (addr array value) <- lookup *data-ah var top/edx: int <- copy *top-addr top <- decrement var dest-offset/edx: (offset value) <- compute-offset data, top var target-val/edx: (addr value) <- index data, dest-offset # check target-val is a string or array var target-type-addr/eax: (addr int) <- get target-val, type compare *target-type-addr, 1/string { break-if-!= # compute length var src-ah/eax: (addr handle array byte) <- get target-val, text-data var src/eax: (addr array byte) <- lookup *src-ah var result/ebx: int <- length src var result-f/xmm0: float <- convert result # save result into target-val var type-addr/eax: (addr int) <- get target-val, type copy-to *type-addr, 0/int var target-string-ah/eax: (addr handle array byte) <- get target-val, text-data clear-object target-string-ah var target/eax: (addr float) <- get target-val, number-data copy-to *target, result-f break $evaluate:process-word } compare *target-type-addr, 2/array { break-if-!= # compute length var src-ah/eax: (addr handle array value) <- get target-val, array-data var src/eax: (addr array value) <- lookup *src-ah var result/ebx: int <- length src var result-f/xmm0: float <- convert result # save result into target-val var type-addr/eax: (addr int) <- get target-val, type copy-to *type-addr, 0/int var target-array-ah/eax: (addr handle array value) <- get target-val, array-data clear-object target-array-ah var target/eax: (addr float) <- get target-val, number-data copy-to *target, result-f break $evaluate:process-word } } ## files { var open?/eax: boolean <- stream-data-equal? curr-stream, "open" compare open?, 0 br