From ae470b42f102d5da4f7d4255a47e3cf582079f33 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Tue, 15 Sep 2020 22:21:15 -0700 Subject: 6781 - new app: RPN (postfix) calculator This was surprisingly hard; bugs discovered all over the place. --- 118parse-hex-int.subx | 6 +- 127next-word.subx | 7 +- 304screen.subx | 19 ++++ 305keyboard.subx | 16 ++++ 308allocate-array.subx | 2 +- 311parse-decimal-int.subx | 233 ++++++++++++++++++++++++++++++++++++++++++++++ 400.mu | 12 ++- apps/assort | Bin 44513 -> 44508 bytes apps/braces | Bin 46376 -> 46371 bytes apps/calls | Bin 51023 -> 51018 bytes apps/crenshaw2-1 | Bin 43854 -> 43849 bytes apps/crenshaw2-1b | Bin 44401 -> 44396 bytes apps/dquotes | Bin 48135 -> 48130 bytes apps/factorial | Bin 42957 -> 42952 bytes apps/hex | Bin 46693 -> 46688 bytes apps/mu | Bin 389400 -> 390307 bytes apps/mu.subx | 7 ++ apps/pack | Bin 57092 -> 57087 bytes apps/rpn.mu | 149 +++++++++++++++++++++++++++++ apps/sigils | Bin 58745 -> 58740 bytes apps/survey | Bin 54445 -> 54440 bytes apps/tests | Bin 43285 -> 43299 bytes apps/tests.subx | 12 +++ 23 files changed, 451 insertions(+), 12 deletions(-) create mode 100644 311parse-decimal-int.subx create mode 100644 apps/rpn.mu diff --git a/118parse-hex-int.subx b/118parse-hex-int.subx index ebbd4e4e..5d92b13a 100644 --- a/118parse-hex-int.subx +++ b/118parse-hex-int.subx @@ -393,7 +393,7 @@ parse-hex-int-from-slice: # in: (addr slice) -> result/eax: int 52/push-edx # ecx = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # edx = in->end + # var max/edx: (addr byte) = in->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx # var curr/ecx: (addr byte) = in->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx @@ -582,7 +582,7 @@ test-parse-hex-int-from-slice-0x-prefix: e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # check-ints-equal(eax, 0x34a, msg) + # check-ints-equal(eax, 0x34, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-0x-prefix"/imm32 68/push 0x34/imm32 @@ -616,7 +616,7 @@ test-parse-hex-int-from-slice-zero: e8/call parse-hex-int-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # check-ints-equal(eax, 0x34a, msg) + # check-ints-equal(eax, 0, msg) # . . push args 68/push "F - test-parse-hex-int-from-slice-zero"/imm32 68/push 0/imm32 diff --git a/127next-word.subx b/127next-word.subx index c3e9762d..6a186656 100644 --- a/127next-word.subx +++ b/127next-word.subx @@ -20,14 +20,13 @@ next-word: # line: (addr stream byte), out: (addr slice) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi - # skip-chars-matching(line, ' ') + # skip-chars-matching-whitespace(line) # . . push args - 68/push 0x20/imm32/space ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) # . . call - e8/call skip-chars-matching/disp32 + e8/call skip-chars-matching-whitespace/disp32 # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp $next-word:check0: # if (line->read >= line->write) clear out and return # . eax = line->read diff --git a/304screen.subx b/304screen.subx index 1537a9b1..8ec33fd5 100644 --- a/304screen.subx +++ b/304screen.subx @@ -131,6 +131,19 @@ $print-string-to-real-screen:end: 5d/pop-to-ebp c3/return +print-slice-to-real-screen: # s: (addr slice) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # + (write-slice-buffered Stdout *(ebp+8)) + (flush Stdout) +$print-slice-to-real-screen:end: + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + print-stream-to-real-screen: # s: (addr stream byte) # . prologue 55/push-ebp @@ -240,6 +253,8 @@ write-int32-decimal-buffered: # f: (addr buffered-file), n: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx # var ecx: (stream byte 16) 81 5/subop/subtract %esp 0x10/imm32 68/push 0x10/imm32/size @@ -249,6 +264,10 @@ write-int32-decimal-buffered: # f: (addr buffered-file), n: int (write-int32-decimal %ecx *(ebp+0xc)) (write-stream-data *(ebp+8) %ecx) $write-int32-decimal-buffered:end: + # . reclaim locals + 81 0/subop/add %esp 0x1c/imm32 + # . restore registers + 59/pop-to-ecx # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp diff --git a/305keyboard.subx b/305keyboard.subx index e1a9cc0e..7c9ce065 100644 --- a/305keyboard.subx +++ b/305keyboard.subx @@ -144,6 +144,22 @@ $read-key-from-real-keyboard:end: 5d/pop-to-ebp c3/return +read-line-from-real-keyboard: # in: (addr stream byte) + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + # + (read 0 *(ebp+8)) # => eax +$read-line-from-real-keyboard:end: + # . restore registers + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + == data # iflags: octal hex diff --git a/308allocate-array.subx b/308allocate-array.subx index 760b8090..c243ee33 100644 --- a/308allocate-array.subx +++ b/308allocate-array.subx @@ -11,7 +11,7 @@ allocate-array2: # ad: (addr allocation-descriptor), array-len: int, elem-size: 52/push-edx # 8b/-> *(ebp+0xc) 0/r32/eax - f7 4/subop/multiply-into-eax-edx *(ebp+0x10) + f7 4/subop/multiply-into-edx-eax *(ebp+0x10) # TODO: check edx for overflow (allocate-array *(ebp+8) %eax *(ebp+0x14)) $allocate-array2:end: diff --git a/311parse-decimal-int.subx b/311parse-decimal-int.subx new file mode 100644 index 00000000..538f3e87 --- /dev/null +++ b/311parse-decimal-int.subx @@ -0,0 +1,233 @@ +# Helpers for parsing decimal ints. + +parse-decimal-int-from-slice: # in: (addr slice) -> out/eax: int # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + # ecx = in + 8b/-> *(ebp+8) 1/r32/ecx + # + (parse-decimal-int-helper *ecx *(ecx+4)) # => eax +$parse-decimal-int-from-slice:end: + # . restore registers + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +parse-decimal-int-helper: # start: (addr byte), end: (addr byte) -> result/eax: int + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 51/push-ecx + 52/push-edx + 53/push-ebx + 56/push-esi + 57/push-edi + # var curr/esi: (addr byte) = start + 8b/-> *(ebp+8) 6/r32/esi + # edi = end + 8b/-> *(ebp+0xc) 7/r32/edi + # var negate?/edx: boolean = false + ba/copy-to-edx 0/imm32/false + # if (*curr == '-') ++curr, negate = true + { +$parse-decimal-int-helper:negative: + b8/copy-to-eax 0/imm32 + 8a/copy-byte *esi 0/r32/AL + 3d/compare-eax-and 0x2d/imm32/- + 75/jump-if-!= break/disp8 + # . ++curr + 46/increment-esi + # . negate = true + ba/copy-to-edx 1/imm32/true + } + # spill negate? + 52/push-edx + # var result/eax: int = 0 + b8/copy-to-eax 0/imm32 + # var digit/ecx: int = 0 + b9/copy-to-ecx 0/imm32 + # const TEN/ebx: int = 10 + bb/copy-to-ebx 0xa/imm32 + { +$parse-decimal-int-helper:loop: + # if (curr >= in->end) break + 39/compare %esi 7/r32/edi + 73/jump-if-addr>= break/disp8 + # digit = from-decimal-char(*curr) + 8a/copy-byte *esi 1/r32/CL + 81 5/subop/subtract %ecx 0x30/imm32/zero + # TODO: error checking + # result = result * 10 + digit + ba/copy-to-edx 0/imm32 + f7 4/subop/multiply-into-edx-eax %ebx + # TODO: check edx for overflow + 01/add %eax 1/r32/ecx + # ++curr + 46/increment-esi + # + eb/jump loop/disp8 + } +$parse-decimal-int-helper:negate: + # if (negate?) result = -result + 5a/pop-to-edx + { + 81 7/subop/compare %edx 0/imm32/false + 74/jump-if-= break/disp8 + f7 3/subop/negate %eax + } +$parse-decimal-int-helper:end: + # . restore registers + 5f/pop-to-edi + 5e/pop-to-esi + 5b/pop-to-ebx + 5a/pop-to-edx + 59/pop-to-ecx + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-parse-decimal-int-from-slice-single-digit: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # (eax..ecx) = "3" + b8/copy-to-eax "3"/imm32 + 8b/-> *eax 1/r32/ecx + 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 05/add-to-eax 4/imm32 + # var slice/ecx: slice = {eax, ecx} + 51/push-ecx + 50/push-eax + 89/<- %ecx 4/r32/esp + # + (parse-decimal-int-from-slice %ecx) # => eax + (check-ints-equal %eax 3 "F - test-parse-decimal-int-from-slice-single-digit") +$test-parse-decimal-int-helper-single-digit:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-parse-decimal-int-from-slice-multi-digit: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # (eax..ecx) = "34" + b8/copy-to-eax "34"/imm32 + 8b/-> *eax 1/r32/ecx + 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 05/add-to-eax 4/imm32 + # var slice/ecx: slice = {eax, ecx} + 51/push-ecx + 50/push-eax + 89/<- %ecx 4/r32/esp + # + (parse-decimal-int-from-slice %ecx) # => eax + (check-ints-equal %eax 0x22 "F - test-parse-decimal-int-from-slice-multi-digit") # 34 in hex +$test-parse-decimal-int-helper-multi-digit:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-parse-decimal-int-from-slice-zero: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # (eax..ecx) = "00" + b8/copy-to-eax "00"/imm32 + 8b/-> *eax 1/r32/ecx + 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 05/add-to-eax 4/imm32 + # var slice/ecx: slice = {eax, ecx} + 51/push-ecx + 50/push-eax + 89/<- %ecx 4/r32/esp + # + (parse-decimal-int-from-slice %ecx) # => eax + (check-ints-equal %eax 0 "F - test-parse-decimal-int-from-slice-zero") +$test-parse-decimal-int-helper-zero:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-parse-decimal-int-from-slice-negative: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # (eax..ecx) = "-3" + b8/copy-to-eax "-3"/imm32 + 8b/-> *eax 1/r32/ecx + 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 05/add-to-eax 4/imm32 + # var slice/ecx: slice = {eax, ecx} + 51/push-ecx + 50/push-eax + 89/<- %ecx 4/r32/esp + # + (parse-decimal-int-from-slice %ecx) # => eax + (check-ints-equal %eax -3 "F - test-parse-decimal-int-from-slice-negative") +$test-parse-decimal-int-helper-negative:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return + +test-parse-decimal-int-from-slice-multi-digit-negative: + # . prologue + 55/push-ebp + 89/<- %ebp 4/r32/esp + # . save registers + 50/push-eax + 51/push-ecx + # (eax..ecx) = "-32" + b8/copy-to-eax "-32"/imm32 + 8b/-> *eax 1/r32/ecx + 8d/copy-address *(eax+ecx+4) 1/r32/ecx + 05/add-to-eax 4/imm32 + # var slice/ecx: slice = {eax, ecx} + 51/push-ecx + 50/push-eax + 89/<- %ecx 4/r32/esp + # + (parse-decimal-int-from-slice %ecx) # => eax + (check-ints-equal %eax -0x20 "F - test-parse-decimal-int-from-slice-multi-digit-negative") # -32 in hex +$test-parse-decimal-int-helper-multi-digit-negative:end: + # . restore registers + 59/pop-to-ecx + 58/pop-to-eax + # . epilogue + 89/<- %esp 5/r32/ebp + 5d/pop-to-ebp + c3/return diff --git a/400.mu b/400.mu index 57032f0b..7b32f3cb 100644 --- a/400.mu +++ b/400.mu @@ -69,6 +69,8 @@ sig parse-hex-int-from-slice in: (addr slice) -> result/eax: int #sig parse-hex-int-helper start: (addr byte), end: (addr byte) -> result/eax: int sig is-hex-digit? c: byte -> result/eax: boolean #sig from-hex-char in/eax: byte -> out/eax: nibble +sig parse-decimal-int-from-slice in: (addr slice) -> result/eax: int +#sig parse-decimal-int-helper start: (addr byte), end: (addr byte) -> result/eax: int sig error-byte ed: (addr exit-descriptor), out: (addr buffered-file), msg: (addr array byte), n: byte #sig allocate ad: (addr allocation-descriptor), n: int, out: (addr handle _) #sig allocate-raw ad: (addr allocation-descriptor), n: int, out: (addr handle _) @@ -127,10 +129,10 @@ sig compute-width-of-slice s: (addr slice) -> result/eax: int sig emit-hex-array out: (addr buffered-file), arr: (addr array byte) sig next-word-or-string line: (addr stream byte), out: (addr slice) sig write-int out: (addr stream byte), n: int -sig clear-stack s: (addr stack) -sig push s: (addr stack), n: int -sig pop s: (addr stack) -> n/eax: int -sig top s: (addr stack) -> n/eax: int +#sig clear-stack s: (addr stack) +#sig push s: (addr stack), n: int +#sig pop s: (addr stack) -> n/eax: int +#sig top s: (addr stack) -> n/eax: int sig array-equal? a: (addr array int), b: (addr array int) -> result/eax: boolean sig parse-array-of-ints ad: (addr allocation-descriptor), s: (addr string), out: (addr handle array int) sig check-array-equal a: (addr array int), expected: (addr string), msg: (addr string) @@ -143,6 +145,7 @@ sig real-screen-size -> nrows/eax: int, ncols/ecx: int sig clear-real-screen sig move-cursor-on-real-screen row: int, column: int sig print-string-to-real-screen s: (addr array byte) +sig print-slice-to-real-screen s: (addr slice) sig print-stream-to-real-screen s: (addr stream byte) sig print-grapheme-to-real-screen c: grapheme sig print-int32-hex-to-real-screen n: int @@ -159,6 +162,7 @@ sig show-cursor-on-real-screen sig enable-keyboard-immediate-mode sig enable-keyboard-type-mode sig read-key-from-real-keyboard -> result/eax: byte +sig read-line-from-real-keyboard in: (addr stream byte) sig open filename: (addr array byte), write?: boolean, out: (addr handle buffered-file) sig populate-buffered-file-containing contents: (addr array byte), out: (addr handle buffered-file) sig new-buffered-file out: (addr handle buffered-file) diff --git a/apps/assort b/apps/assort index 42c0c4d5..91acd903 100755 Binary files a/apps/assort and b/apps/assort differ diff --git a/apps/braces b/apps/braces index fefabcc8..04c119a4 100755 Binary files a/apps/braces and b/apps/braces differ diff --git a/apps/calls b/apps/calls index 443dc7f3..fcf9fa3e 100755 Binary files a/apps/calls and b/apps/calls differ diff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1 index f26dedce..b47821fc 100755 Binary files a/apps/crenshaw2-1 and b/apps/crenshaw2-1 differ diff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b index 139327ca..59603ae2 100755 Binary files a/apps/crenshaw2-1b and b/apps/crenshaw2-1b differ diff --git a/apps/dquotes b/apps/dquotes index 302c3490..fe2b9da5 100755 Binary files a/apps/dquotes and b/apps/dquotes differ diff --git a/apps/factorial b/apps/factorial index 7e8edb63..424b6a84 100755 Binary files a/apps/factorial and b/apps/factorial differ diff --git a/apps/hex b/apps/hex index 75edad2d..5087ab7d 100755 Binary files a/apps/hex and b/apps/hex differ diff --git a/apps/mu b/apps/mu index 3ebe2ab7..8acd93f9 100755 Binary files a/apps/mu and b/apps/mu differ diff --git a/apps/mu.subx b/apps/mu.subx index 1b68350f..b3cb99de 100644 --- a/apps/mu.subx +++ b/apps/mu.subx @@ -14518,6 +14518,13 @@ size-of-type-id: # t: type-id -> result/eax: int b8/copy-to-eax 8/imm32 eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int } + # if t is a slice, return 8 + 3d/compare-eax-and 0xc/imm32/slice + { + 75/jump-if-!= break/disp8 + b8/copy-to-eax 8/imm32 + eb/jump $size-of-type-id:end/disp8 # eax changes type from type-id to int + } # if t is a user-defined type, return its size # TODO: support non-atom type (find-typeinfo %eax %ecx) diff --git a/apps/pack b/apps/pack index a6211a7d..ebae4f3a 100755 Binary files a/apps/pack and b/apps/pack differ diff --git a/apps/rpn.mu b/apps/rpn.mu new file mode 100644 index 00000000..5e2fdbb6 --- /dev/null +++ b/apps/rpn.mu @@ -0,0 +1,149 @@ +# Integer arithmetic using postfix notation +# +# Limitations: +# No division yet. +# +# To build: +# $ ./translate_mu apps/rpn.mu +# +# Example session: +# $ ./a.elf +# press ctrl-c or ctrl-d to exit +# > 1 +# 1 +# > 1 1 + +# 2 +# > 1 2 3 + + +# 6 +# > 1 2 3 * + +# 7 +# > 1 2 + 3 * +# 9 +# > 1 3 4 * + +# 13 +# > ^D +# $ +# +# Error handling is non-existent. This is just a prototype. + +fn main -> exit-status/ebx: int { + var in-storage: (stream byte 0x100) + var in/esi: (addr stream byte) <- address in-storage + print-string 0, "press ctrl-c or ctrl-d to exit\n" + # read-eval-print loop + { + # print prompt + print-string 0, "> " + # read line + clear-stream in + read-line-from-real-keyboard in + var done?/eax: boolean <- stream-empty? in + compare done?, 0 + break-if-!= + # parse and eval + var out/eax: int <- simplify in + # print + print-int32-decimal 0, out + print-string 0, "\n" + # + loop + } + exit-status <- copy 0 +} + +type int-stack { + data: (handle array int) + top: int +} + +fn simplify in: (addr stream byte) -> result/eax: int { + var word-storage: slice + var word/ecx: (addr slice) <- address word-storage + var stack-storage: int-stack + var stack/esi: (addr int-stack) <- address stack-storage + initialize-stack stack, 0x10 + $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 stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- add b + push-int-stack stack, 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 stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- subtract b + push-int-stack stack, 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 stack + var b/edx: int <- copy _b + var a/eax: int <- pop-int-stack stack + a <- multiply b + push-int-stack stack, a + loop $simplify:word-loop + } + # otherwise it's an int + var n/eax: int <- parse-decimal-int-from-slice word + push-int-stack stack, n + loop + } + result <- pop-int-stack stack +} + +fn initialize-stack _self: (addr int-stack), n: int { + var self/esi: (addr int-stack) <- copy _self + var d/edi: (addr handle array int) <- get self, data + populate d, n + var top/eax: (addr int) <- get self, top + copy-to *top, 0 +} + +fn push-int-stack _self: (addr int-stack), _val: int { + var self/esi: (addr int-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + var data-ah/edx: (addr handle array int) <- get self, data + var data/eax: (addr array int) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var dest-addr/edx: (addr int) <- index data, top + var val/eax: int <- copy _val + copy-to *dest-addr, val + add-to *top-addr, 1 +} + +fn pop-int-stack _self: (addr int-stack) -> val/eax: int { +$pop-int-stack:body: { + var self/esi: (addr int-stack) <- copy _self + var top-addr/ecx: (addr int) <- get self, top + { + compare *top-addr, 0 + break-if-> + val <- copy 0 + break $pop-int-stack:body + } + subtract-from *top-addr, 1 + var data-ah/edx: (addr handle array int) <- get self, data + var data/eax: (addr array int) <- lookup *data-ah + var top/edx: int <- copy *top-addr + var result-addr/eax: (addr int) <- index data, top + val <- copy *result-addr +} +} diff --git a/apps/sigils b/apps/sigils index 82f4e43a..087caf38 100755 Binary files a/apps/sigils and b/apps/sigils differ diff --git a/apps/survey b/apps/survey index abb0d1f0..76cadf48 100755 Binary files a/apps/survey and b/apps/survey differ diff --git a/apps/tests b/apps/tests index 7a4df46d..8c013997 100755 Binary files a/apps/tests and b/apps/tests differ diff --git a/apps/tests.subx b/apps/tests.subx index 75f8ef22..d61ea137 100644 --- a/apps/tests.subx +++ b/apps/tests.subx @@ -80,6 +80,8 @@ subx-gen-run-tests: # in: (addr buffered-file), out: (addr buffered-file) # read-line-buffered(in, line) # if (line->write == 0) break # end of file # var word-slice = next-word(line) + # if slice-empty?(word-slice) # empty line + # continue # if is-label?(word-slice) # if slice-starts-with?(word-slice, "test-") # tests-found = true @@ -184,6 +186,16 @@ $subx-gen-run-tests:check0: e8/call next-word/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp +$subx-gen-run-tests:check-empty: + # if slice-empty?(word-slice) break + # . eax = slice-empty?(word-slice) + 52/push-edx + e8/call slice-empty?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false + 75/jump-if-!= $subx-gen-run-tests:loop/disp8 $subx-gen-run-tests:check-for-label: # if (!is-label?(word-slice)) continue # . eax = is-label?(word-slice) -- cgit 1.4.1-2-gfad0