From 8e4b4f2013b3f347e84398c70eabab60f6edd625 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 19 Sep 2020 21:44:48 -0700 Subject: 6807 - tile: render intermediate stack state --- apps/tile/rpn.mu | 122 +++++++++++++++++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 44 deletions(-) (limited to 'apps/tile/rpn.mu') diff --git a/apps/tile/rpn.mu b/apps/tile/rpn.mu index 696912fd..3ca8a38f 100644 --- a/apps/tile/rpn.mu +++ b/apps/tile/rpn.mu @@ -1,53 +1,87 @@ -fn simplify in: (addr stream byte), out: (addr int-stack) { - var word-storage: slice - var word/ecx: (addr slice) <- address word-storage +fn evaluate start: (addr word), end: (addr word), out: (addr int-stack) { + var curr/eax: (addr word) <- copy start + var curr-text-storage: (stream byte 0x10) + var curr-text/edi: (addr stream byte) <- address curr-text-storage clear-int-stack out - $simplify:word-loop: { - next-word in, word - var done?/eax: boolean <- slice-empty? word - compare done?, 0 - break-if-!= - # if word is an operator, perform it - { - var is-add?/eax: boolean <- slice-equal? word, "+" - compare is-add?, 0 - break-if-= - var _b/eax: int <- pop-int-stack out - var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out - a <- add b - push-int-stack out, a - loop $simplify:word-loop - } - { - var is-sub?/eax: boolean <- slice-equal? word, "-" - compare is-sub?, 0 - break-if-= - var _b/eax: int <- pop-int-stack out - var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out - a <- subtract b - push-int-stack out, a - loop $simplify:word-loop - } - { - var is-mul?/eax: boolean <- slice-equal? word, "*" - compare is-mul?, 0 - break-if-= - var _b/eax: int <- pop-int-stack out - var b/edx: int <- copy _b - var a/eax: int <- pop-int-stack out - a <- multiply b - push-int-stack out, a - loop $simplify:word-loop + $evaluate:loop: { + # precondition (should never hit) + compare curr, 0 + break-if-= + # update curr-text + emit-word curr, curr-text + $evaluate:process-word: { + # if curr-text is an operator, perform it + { + var is-add?/eax: boolean <- stream-data-equal? curr-text, "+" + compare is-add?, 0 + break-if-= + var _b/eax: int <- pop-int-stack out + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack out + a <- add b + push-int-stack out, a + break $evaluate:process-word + } + { + var is-sub?/eax: boolean <- stream-data-equal? curr-text, "-" + compare is-sub?, 0 + break-if-= + var _b/eax: int <- pop-int-stack out + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack out + a <- subtract b + push-int-stack out, a + break $evaluate:process-word + } + { + var is-mul?/eax: boolean <- stream-data-equal? curr-text, "*" + compare is-mul?, 0 + break-if-= + var _b/eax: int <- pop-int-stack out + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack out + a <- multiply b + push-int-stack out, a + break $evaluate:process-word + } + # otherwise it's an int + { + var n/eax: int <- parse-decimal-int-from-stream curr-text + push-int-stack out, n + } } - # otherwise it's an int - var n/eax: int <- parse-decimal-int-from-slice word - push-int-stack out, n + # termination check + compare curr, end + break-if-= + # update + var next-word-ah/edx: (addr handle word) <- get curr, next + curr <- lookup *next-word-ah + # loop } } +fn test-evaluate { + # input = [1, 2, +] + var w: (handle word) + var wah/eax: (addr handle word) <- address w + allocate wah + var wa/eax: (addr word) <- lookup w + initialize-word-with wa, "1" + append-word-with w, "2" + var next/ecx: (addr handle word) <- get wa, next + append-word-with *next, "+" + # initialize output + var stack-storage: int-stack + var stack/edx: (addr int-stack) <- address stack-storage + initialize-int-stack stack, 0x10 + # + evaluate wa, 0, stack + # check output + var x/eax: int <- pop-int-stack stack + check-ints-equal x, 3, "F - test-evaluate" +} + # Copy of 'simplify' that just tracks the maximum stack depth needed # Doesn't actually need to simulate the stack, since every word has a predictable effect. fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/edi: int { -- cgit 1.4.1-2-gfad0