From 2a2a5b1e43b6aa650a41ab1ec68d9778c14cb649 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 8 Dec 2019 13:56:46 -0800 Subject: [PATCH] 5804 Try to make the comments consistent with the type system we'll eventually have. --- 050_write.subx | 20 ++ 051test.subx | 14 +- 052kernel-string-equal.subx | 26 ++- 053new-segment.subx | 8 +- 054string-equal.subx | 17 +- 055stream.subx | 18 +- 056trace.subx | 96 ++++---- 057write.subx | 4 +- 058stream-equal.subx | 32 +-- 059stop.subx | 2 +- 060read.subx | 7 +- 061read-byte.subx | 17 +- 062write-stream.subx | 6 +- 063error.subx | 2 +- 064write-byte.subx | 18 +- 065write-buffered.subx | 8 +- 066print-int.subx | 7 +- 067parse-hex.subx | 52 +++-- 068error-byte.subx | 4 +- 069allocate.subx | 16 +- 070new-stream.subx | 10 +- 071read-line.subx | 2 +- 072slice.subx | 106 ++++----- 073next-token.subx | 78 ++++--- 074write-stream-data.subx | 6 +- 075print-int-decimal.subx | 12 +- 076next-word.subx | 8 +- 077subx-words.subx | 70 +++--- 078emit-hex.subx | 4 +- 079emit.subx | 26 +-- 080zero-out.subx | 4 +- 081table.subx | 123 +++++----- 082slurp.subx | 4 +- 083subx-widths.subx | 25 +- 084emit-hex-array.subx | 12 +- 092write-int.subx | 2 +- 093array-equal.subx | 60 ++--- 094next-word-or-string.subx | 12 +- 095stack.subx | 12 +- apps/assort | Bin 42810 -> 42800 bytes apps/assort.subx | 44 ++-- apps/braces | Bin 42826 -> 42816 bytes apps/braces.subx | 20 +- apps/calls | Bin 47536 -> 47526 bytes apps/calls.subx | 56 ++--- apps/crenshaw2-1 | Bin 42218 -> 42208 bytes apps/crenshaw2-1.subx | 32 +-- apps/crenshaw2-1b | Bin 42765 -> 42755 bytes apps/crenshaw2-1b.subx | 30 +-- apps/dquotes | Bin 46460 -> 46450 bytes apps/dquotes.subx | 74 +++--- apps/factorial | Bin 41237 -> 41227 bytes apps/factorial.subx | 8 +- apps/handle | Bin 42135 -> 42125 bytes apps/handle.subx | 22 +- apps/hex | Bin 45057 -> 45047 bytes apps/hex.subx | 28 +-- apps/mu | Bin 63193 -> 63183 bytes apps/mu.subx | 451 ++++++++++++++++++------------------ apps/mulisp.subx | 18 +- apps/pack | Bin 55202 -> 55192 bytes apps/pack.subx | 260 ++++++++++----------- apps/sigils | Bin 55211 -> 55201 bytes apps/sigils.subx | 47 ++-- apps/survey | Bin 52051 -> 52041 bytes apps/survey.subx | 142 ++++++------ apps/tests | Bin 41608 -> 41598 bytes apps/tests.subx | 18 +- 68 files changed, 1122 insertions(+), 1078 deletions(-) diff --git a/050_write.subx b/050_write.subx index 4a48e825..13f3cddf 100644 --- a/050_write.subx +++ b/050_write.subx @@ -11,6 +11,26 @@ Entry: # just exit; can't test _write just yet b8/copy-to-eax 1/imm32/exit cd/syscall 0x80/imm8 +# Since this is the first file of SubX code, a note about type comments. +# Eventually we'll build a slightly higher-level safe language atop SubX. +# Even though we don't have the safe language yet, we'll start thinking in +# terms of the higher-level types in comments. +# +# Mu will have two kinds of addresses: +# - 'ref' which is used to point to a unique element, because machine +# code can't store large types in registers. +# - 'handle' which can point to a heap allocation, different heap allocations +# at different times, or even at times nothing at all. +# +# The type 'address' can be obtained from either a ref or handle, but it can +# only be stored on the stack (say to pass objects by reference). +# Conversely, a ref can't be copied into another ref, only to an address (which +# by construction has a shorter lifetime). +# +# Beginnings of a lattice of types: +# You can convert a ref or handle to an address, but not the other way around. +# You can convert addresses to ints, but not the other way around. + _write: # fd : int, s : (address array byte) # . prologue 55/push-ebp diff --git a/051test.subx b/051test.subx index 846e6cee..ac0f32a5 100644 --- a/051test.subx +++ b/051test.subx @@ -80,26 +80,26 @@ $check-ints-equal:end: # length-prefixed string containing just a single newline # convenient to have when printing messages and so on -Newline: - # size +Newline: # (ref array byte) + # size : int 1/imm32 # data 0a/newline # every test failure increments this counter -Num-test-failures: +Num-test-failures: # int 0/imm32 # length-prefixed string containing just a single space -Space: - # size +Space: # (ref array byte) + # size : int 1/imm32 # data 20/space # length-prefixed string containing just a single slash -Slash: - # size +Slash: # (ref array byte) + # size : int 1/imm32 # data 2f/slash diff --git a/052kernel-string-equal.subx b/052kernel-string-equal.subx index 357591e1..57b5b1ec 100644 --- a/052kernel-string-equal.subx +++ b/052kernel-string-equal.subx @@ -1,9 +1,11 @@ # Checking null-terminated ascii strings. # -# By default we create strings with a 4-byte length prefix rather than a null suffix. -# However we still need null-prefixed strings when interacting with the Linux -# kernel in a few places. This layer implements a function for comparing -# a null-terminated 'kernel string' with a length-prefixed 'SubX string'. +# By default we create strings as arrays of bytes, and all arrays have a 4-byte +# length prefix. +# +# However, we sometimes need to deal with null-prefixed strings when interacting +# with the Linux kernel. This layer implements a function for comparing a +# null-terminated 'kernel string' with a length-prefixed 'SubX string'. # # To run (from the subx directory): # $ ./subx translate 05[0-2]*.subx -o /tmp/tmp52 @@ -28,7 +30,7 @@ Entry: # run all tests # compare a null-terminated ascii string with a more idiomatic length-prefixed byte array # reason for the name: the only place we should have null-terminated ascii strings is from commandline args -kernel-string-equal?: # s : null-terminated ascii string, benchmark : length-prefixed ascii string -> eax : boolean +kernel-string-equal?: # s : (address kernel-string), benchmark : (address array byte) -> eax : boolean # pseudocode: # n = benchmark->length # s1 = s @@ -59,17 +61,19 @@ kernel-string-equal?: # s : null-terminated ascii string, benchmark : length-pr 53/push-ebx 56/push-esi 57/push-edi - # s1/edi = s + # var s1/edi : (address byte) = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi - # n/edx = benchmark->length + # var n/edx : int = benchmark->length 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx 8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx - # s2/esi = benchmark->data + # var s2/esi : (address byte) = benchmark->data 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi - # i/ecx = c1/eax = c2/ebx = 0 + # var i/ecx : int = 0 b9/copy-to-ecx 0/imm32/exit + # var c1/eax : byte = 0 b8/copy-to-eax 0/imm32 + # var c2/ebx : byte = 0 bb/copy-to-ebx 0/imm32 $kernel-string-equal?:loop: # if (i >= n) break @@ -258,10 +262,10 @@ test-compare-kernel-string-with-longer-array: == data -Null-kernel-string: +Null-kernel-string: # (address kernel-string) 00/null -_test-Abc-kernel-string: +_test-Abc-kernel-string: # (address kernel-string) 41/A 62/b 63/c 00/null # . . vim:nowrap:textwidth=0 diff --git a/053new-segment.subx b/053new-segment.subx index 719413ab..ba2487d5 100644 --- a/053new-segment.subx +++ b/053new-segment.subx @@ -17,7 +17,7 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes Entry: # manual test - # var ad/ecx : (address allocation-descriptor) = {0, 0} + # var ad/ecx : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -29,7 +29,7 @@ Entry: # manual test e8/call new-segment/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # eax = ad->curr + # var eax : (address _) = ad->curr 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax # write to *eax to check that we have access to the newly-allocated segment c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0x34/imm32 # copy to *eax @@ -38,7 +38,7 @@ Entry: # manual test b8/copy-to-eax 1/imm32/exit cd/syscall 0x80/imm8 -new-segment: # len : int, ad : (address allocation-descriptor) +new-segment: # len : int, ad : (ref allocation-descriptor) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -72,7 +72,7 @@ $new-segment:end: == data # various constants used here were found in the Linux sources (search for file mman-common.h) -_mmap-new-segment: # type mmap_arg_struct +_mmap-new-segment: # (ref mmap_arg_struct) # addr 0/imm32 $_mmap-new-segment:len: diff --git a/054string-equal.subx b/054string-equal.subx index 484844d9..c63688a1 100644 --- a/054string-equal.subx +++ b/054string-equal.subx @@ -13,12 +13,12 @@ Entry: # run all tests b8/copy-to-eax 1/imm32/exit cd/syscall 0x80/imm8 -string-equal?: # s : (address string), benchmark : (address string) -> eax : boolean +string-equal?: # s : (address array byte), benchmark : (address array byte) -> eax : boolean # pseudocode: # if (s->length != benchmark->length) return false # currs = s->data # currb = benchmark->data - # maxs = s->data + s->length + # maxs = &s->data[s->length] # while currs < maxs # c1 = *currs # c2 = *currb @@ -51,14 +51,15 @@ $string-equal?:lengths: # if (ecx != benchmark->length) return false 39/compare 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # compare *edi and ecx 75/jump-if-not-equal $string-equal?:false/disp8 - # currs/esi = s->data + # var currs/esi : (address byte) = s->data 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi - # maxs/ecx = s->data + s->length + # var maxs/ecx : (address byte) = &s->data[s->length] 01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx - # currb/edi = benchmark->data + # var currb/edi : (address byte) = benchmark->data 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi - # c1/eax = c2/edx = 0 + # var c1/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var c2/edx : byte = 0 31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx $string-equal?:loop: # if (currs >= maxs) return true @@ -175,13 +176,13 @@ test-compare-inequal-strings-equal-lengths: c3/return # helper for later tests -check-strings-equal: # s : (address string), expected : (address string), msg : (address string) +check-strings-equal: # s : (address array byte), expected : (address array byte), msg : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax - # eax = string-equal?(s, expected) + # var eax : boolean = string-equal?(s, expected) # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) diff --git a/055stream.subx b/055stream.subx index c60be1d5..6568602a 100644 --- a/055stream.subx +++ b/055stream.subx @@ -3,7 +3,7 @@ # A stream looks like this: # write : int # index at which writes go # read : int # index that we've read until -# data : (array byte) # prefixed by length as usual +# data : (ref array byte) # prefixed by length as usual # # some primitives for operating on streams: # - clear-stream (clears everything but the data length) @@ -14,7 +14,7 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -clear-stream: # f : (address stream) +clear-stream: # f : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -23,23 +23,23 @@ clear-stream: # f : (address stream) 51/push-ecx # eax = f 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax - # ecx = f->length + # var count/ecx : int = f->length 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 8/disp8 . # copy *(eax+8) to ecx - # ecx = &f->data[f->length] + # var max/ecx : (address byte) = &f->data[f->length] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 0xc/disp8 . # copy eax+ecx+12 to ecx # f->write = 0 c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax # f->read = 0 c7 0/subop/copy 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 0/imm32 # copy to *(eax+4) - # eax = f->data + # var curr/eax : (address byte) = f->data 81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 0xc/imm32 # add to eax $clear-stream:loop: - # if (eax >= ecx) break + # if (curr >= max) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 73/jump-if-greater-or-equal-unsigned $clear-stream:end/disp8 - # *eax = 0 + # *curr = 0 c6 0/subop/copy-byte 0/mod/direct 0/rm32/eax . . . . . 0/imm8 # copy byte to *eax - # ++eax + # ++curr 40/increment-eax eb/jump $clear-stream:loop/disp8 $clear-stream:end: @@ -51,7 +51,7 @@ $clear-stream:end: 5d/pop-to-ebp c3/return -rewind-stream: # f : (address stream) +rewind-stream: # f : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/056trace.subx b/056trace.subx index 2bcdde1e..0a09bd4f 100644 --- a/056trace.subx +++ b/056trace.subx @@ -14,9 +14,9 @@ == data -# We'll save the address of the trace segment here. -Trace-stream: +Trace-stream: # (handle stream byte) 0/imm32 + # we don't have safe handles (fat pointers) yet Trace-segment: 0/imm32/curr @@ -24,7 +24,7 @@ Trace-segment: # Fake trace-stream for tests. # Also illustrates the layout of the real trace-stream (segment). -_test-trace-stream: +_test-trace-stream: # (ref stream byte) # current write index 0/imm32 # current read index @@ -60,7 +60,7 @@ initialize-trace-stream: # n : int 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # copy Trace-segment->curr to *Trace-stream 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-segment/disp32 # copy *Trace-segment to eax - # watch point to catch Trace-stream leaks +#? # watch point to catch Trace-stream leaks #? $watch-1: 89/copy 0/mod/indirect 5/rm32/.disp32 . . 0/r32/eax Trace-stream/disp32 # copy eax to *Trace-stream # Trace-stream->length = n - 12 @@ -79,7 +79,7 @@ $initialize-trace-stream:end: # Append a string to the given trace stream. # Silently give up if it's already full. Or truncate the string if there isn't enough room. -trace: # line : (address string) +trace: # line : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -90,13 +90,13 @@ trace: # line : (address string) 53/push-ebx 56/push-esi 57/push-edi - # edi = *Trace-stream + # var edi : (address stream byte) = *Trace-stream 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 7/r32/edi Trace-stream/disp32 # copy *Trace-stream to edi # esi = line 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # ecx = t->write + # var ecx : int = t->write 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx - # edx = t->length + # var edx : int = t->length 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx # eax = _append-3(&t->data[t->write], &t->data[t->length], line) # . . push line @@ -302,7 +302,7 @@ $check-trace-scans-to:end: c3/return # Start scanning from Trace-stream->read for 'line'. If found, update Trace-stream->read and return true. -trace-scan: # line : (address string) -> result/eax : boolean +trace-scan: # line : (address array byte) -> result/eax : boolean # pseudocode: # push Trace-stream->read # while true: @@ -340,8 +340,8 @@ $trace-scan:loop: e8/call next-line-matches?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # if (eax == 0) continue - 3d/compare-eax-and 0/imm32 + # if (eax == false) continue + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $trace-scan:continue/disp8 $trace-scan:true: # skip-next-line(Trace-stream) @@ -554,7 +554,7 @@ test-trace-scan-failure-leaves-read-index-untouched: # . end c3/return -next-line-matches?: # t : (address stream), line : (address string) -> result/eax : boolean +next-line-matches?: # t : (address stream byte), line : (address array byte) -> result/eax : boolean # pseudocode: # while true: # if (currl >= maxl) break @@ -575,58 +575,58 @@ next-line-matches?: # t : (address stream), line : (address string) -> result/e 57/push-edi # edx = line 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx - # currl/esi = line->data + # var currl/esi : (address byte) = line->data # . esi = line/edx->data 8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 6/r32/esi 4/disp8 . # copy edx+4 to esi - # maxl/ecx = line->data + line->size + # var maxl/ecx : (address byte) = &line->data[line->size] # . eax = line/edx->size 8b/copy 0/mod/indirect 2/rm32/edx . . 0/r32/eax . . # copy *edx to eax - # . maxl/ecx = line->data/esi + line->size/eax + # . maxl = &line->data[line->size] 8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx # edi = t 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi - # ebx = t->data + # var ebx : (address byte) = t->data 8d/copy-address 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 0xc/disp8 . # copy edi+12 to ebx - # maxt/edx = t->data + t->write + # var maxt/edx : (address byte) = &t->data[t->write] # . eax = t->write 8b/copy 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax - # . maxt/edx = t->data/ebx + t->write/eax + # . maxt = &t->data[t->write] 8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 2/r32/edx . . # copy ebx+eax to edx - # currt/edi = t->data + t->read + # var currt/edi : (address byte) = &t->data[t->read] # . eax = t/edi->read 8b/copy 1/mod/*+disp8 7/rm32/edi . . 0/r32/eax 4/disp8 . # copy *(edi+4) to eax - # . currt/edi = t->data/ebx + t->read/eax + # . currt = &t->data[t->read] 8d/copy-address 0/mod/indirect 4/rm32/sib 3/base/ebx 0/index/eax . 7/r32/edi . . # copy ebx+eax to edi $next-line-matches?:loop: - # if (currl/esi >= maxl/ecx) break + # if (currl >= maxl) break 39/compare 3/mod/direct 6/rm32/esi . . . 1/r32/ecx . . # compare esi and ecx 73/jump-if-greater-or-equal-unsigned $next-line-matches?:break/disp8 - # if (currt/edi >= maxt/edx) return false + # if (currt >= maxt) return false # . eax = false b8/copy-to-eax 0/imm32/false 39/compare 3/mod/direct 7/rm32/edi . . . 2/r32/edx . . # compare edi and edx 73/jump-if-greater-or-equal-unsigned $next-line-matches?:end/disp8 - # if (*currt/edi != *currl/esi) return false + # if (*currt != *currl) return false 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 31/xor 3/mod/direct 3/rm32/eax . . . 3/r32/eax . . # clear ebx - # . eax = (char) *currt/edi + # . eax : byte = *currt 8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax - # . ebx = (char) *currl/esi + # . ebx : byte = *currl 8a/copy-byte 0/mod/indirect 6/rm32/esi . . 3/r32/ebx . . # copy *esi to ebx # . eax >= ebx 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx # . eax = false b8/copy-to-eax 0/imm32/false 75/jump-if-not-equal $next-line-matches?:end/disp8 - # ++currt/edi + # ++currt 47/increment-edi - # ++currl/esi + # ++currl 46/increment-esi eb/jump $next-line-matches?:loop/disp8 $next-line-matches?:break: # return *currt == '\n' 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax - # . eax = (char) *currt + # . eax : byte = *currt 8a/copy-byte 0/mod/indirect 7/rm32/edi . . 0/r32/eax . . # copy *edi to eax 3d/compare-eax-and 0xa/imm32/newline # . eax = false @@ -730,11 +730,11 @@ test-next-line-matches?-match: c3/return # move t->read to _after_ next newline -skip-next-line: # t : (address stream) +skip-next-line: # t : (address stream byte) # pseudocode: - # max = t->data + t->write + # max = &t->data[t->write] # i = t->read - # curr = t->data + t->read + # curr = &t->data[t->read] # while true # if (curr >= max) break # ++i @@ -752,37 +752,37 @@ skip-next-line: # t : (address stream) 53/push-ebx # ecx = t 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # edx = t/ecx->data + # edx = t->data 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 0xc/disp8 . # copy ecx+12 to edx - # eax = t/ecx->write + # eax = t->write 8b/copy 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax - # max/ebx = t->data/edx + t->write/eax + # var max/ebx : (address byte) = &t->data[t->write] 8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 3/r32/ebx . . # copy edx+eax to ebx - # eax = t/ecx->read + # eax = t->read 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy *(ecx+4) to edx - # curr/ecx = t->data/edx + t->read/eax + # var curr/ecx : (address byte) = &t->data[t->read] 8d/copy-address 0/mod/indirect 4/rm32/sib 2/base/edx 0/index/eax . 1/r32/ecx . . # copy edx+eax to ecx - # i/edx = eax + # var i/edx : int = t->read 89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx $skip-next-line:loop: - # if (curr/ecx >= max/ebx) break + # if (curr >= max) break 39/compare 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # compare ecx and ebx 73/jump-if-greater-or-equal-unsigned $skip-next-line:end/disp8 - # ++i/edx + # ++i 42/increment-edx - # if (*curr/ecx == '\n') break + # if (*curr == '\n') break 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/eax . . # copy *ecx to eax 3d/compare-eax-and 0a/imm32/newline 74/jump-if-equal $skip-next-line:end/disp8 - # ++curr/ecx + # ++curr 41/increment-ecx # loop eb/jump $skip-next-line:loop/disp8 $skip-next-line:end: # ecx = t 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # t/ecx->read = i/edx + # t->read = i 89/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy edx to *(ecx+4) # . restore registers 5b/pop-to-ebx @@ -858,7 +858,7 @@ $clear-trace-stream:end: # - helpers # 3-argument variant of _append -_append-3: # out : address, outend : address, s : (array byte) -> num_bytes_appended/eax +_append-3: # out : (address byte), outend : (address byte), s : (address array byte) -> num_bytes_appended/eax # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -890,7 +890,7 @@ $_append-3:end: c3/return # 4-argument variant of _append -_append-4: # out : address, outend : address, in : address, inend : address -> num_bytes_appended/eax +_append-4: # out : (address byte), outend : (address byte), in : (address byte), inend : (address byte) -> num_bytes_appended/eax : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -900,7 +900,7 @@ _append-4: # out : address, outend : address, in : address, inend : address -> 53/push-ebx 56/push-esi 57/push-edi - # eax/num_bytes_appended = 0 + # num_bytes_appended = 0 b8/copy-to-eax 0/imm32 # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi @@ -956,7 +956,7 @@ $_append-4:abort: == data -_test-stream-line-ABABA: +_test-stream-line-ABABA: # (ref stream byte) # write 8/imm32 # read @@ -966,7 +966,7 @@ _test-stream-line-ABABA: # data 41 42 41 42 41 0a 00 00 # 8 bytes -_test-stream-empty: +_test-stream-empty: # (ref stream byte) # write 0/imm32 # read @@ -976,7 +976,7 @@ _test-stream-empty: # data 00 00 00 00 00 00 00 00 # 8 bytes -_test-stream-filled: +_test-stream-filled: # (ref stream byte) # write 8/imm32 # read diff --git a/057write.subx b/057write.subx index b1ec1688..db3cb5cc 100644 --- a/057write.subx +++ b/057write.subx @@ -21,7 +21,7 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # TODO: come up with a way to signal when a write to disk fails -write: # f : fd or (address stream), s : (address array byte) +write: # f : fd or (address stream byte), s : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -145,7 +145,7 @@ test-write-appends: == data -_test-stream: +_test-stream: # (ref stream byte) # current write index 0/imm32 # current read index diff --git a/058stream-equal.subx b/058stream-equal.subx index 25330a52..bc3bc4d0 100644 --- a/058stream-equal.subx +++ b/058stream-equal.subx @@ -6,7 +6,7 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # compare all the data in a stream (ignoring the read pointer) -stream-data-equal?: # f : (address stream), s : (address string) -> eax : boolean +stream-data-equal?: # f : (address stream byte), s : (address array byte) -> eax : boolean # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -19,20 +19,21 @@ stream-data-equal?: # f : (address stream), s : (address string) -> eax : boole 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi # eax = f->write 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax - # maxf/edx = f->data + f->write + # var maxf/edx : (address byte) = &f->data[f->write] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 2/r32/edx 0xc/disp8 . # copy esi+eax+12 to edx - # currf/esi = f->data + # var currf/esi : (address byte) = f->data 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to esi # edi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi - # if (f->write != s->length) return false $stream-data-equal?:compare-lengths: + # if (f->write != s->length) return false 39/compare 0/mod/indirect 7/rm32/edi . . . 0/r32/eax . . # compare *edi and eax 75/jump-if-not-equal $stream-data-equal?:false/disp8 - # currs/edi = s->data + # var currs/edi : (address byte) = s->data 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi - # eax = ecx = 0 + # var eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var ecx : byte = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx $stream-data-equal?:loop: # if (currf >= maxf) return true @@ -190,7 +191,7 @@ test-stream-data-equal-length-check: c3/return # helper for later tests -check-stream-equal: # f : (address stream), s : (address string), msg : (address string) +check-stream-equal: # f : (address stream byte), s : (address array byte), msg : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -226,7 +227,7 @@ $check-stream-equal:end: # on success, set f->read to after the next newline # on failure, leave f->read unmodified # this function is usually used only in tests, so we repeatedly write f->read -next-stream-line-equal?: # f : (address stream), s : (address string) -> eax : boolean +next-stream-line-equal?: # f : (address stream byte), s : (address array byte) -> eax : boolean # pseudocode: # currf = f->read # bound: f->write # currs = 0 # bound : s->length @@ -273,30 +274,31 @@ next-stream-line-equal?: # f : (address stream), s : (address string) -> eax : 57/push-edi # esi = f 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # currf/ecx = f->read + # var currf/ecx : int = f->read 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx # edi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi - # currs/edx = 0 + # var currs/edx : int = 0 31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx - # eax = ebx = 0 + # var c1/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var c2/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $next-stream-line-equal?:loop: # if (currf >= f->write) break 3b/compare 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # compare ecx with *esi 7d/jump-if-greater-or-equal $next-stream-line-equal?:break/disp8 - # AL = *(f->data + f->read) + # c1 = f->data[f->read] 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0xc/disp8 . # copy byte at *(esi+ecx+12) to AL - # if (eax == '\n') break + # if (c1 == '\n') break 3d/compare-eax-and 0xa/imm32/newline 74/jump-if-equal $next-stream-line-equal?:break/disp8 # if (currs >= s->length) return false 3b/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare edx with *edi 7d/jump-if-greater-or-equal $next-stream-line-equal?:false/disp8 - # BL = *(s->data + currs) + # c2 = s->data[currs] 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 3/r32/BL 4/disp8 . # copy byte at *(edi+edx+4) to BL - # if (eax != ebx) return false + # if (c1 != c2) return false 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx 75/jump-if-not-equal $next-stream-line-equal?:false/disp8 # ++currf diff --git a/059stop.subx b/059stop.subx index 628c813d..7c1c776b 100644 --- a/059stop.subx +++ b/059stop.subx @@ -123,7 +123,7 @@ test-stop-skips-returns-on-exit: # Make room for an exit descriptor on the stack. That's almost always the # right place for it, available only as long as it's legal to use. Once this # containing function returns we'll need a new exit descriptor. - # var ed/eax : (address exit-descriptor) + # var ed/eax : (ref exit-descriptor) 68/push 0/imm32 68/push 0/imm32 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax diff --git a/060read.subx b/060read.subx index 1fe37da7..34658b7b 100644 --- a/060read.subx +++ b/060read.subx @@ -45,7 +45,7 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -read: # f : fd or (address stream), s : (address stream) -> num-bytes-read/eax +read: # f : fd or (address stream byte), s : (address stream byte) -> num-bytes-read/eax : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -191,12 +191,11 @@ $_buffer-4:end: 5d/pop-to-ebp c3/return - # idea: a clear-if-empty method on streams that clears only if f->read == f->write # Unclear how I'd use it, though. Callers seem to need the check anyway. # Maybe a better helper would be 'empty-stream?' -_read: # fd : int, s : (address stream) -> num-bytes-read/eax +_read: # fd : int, s : (address stream byte) -> num-bytes-read/eax : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -427,7 +426,7 @@ test-read-returns-0-on-end-of-file: == data -_test-tmp-stream: +_test-tmp-stream: # (ref stream byte) # current write index 0/imm32 # current read index diff --git a/061read-byte.subx b/061read-byte.subx index 4806a9f5..a90c05da 100644 --- a/061read-byte.subx +++ b/061read-byte.subx @@ -11,8 +11,8 @@ # The buffered file for standard input. Also illustrates the layout for # buffered-file: a pointer to the backing store, followed by a 'buffer' stream -Stdin: - # file descriptor or (address stream) +Stdin: # (ref buffered-file) + # file descriptor or (address stream byte) 0/imm32 # standard input $Stdin->buffer: # inlined fields for a stream @@ -73,8 +73,7 @@ read-byte-buffered: # f : (address buffered-file) -> byte-or-Eof/eax b8/copy-to-eax 0xffffffff/imm32/Eof eb/jump $read-byte-buffered:end/disp8 $read-byte-buffered:from-stream: - # read byte from stream - # AL = f->data[f->read] + # byte-or-Eof = f->data[f->read] 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0x10/disp8 . # copy byte at *(esi+ecx+16) to AL # ++f->read @@ -272,8 +271,8 @@ test-read-byte-buffered-refills-buffer: == data # a test buffered file for _test-stream -_test-buffered-file: - # file descriptor or (address stream) +_test-buffered-file: # (ref buffered-file) + # file descriptor or (address stream byte) _test-stream/imm32 $_test-buffered-file->buffer: # current write index @@ -285,7 +284,7 @@ $_test-buffered-file->buffer: # data 00 00 00 00 00 00 # 6 bytes -_test-input-stream: +_test-input-stream: # (ref stream byte) # current write index 0/imm32 # current read index @@ -311,8 +310,8 @@ _test-input-stream: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # a test buffered file for _test-input-stream -_test-input-buffered-file: - # file descriptor or (address stream) +_test-input-buffered-file: # (ref buffered-file) + # file descriptor or (address stream byte) _test-input-stream/imm32 $_test-input-buffered-file->buffer: # current write index diff --git a/062write-stream.subx b/062write-stream.subx index 12d3c7e2..2dab3fe8 100644 --- a/062write-stream.subx +++ b/062write-stream.subx @@ -15,7 +15,7 @@ #? b8/copy-to-eax 1/imm32/exit #? cd/syscall 0x80/imm8 -write-stream: # f : fd or (address stream), s : (address stream) +write-stream: # f : fd or (address stream byte), s : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -75,7 +75,7 @@ $write-stream:end: 5d/pop-to-ebp c3/return -_write-stream: # fd : int, s : (address stream) +_write-stream: # fd : int, s : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -242,7 +242,7 @@ test-write-stream-appends: == data -_test-stream2: +_test-stream2: # (ref stream byte) # current write index 4/imm32 # current read index diff --git a/063error.subx b/063error.subx index 1d77b3f0..bb1a8b71 100644 --- a/063error.subx +++ b/063error.subx @@ -6,7 +6,7 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # write(out, "Error: "+msg+"\n") then stop(ed, 1) -error: # ed : (address exit-descriptor), out : fd or (address stream), msg : (address array byte) +error: # ed : (address exit-descriptor), out : fd or (address stream byte), msg : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/064write-byte.subx b/064write-byte.subx index ec849c6d..2e7a36f3 100644 --- a/064write-byte.subx +++ b/064write-byte.subx @@ -7,8 +7,8 @@ == data # The buffered file for standard output. -Stdout: - # file descriptor or (address stream) +Stdout: # (ref buffered-file) + # file descriptor or (address stream byte) 1/imm32 # standard output $Stdout->buffer: # inlined fields for a stream @@ -205,7 +205,7 @@ test-write-byte-buffered-multiple-flushes: # - variant without buffering # Write lower byte of 'n' to 'f'. -append-byte: # f : (address stream), n : int +append-byte: # f : (address stream byte), n : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -283,7 +283,7 @@ test-append-byte-single: == data -_test-output-stream: +_test-output-stream: # (ref stream byte) # current write index 0/imm32 # current read index @@ -325,8 +325,8 @@ _test-output-stream: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # a test buffered file for _test-output-stream -_test-output-buffered-file: - # file descriptor or (address stream) +_test-output-buffered-file: # (ref buffered-file) + # file descriptor or (address stream byte) _test-output-stream/imm32 $_test-output-buffered-file->buffer: # current write index @@ -338,7 +338,7 @@ $_test-output-buffered-file->buffer: # data 00 00 00 00 00 00 # 6 bytes -_test-error-stream: +_test-error-stream: # (ref stream byte) # current write index 0/imm32 # current read index @@ -356,8 +356,8 @@ _test-error-stream: 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 # a test buffered file for _test-error-stream -_test-error-buffered-file: - # file descriptor or (address stream) +_test-error-buffered-file: # (ref buffered-file) + # file descriptor or (address stream byte) _test-error-stream/imm32 $_test-error-buffered-file->buffer: # current write index diff --git a/065write-buffered.subx b/065write-buffered.subx index bc829a51..8c7ae9c5 100644 --- a/065write-buffered.subx +++ b/065write-buffered.subx @@ -38,9 +38,9 @@ write-buffered: # f : (address buffered-file), msg : (address array byte) 57/push-edi # eax = msg 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax - # in/esi = msg->data + # var in/esi : (address byte) = msg->data 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 6/r32/esi 4/disp8 . # copy eax+4 to esi - # inend/ecx = &msg->data[msg->length] + # var inend/ecx : (address byte) = &msg->data[msg->length] 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 0/mod/indirect 4/rm32/sib 6/base/esi 1/index/ecx . 1/r32/ecx . . # copy esi+ecx to ecx # edi = f @@ -206,8 +206,8 @@ test-write-buffered-with-intermediate-flush: == data # The buffered file for standard error. -Stderr: - # file descriptor or (address stream) +Stderr: # (ref buffered-file) + # file descriptor or (address stream byte) 2/imm32 # standard error $Stderr->buffer: # inlined fields for a stream diff --git a/066print-int.subx b/066print-int.subx index cf043635..a1f968f7 100644 --- a/066print-int.subx +++ b/066print-int.subx @@ -5,7 +5,8 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -to-hex-char: # in/eax : nibble -> out/eax : byte +# convert the lowest nibble of eax to ascii and return it in the lowest byte of eax +to-hex-char: # in/eax : int -> out/eax : int # no error checking; accepts argument in eax # if (eax <= 9) return eax + '0' 3d/compare-eax-with 0x9/imm32/9 @@ -17,7 +18,7 @@ $to-hex-char:else: 05/add-to-eax 0x57/imm32/a-10 c3/return -append-byte-hex: # f : (address stream), n : int +append-byte-hex: # f : (address stream byte), n : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -174,7 +175,7 @@ test-print-byte-buffered: # . end c3/return -print-int32: # f : (address stream), n : int +print-int32: # f : (address stream byte), n : int # pseudocode: # write(f, "0x") # ecx = 28 diff --git a/067parse-hex.subx b/067parse-hex.subx index b5694b8c..105943ca 100644 --- a/067parse-hex.subx +++ b/067parse-hex.subx @@ -18,7 +18,7 @@ is-hex-int?: # in : (address slice) -> eax : boolean 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = s->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx - # curr/ecx = s->start + # var curr/ecx : (address byte) = s->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx # if s is empty return false b8/copy-to-eax 0/imm32/false @@ -56,7 +56,7 @@ $is-hex-int?:loop: # if (curr >= in->end) return true 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-or-equal-unsigned $is-hex-int?:true/disp8 - # eax = is-hex-digit?(*curr) + # var eax : boolean = is-hex-digit?(*curr) # . . push args 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 50/push-eax @@ -93,7 +93,7 @@ test-is-hex-int: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -127,7 +127,7 @@ test-is-hex-int-handles-letters: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -161,7 +161,7 @@ test-is-hex-int-with-trailing-char: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -195,7 +195,7 @@ test-is-hex-int-with-leading-char: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -224,7 +224,7 @@ test-is-hex-int-empty: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var slice/ecx = "" + # var slice/ecx : (ref slice) = "" 68/push 0/imm32 68/push 0/imm32 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -258,7 +258,7 @@ test-is-hex-int-handles-0x-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -292,7 +292,7 @@ test-is-hex-int-handles-negative: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -326,7 +326,7 @@ test-is-hex-int-handles-negative-0x-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -351,7 +351,7 @@ test-is-hex-int-handles-negative-0x-prefix: 5d/pop-to-ebp c3/return -parse-hex-int: # in : (address slice) -> result/eax +parse-hex-int: # in : (address slice) -> result/eax : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -360,18 +360,18 @@ parse-hex-int: # in : (address slice) -> result/eax 52/push-edx 53/push-ebx 56/push-esi - # result/ebx = 0 + # var result/ebx : int = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - # ecx = s + # ecx = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # edx = s->end + # edx = in->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx - # curr/ecx = s->start + # var curr/ecx : (address byte) = in->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 1/r32/ecx . . # copy *ecx to ecx - # negate?/esi = false + # var negate?/esi : boolean = false 31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi $parse-hex-int:negative: - # . if (*curr == '-') negate = true + # if (*curr == '-') ++curr, negate = true 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL 3d/compare-eax-and 0x2d/imm32/- @@ -403,7 +403,7 @@ $parse-hex-int:loop: # if (curr >= in->end) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-or-equal-unsigned $parse-hex-int:negate/disp8 - # eax = from-hex-char(*curr) + # var eax : int = from-hex-char(*curr) # . . copy arg to eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL # . . call @@ -416,10 +416,12 @@ $parse-hex-int:loop: # loop eb/jump $parse-hex-int:loop/disp8 $parse-hex-int:negate: - 81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32 # compare esi + # if (negate?) result = -result + 81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32/false # compare esi 74/jump-if-equal $parse-hex-int:end/disp8 f7 3/subop/negate 3/mod/direct 3/rm32/ebx . . . . . . # negate ebx $parse-hex-int:end: + # return result 89/copy 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to eax # . restore registers 5e/pop-to-esi @@ -440,7 +442,7 @@ test-parse-hex-int-single-digit: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -474,7 +476,7 @@ test-parse-hex-int-multi-digit: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -508,7 +510,7 @@ test-parse-hex-int-0x-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -542,7 +544,7 @@ test-parse-hex-int-zero: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -576,7 +578,7 @@ test-parse-hex-int-0-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -610,7 +612,7 @@ test-parse-hex-int-negative: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/068error-byte.subx b/068error-byte.subx index 5284c034..5490f890 100644 --- a/068error-byte.subx +++ b/068error-byte.subx @@ -6,7 +6,7 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes #? Entry: # manual test -#? # . var ed/eax : exit-descriptor +#? # . var ed/eax : (ref exit-descriptor) #? 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp #? 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax #? # . configure ed to really exit() @@ -68,7 +68,7 @@ error-byte: # ed : (address exit-descriptor), out : (address buffered-file), ms e8/call write-buffered/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . flush(out) + # flush(out) # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) # . . call diff --git a/069allocate.subx b/069allocate.subx index df3c05db..9b4dff57 100644 --- a/069allocate.subx +++ b/069allocate.subx @@ -19,14 +19,14 @@ == data # A default allocation descriptor for programs to use. -Heap: +Heap: # (ref allocation-descriptor) # curr 0/imm32 # limit 0/imm32 # a reasonable default -Heap-size: +Heap-size: # (ref int) 0x200000/imm32/2MB == code @@ -56,7 +56,7 @@ $array-equal-main:end: # Claim the next 'n' bytes of memory starting at ad->curr and update ad->curr. # Abort if there isn't enough memory in 'ad'. -allocate: # ad : (address allocation-descriptor), n : int -> address-or-null/eax +allocate: # ad : (address allocation-descriptor), n : int -> address-or-null/eax : (address _) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -104,11 +104,11 @@ test-allocate-success: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ad/ecx : (address allocation-descriptor) = {11, 15} + # var ad/ecx : (ref allocation-descriptor) = {11, 15} 68/push 0xf/imm32/limit 68/push 0xb/imm32/curr 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # eax = allocate(ad, 3) + # var eax : (handle byte) = allocate(ad, 3) # . . push args 68/push 3/imm32 51/push-ecx @@ -143,11 +143,11 @@ _pending-test-allocate-failure: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ad/ecx : (address allocation-descriptor) = {11, 15} + # var ad/ecx : (ref allocation-descriptor) = {11, 15} 68/push 0xf/imm32/limit 68/push 0xb/imm32/curr 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # eax = allocate(ad, 6) + # var eax : (handle byte) = allocate(ad, 6) # . . push args 68/push 6/imm32 51/push-ecx @@ -180,7 +180,7 @@ _pending-test-allocate-failure: c3/return # helper: create a nested allocation descriptor (useful for tests) -allocate-region: # ad : (address allocation-descriptor), n : int -> new-ad : (address allocation-descriptor) +allocate-region: # ad : (address allocation-descriptor), n : int -> new-ad : (handle allocation-descriptor) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/070new-stream.subx b/070new-stream.subx index e1bea314..45076c91 100644 --- a/070new-stream.subx +++ b/070new-stream.subx @@ -5,13 +5,13 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -new-stream: # ad : (address allocation-descriptor), length : int, elemsize : int -> address/eax +new-stream: # ad : (address allocation-descriptor), length : int, elemsize : int -> address/eax : (handle stream _) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 52/push-edx - # n = elemsize * length + 12 (for read, write and length) + # var n/eax : int = elemsize * length + 12 (for read, write and length) # . eax = elemsize 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0x10/disp8 . # copy *(ebp+16) to eax # . eax *= length @@ -24,7 +24,7 @@ new-stream: # ad : (address allocation-descriptor), length : int, elemsize : in 89/copy 3/mod/direct 2/rm32/edx . . . 0/r32/eax . . # copy eax to edx # . eax += 12 05/add-to-eax 0xc/imm32 - # allocate(ad, n) + # var eax : (handle stream _) = allocate(ad, n) # . . push args 50/push-eax ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) @@ -68,7 +68,7 @@ test-new-stream: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var heap/ecx : (address allocation-descriptor) = {0, 0} + # var heap/ecx : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -82,7 +82,7 @@ test-new-stream: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # var start/edx = ad->curr 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # eax = new-stream(heap, 3, 2) + # var eax : (handle stream byte) = new-stream(heap, 3, 2) # . . push args 68/push 2/imm32 68/push 3/imm32 diff --git a/071read-line.subx b/071read-line.subx index 6fe8deb7..ab336c52 100644 --- a/071read-line.subx +++ b/071read-line.subx @@ -216,7 +216,7 @@ test-read-line-buffered-reads-final-line-until-Eof: # read bytes from 'f' until (and including) a newline and store them into 's' # 's' fails to grow if and only if no data found # just abort if 's' is too small -read-line: # f : (address stream), s : (address stream byte) +read-line: # f : (address stream byte), s : (address stream byte) # pseudocode: # while true # if (s->write >= s->length) abort diff --git a/072slice.subx b/072slice.subx index 6ecdc003..30c1b356 100644 --- a/072slice.subx +++ b/072slice.subx @@ -34,7 +34,7 @@ test-slice-empty-true: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var slice/ecx = {34, 34} + # var slice/ecx : (ref slice) = {34, 34} 68/push 34/imm32/end 68/push 34/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -63,7 +63,7 @@ test-slice-empty-false: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var slice/ecx = {34, 23} + # var slice/ecx : (ref slice) = {34, 23} 68/push 23/imm32/end 68/push 34/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -88,7 +88,7 @@ test-slice-empty-false: 5d/pop-to-ebp c3/return -slice-equal?: # s : (address slice), p : (address string) -> eax : boolean +slice-equal?: # s : (address slice), p : (address array byte) -> eax : boolean # pseudocode: # if (p == 0) return (s == 0) # currs = s->start @@ -118,11 +118,11 @@ slice-equal?: # s : (address slice), p : (address string) -> eax : boolean 56/push-esi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # currs/edx = s->start + # var currs/edx : (address byte) = s->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx - # maxs/esi = s->end + # var maxs/esi : (address byte) = s->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi - # eax = maxs - currs + # var slen/eax : int = maxs - currs 89/copy 3/mod/direct 0/rm32/eax . . . 6/r32/esi . . # copy esi to eax 29/subtract 3/mod/direct 0/rm32/eax . . . 2/r32/edx . . # subtract edx from eax # ebx = p @@ -136,23 +136,24 @@ $slice-equal?:null-string: 74/jump-if-equal $slice-equal?:true/disp8 eb/jump $slice-equal?:false/disp8 $slice-equal?:nonnull-string: - # if (eax != p->length) return false + # if (slen != p->length) return false 39/compare 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # compare *ebx and eax 75/jump-if-not-equal $slice-equal?:false/disp8 - # currp/ebx = p->data + # var currp/ebx : (address byte) = p->data 81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx - # eax = ecx = 0 + # var c1/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var c2/ecx : byte = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx $slice-equal?:loop: # if (currs >= maxs) return true 39/compare 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # compare edx with esi 73/jump-if-greater-or-equal-unsigned $slice-equal?:true/disp8 - # AL = *currp + # c1 = *currp 8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL - # CL = *currs + # c2 = *currs 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 1/r32/CL . . # copy byte at *edx to CL - # if (eax != ecx) return false + # if (c1 != c2) return false 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax and ecx 75/jump-if-not-equal $slice-equal?:false/disp8 # ++currp @@ -186,7 +187,7 @@ test-slice-equal: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -222,7 +223,7 @@ test-slice-equal-false: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -258,7 +259,7 @@ test-slice-equal-too-long: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -294,7 +295,7 @@ test-slice-equal-too-short: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -325,7 +326,7 @@ test-slice-equal-empty: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var slice/ecx + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -361,7 +362,7 @@ test-slice-equal-with-empty: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -392,7 +393,7 @@ test-slice-equal-empty-with-empty: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var slice/ecx + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -428,7 +429,7 @@ test-slice-equal-with-null: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -454,7 +455,7 @@ test-slice-equal-with-null: 5d/pop-to-ebp c3/return -slice-starts-with?: # s : (address slice), head : (address string) -> eax : boolean +slice-starts-with?: # s : (address slice), head : (address array byte) -> eax : boolean # pseudocode # lenh = head->length # if (lenh > s->end - s->start) return false @@ -487,34 +488,35 @@ slice-starts-with?: # s : (address slice), head : (address string) -> eax : boo 57/push-edi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # ecx = s->end - s->start + # var lens/ecx : int = s->end - s->start 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy *(esi+4) to ecx 2b/subtract 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # subtract *esi from ecx # edi = head 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi - # lenh/edx = head->length + # var lenh/edx : int = head->length 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx - # if (lenh > s->end - s->start) return false + # if (lenh > lens) return false 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 7f/jump-if-greater $slice-starts-with?:false/disp8 - # currs/esi = s->start + # var currs/esi : (address byte) = s->start 8b/subtract 0/mod/indirect 6/rm32/esi . . . 6/r32/esi . . # copy *esi to esi - # currh/edi = head->data + # var currh/edi : (address byte) = head->data 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi - # i/ecx = 0 + # var i/ecx : int = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx - # eax = ebx = 0 + # var c1/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax + # var c2/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $slice-starts-with?:loop: # if (i >= lenh) return true 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 7d/jump-if-greater-or-equal $slice-starts-with?:true/disp8 - # AL = *currs + # c1 = *currs 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL - # BL = *currh + # c2 = *currh 8a/copy-byte 0/mod/indirect 7/rm32/edi . . . 3/r32/BL . . # copy byte at *edi to BL - # if (*currs != *currh) return false + # if (c1 != c2) return false 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx 75/jump-if-not-equal $slice-starts-with?:false/disp8 # ++i @@ -551,7 +553,7 @@ test-slice-starts-with-single-character: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -587,7 +589,7 @@ test-slice-starts-with-empty-string: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -623,7 +625,7 @@ test-slice-starts-with-multiple-characters: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -659,7 +661,7 @@ test-slice-starts-with-entire-string: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -695,7 +697,7 @@ test-slice-starts-with-fails: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -731,7 +733,7 @@ test-slice-starts-with-fails-2: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -759,7 +761,7 @@ test-slice-starts-with-fails-2: # write a slice to a stream # abort if the stream doesn't have enough space -write-slice: # out : (address stream), s : (address slice) +write-slice: # out : (address stream byte), s : (address slice) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -772,9 +774,9 @@ write-slice: # out : (address stream), s : (address slice) 57/push-edi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # curr/ecx = s->start + # var curr/ecx : (address byte) = s->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx - # max/esi = s->end + # var max/esi : (address byte) = s->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi @@ -848,7 +850,7 @@ test-write-slice: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -888,9 +890,9 @@ write-slice-buffered: # out : (address buffered-file), s : (address slice) 57/push-edi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # curr/ecx = s->start + # var curr/ecx : (address byte) = s->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx - # max/esi = s->end + # var max/esi : (address byte) = s->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi @@ -976,7 +978,7 @@ test-write-slice-buffered: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -1010,7 +1012,7 @@ test-write-slice-buffered: c3/return # copy a slice into a new (dynamically allocated) string -slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -> out/eax : (address array) +slice-to-string: # ad : (address allocation-descriptor), in : (address slice) -> out/eax : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -1021,15 +1023,15 @@ slice-to-string: # ad : (address allocation-descriptor), in : (address slice) - 56/push-esi # esi = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # curr/edx = in->start + # var curr/edx : (address byte) = in->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx - # max/ebx = in->end + # var max/ebx : (address byte) = in->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 3/r32/ebx 4/disp8 . # copy *(esi+4) to ebx - # size/ecx = max - curr + 4 # total size of output string (including the initial length) + # var size/ecx : int = max - curr + 4 # total size of output string (including the initial length) 89/copy 3/mod/direct 1/rm32/ecx . . . 3/r32/ebx . . # copy ebx to ecx 29/subtract 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # subtract edx from ecx 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx - # out/eax = allocate(ad, size) + # var out/eax : (handle array byte) = allocate(ad, size) # . . push args 51/push-ecx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) @@ -1040,7 +1042,7 @@ slice-to-string: # ad : (address allocation-descriptor), in : (address slice) - # if (eax == 0) abort 3d/compare-eax-and 0/imm32 74/jump-if-equal $slice-to-string:abort/disp8 - # *out = size-4 + # out->length = size-4 89/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy ecx to *eax 81 5/subop/subtract 0/mod/indirect 0/rm32/eax . . . . . 4/imm32 # subtract 4 from *eax # save out @@ -1092,7 +1094,7 @@ test-slice-to-string: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var heap/edx : (address allocation-descriptor) = {0, 0} + # var heap/edx : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -1109,7 +1111,7 @@ test-slice-to-string: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/073next-token.subx b/073next-token.subx index 35414883..567f0cce 100644 --- a/073next-token.subx +++ b/073next-token.subx @@ -7,7 +7,7 @@ # extract the next run of characters that are different from a given 'delimiter' (skipping multiple delimiters if necessary) # on reaching end of file, return an empty interval -next-token: # in : (address stream), delimiter : byte, out : (address slice) +next-token: # in : (address stream byte), delimiter : byte, out : (address slice) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -66,7 +66,7 @@ test-next-token: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -130,7 +130,7 @@ test-next-token-Eof: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -216,7 +216,7 @@ test-next-token-from-slice: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var out/edi : (address slice) = {0, 0} + # var out/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -265,7 +265,7 @@ test-next-token-from-slice-Eof: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var out/edi : (address slice) = {0, 0} + # var out/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -306,7 +306,7 @@ test-next-token-from-slice-nothing: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var out/edi : (address slice) = {0, 0} + # var out/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -338,7 +338,7 @@ test-next-token-from-slice-nothing: 5d/pop-to-ebp c3/return -skip-chars-matching: # in : (address stream), delimiter : byte +skip-chars-matching: # in : (address stream byte), delimiter : byte # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -461,7 +461,7 @@ test-skip-chars-matching-none: # end c3/return -skip-chars-matching-whitespace: # in : (address stream) +skip-chars-matching-whitespace: # in : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -551,7 +551,7 @@ test-skip-chars-matching-whitespace: c3/return # minor fork of 'skip-chars-matching' -skip-chars-not-matching: # in : (address stream), delimiter : byte +skip-chars-not-matching: # in : (address stream byte), delimiter : byte # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -713,7 +713,7 @@ test-skip-chars-not-matching-all: # end c3/return -skip-chars-not-matching-whitespace: # in : (address stream) +skip-chars-not-matching-whitespace: # in : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -815,14 +815,15 @@ skip-chars-matching-in-slice: # curr : (address byte), end : (address byte), de 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # edx = delimiter 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx - # ebx = 0 + # var c/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-matching-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 73/jump-if-greater-or-equal-unsigned $skip-chars-matching-in-slice:end/disp8 - # if (*curr != delimiter) break + # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL + # if (c != delimiter) break 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx and edx 75/jump-if-not-equal $skip-chars-matching-in-slice:end/disp8 # ++curr @@ -896,7 +897,7 @@ test-skip-chars-matching-in-slice-none: # end c3/return -skip-chars-matching-whitespace-in-slice: # in : (address stream) +skip-chars-matching-whitespace-in-slice: # curr : (address byte), end : (address byte) -> curr/eax # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -907,24 +908,24 @@ skip-chars-matching-whitespace-in-slice: # in : (address stream) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx - # ebx = 0 + # var c/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-matching-whitespace-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 0f 83/jump-if-greater-or-equal-unsigned $skip-chars-matching-in-slice:end/disp32 - # ebx = *curr + # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL - # if (*curr == ' ') goto body + # if (c == ' ') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx 74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8 - # if (*curr == '\n') goto body + # if (c == '\n') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx 74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8 - # if (*curr == '\t') goto body + # if (c == '\t') goto body 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx 74/jump-if-equal $skip-chars-matching-whitespace-in-slice:body/disp8 - # if (*curr != '\r') break + # if (c != '\r') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx 75/jump-if-not-equal $skip-chars-matching-whitespace-in-slice:end/disp8 $skip-chars-matching-whitespace-in-slice:body: @@ -983,14 +984,15 @@ skip-chars-not-matching-in-slice: # curr : (address byte), end : (address byte) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx # edx = delimiter 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx - # ebx = 0 + # var c/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-not-matching-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 73/jump-if-greater-or-equal-unsigned $skip-chars-not-matching-in-slice:end/disp8 - # if (*curr == delimiter) break + # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL + # if (c == delimiter) break 39/compare 3/mod/direct 3/rm32/ebx . . . 2/r32/edx . . # compare ebx and edx 74/jump-if-equal $skip-chars-not-matching-in-slice:end/disp8 # ++curr @@ -1093,7 +1095,7 @@ test-skip-chars-not-matching-in-slice-all: # end c3/return -skip-chars-not-matching-whitespace-in-slice: # in : (address stream) +skip-chars-not-matching-whitespace-in-slice: # curr : (address byte), end : (address byte) -> curr/eax # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -1104,24 +1106,24 @@ skip-chars-not-matching-whitespace-in-slice: # in : (address stream) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax # ecx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx - # ebx = 0 + # var c/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $skip-chars-not-matching-whitespace-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 0f 83/jump-if-greater-or-equal-unsigned $skip-chars-not-matching-in-slice:end/disp32 - # ebx = *curr + # c = *curr 8a/copy-byte 0/mod/indirect 0/rm32/eax . . . 3/r32/BL . . # copy byte at *eax to BL - # if (*curr == ' ') break + # if (c == ' ') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x20/imm32/space # compare ebx 74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8 - # if (*curr == '\n') break + # if (c == '\n') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0a/imm32/newline # compare ebx 74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8 - # if (*curr == '\t') break + # if (c == '\t') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x09/imm32/tab # compare ebx 74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8 - # if (*curr == '\r') break + # if (c == '\r') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x0d/imm32/cr # compare ebx 74/jump-if-equal $skip-chars-not-matching-whitespace-in-slice:end/disp8 # ++curr @@ -1166,7 +1168,7 @@ test-skip-chars-not-matching-whitespace-in-slice: # update line->read to end of string literal surrounded by double quotes # line->read must start out at a double-quote -skip-string: # line : (address stream) +skip-string: # line : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -1420,7 +1422,7 @@ skip-string-in-slice: # curr : (address byte), end : (address byte) -> new_curr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx - # eax = 0 + # var c/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax # skip initial dquote 41/increment-ecx @@ -1428,14 +1430,14 @@ $skip-string-in-slice:loop: # if (curr >= end) return curr 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-unsigned-or-equal $skip-string-in-slice:return-curr/disp8 - # AL = *curr + # c = *curr 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL $skip-string-in-slice:dquote: - # if (eax == '"') break + # if (c == '"') break 3d/compare-eax-and 0x22/imm32/double-quote 74/jump-if-equal $skip-string-in-slice:break/disp8 $skip-string-in-slice:check-for-escape: - # if (eax == '\') escape next char + # if (c == '\') escape next char 3d/compare-eax-and 0x5c/imm32/backslash 75/jump-if-not-equal $skip-string-in-slice:continue/disp8 $skip-string-in-slice:escape: @@ -1594,7 +1596,7 @@ test-skip-string-in-slice-stops-at-end: # update line->read to ')' # line->read ends at ')' -skip-until-close-paren: # line : (address stream) +skip-until-close-paren: # line : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -1781,7 +1783,7 @@ test-skip-until-close-paren-works-from-mid-stream: 5d/pop-to-ebp c3/return -skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte) -> new_curr/eax +skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte) -> new_curr/eax : (address byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -1792,7 +1794,7 @@ skip-until-close-paren-in-slice: # curr : (address byte), end : (address byte) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx - # eax = 0 + # var c/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax # skip initial dquote 41/increment-ecx @@ -1800,10 +1802,10 @@ $skip-until-close-paren-in-slice:loop: # if (curr >= end) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-unsigned-or-equal $skip-until-close-paren-in-slice:break/disp8 - # AL = *curr + # c = *curr 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL $skip-until-close-paren-in-slice:check-close: - # if (eax == ')') break + # if (c == ')') break 3d/compare-eax-and 0x29/imm32/close-paren 74/jump-if-equal $skip-until-close-paren-in-slice:break/disp8 # ++curr diff --git a/074write-stream-data.subx b/074write-stream-data.subx index 25a8f87c..074e9d29 100644 --- a/074write-stream-data.subx +++ b/074write-stream-data.subx @@ -8,7 +8,7 @@ # - construct a 'maximal slice' and pass it to write-slice-buffered # - flush the buffered-file and pass the stream directly to its fd (disabling buffering) # we'll go with the first way for now -write-stream-data: # f : (address buffered-file), s : (address stream) +write-stream-data: # f : (address buffered-file), s : (address stream byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -18,8 +18,8 @@ write-stream-data: # f : (address buffered-file), s : (address stream) 56/push-esi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # var slice/ecx = {s->data, s->data + s->write} - # . push s->data + s->write + # var slice/ecx : (ref slice) = {s->data, &s->data[s->write]} + # . push &s->data[s->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax 50/push-eax diff --git a/075print-int-decimal.subx b/075print-int-decimal.subx index a9cfa5fc..8e8c7da4 100644 --- a/075print-int-decimal.subx +++ b/075print-int-decimal.subx @@ -5,7 +5,7 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -print-int32-decimal: # out : (address stream), n : int32 +print-int32-decimal: # out : (address stream byte), n : int32 # works by generating characters from lowest to highest and pushing them # to the stack, before popping them one by one into the stream # @@ -44,11 +44,11 @@ print-int32-decimal: # out : (address stream), n : int32 52/push-edx 53/push-ebx 57/push-edi - # ten/ecx = 10 + # const ten/ecx = 10 b9/copy-to-ecx 0xa/imm32 # push sentinel 68/push 0/imm32/sentinel - # eax = abs(n) + # var eax : int = abs(n) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax 3d/compare-eax-with 0/imm32 7d/jump-if-greater-or-equal $print-int32-decimal:read-loop/disp8 @@ -74,11 +74,11 @@ $print-int32-decimal:push-negative: $print-int32-decimal:write: # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi - # w/edx = out->write + # var w/edx : int = out->write 8b/copy 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # copy *edi to edx - # curr/ecx = &out->data[out->write] + # var curr/ecx : (address byte) = &out->data[out->write] 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 1/r32/ecx 0xc/disp8 . # copy ebx+edx+12 to ecx - # max/ebx = &out->data[out->length] + # var max/ebx : (address byte) = &out->data[out->length] 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 3/r32/ebx 8/disp8 . # copy *(edi+8) to ebx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 7/base/edi 3/index/ebx . 3/r32/ebx 0xc/disp8 . # copy edi+ebx+12 to ebx $print-int32-decimal:write-loop: diff --git a/076next-word.subx b/076next-word.subx index 054dfb47..34dd9c4d 100644 --- a/076next-word.subx +++ b/076next-word.subx @@ -35,7 +35,7 @@ $next-word:check0: # . if (eax < line->write) goto next check 3b/compare 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # compare eax with *esi 7c/jump-if-lesser $next-word:check-for-comment/disp8 - # . return out = {0, 0} + # . return out c7 0/subop/copy 0/mod/direct 7/rm32/edi . . . . . 0/imm32 # copy to *edi c7 0/subop/copy 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 0/imm32 # copy to *(edi+4) eb/jump $next-word:end/disp8 @@ -95,7 +95,7 @@ test-next-word: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -158,7 +158,7 @@ test-next-word-returns-whole-comment: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -221,7 +221,7 @@ test-next-word-returns-empty-string-on-eof: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/077subx-words.subx b/077subx-words.subx index 2b53ebb1..a166217a 100644 --- a/077subx-words.subx +++ b/077subx-words.subx @@ -25,9 +25,9 @@ has-metadata?: # word : (address slice), s : (address string) -> eax : boolean 57/push-edi # esi = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # edx = word->end + # var edx : (address byte) = word->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx - # var twig/edi : (address slice) = {0, 0} + # var twig/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -41,15 +41,13 @@ has-metadata?: # word : (address slice), s : (address string) -> eax : boolean e8/call next-token-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp - # curr/ecx = twig->end - 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx $has-metadata?:loop: # next-token-from-slice(curr, word->end, '/', twig) # . . push args 57/push-edi 68/push 0x2f/imm32/slash 52/push-edx - 51/push-ecx + ff 6/subop/push 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 . # push *(edi+4) # . . call e8/call next-token-from-slice/disp32 # . . discard args @@ -62,8 +60,8 @@ $has-metadata?:loop: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) return false - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return false + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $has-metadata?:false/disp8 # if (slice-equal?(twig, s)) return true # . eax = slice-equal?(twig, s) @@ -74,15 +72,11 @@ $has-metadata?:loop: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return true - 3d/compare-eax-and 0/imm32 - 75/jump-if-not-equal $has-metadata?:true/disp8 - # curr = twig->end - 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 1/r32/ecx 4/disp8 . # copy *(edi+4) to ecx + # . if (eax != false) return true + 3d/compare-eax-and 0/imm32/false + # eax already contains true + 75/jump-if-not-equal $has-metadata?:end/disp8 eb/jump $has-metadata?:loop/disp8 -$has-metadata?:true: - b8/copy-to-eax 1/imm32/true - eb/jump $has-metadata?:end/disp8 $has-metadata?:false: b8/copy-to-eax 0/imm32/false $has-metadata?:end: @@ -107,7 +101,7 @@ test-has-metadata-true: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var in/esi : (address slice) = {eax, ecx} + # var in/esi : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -142,7 +136,7 @@ test-has-metadata-false: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var in/esi : (address slice) = {eax, ecx} + # var in/esi : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -177,7 +171,7 @@ test-has-metadata-ignore-name: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var in/esi : (address slice) = {eax, ecx} + # var in/esi : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -212,7 +206,7 @@ test-has-metadata-multiple-true: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var in/esi : (address slice) = {eax, ecx} + # var in/esi : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -247,7 +241,7 @@ test-has-metadata-multiple-false: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var in/esi : (address slice) = {eax, ecx} + # var in/esi : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -290,22 +284,21 @@ is-valid-name?: # in : (address slice) -> eax : boolean 56/push-esi # esi = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # start/ecx = in->start + # var start/ecx : (address byte) = in->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx - # end/eax = in->end - 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax $is-valid-name?:check0: - # if (start >= end) return false - 39/compare 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # compare ecx with eax + # if (start >= in->end) return false + 3b/compare 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # compare ecx with *(esi+4) 73/jump-if-greater-or-equal-unsigned $is-valid-name?:false/disp8 $is-valid-name?:check1: - # eax -= ecx + # var len/eax : int = in->end - start + 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax 29/subtract 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # subtract ecx from eax # if (eax == 2) return false 3d/compare-eax-and 2/imm32 74/jump-if-equal $is-valid-name?:false/disp8 $is-valid-name?:check2: - # c/eax = *ecx + # var c/eax : (address byte) = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL # if (c == "-") return false @@ -344,7 +337,7 @@ test-is-valid-name-digit-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -378,7 +371,7 @@ test-is-valid-name-negative-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -412,7 +405,7 @@ test-is-valid-name-0x-prefix: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -446,7 +439,7 @@ test-is-valid-name-starts-with-pre-digit: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -480,7 +473,7 @@ test-is-valid-name-starts-with-post-digit: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -514,7 +507,7 @@ test-is-valid-name-starts-with-digit: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -547,12 +540,11 @@ is-label?: # word : (address slice) -> eax : boolean 51/push-ecx # ecx = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx - # ecx = word->end + # var end/ecx : (address byte) = word->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 1/r32/ecx 4/disp8 . # copy *(ecx+4) to ecx - # return *(word->end - 1) == ':' - # . eax = 0 + # return *(end - 1) == ':' + # . eax = *(end-1) 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax - # . eax = *((char *) word->end - 1) 8a/copy-byte 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/AL -1/disp8 . # copy byte at *(ecx-1) to AL # . return (eax == ':') 3d/compare-eax-and 0x3a/imm32/colon @@ -577,7 +569,7 @@ $test-is-label?:true: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -603,7 +595,7 @@ $test-is-label?:false: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/078emit-hex.subx b/078emit-hex.subx index 2c642481..caea7800 100644 --- a/078emit-hex.subx +++ b/078emit-hex.subx @@ -20,13 +20,13 @@ emit-hex: # out : (address buffered-file), n : int, width : int 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 3/r32/ebx 0xc/disp8 . # copy *(ebp+12) to ebx # edx = width 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0x10/disp8 . # copy *(ebp+16) to edx - # var curr/ecx = 0 + # var curr/ecx : int = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx $emit-hex:loop: # if (curr >= width) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 7d/jump-if-greater-or-equal $emit-hex:end/disp8 - # print-byte-buffered(out, ebx) + # print-byte-buffered(out, ebx) # only BL used # . . push args 53/push-ebx 57/push-edi diff --git a/079emit.subx b/079emit.subx index 61ed425e..abf11dce 100644 --- a/079emit.subx +++ b/079emit.subx @@ -17,7 +17,7 @@ emit: # out : (address buffered-file), word : (address slice), width : int 57/push-edi # esi = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # var name/edi : (address slice) = {0, 0} + # var datum/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -39,8 +39,8 @@ emit: # out : (address buffered-file), word : (address slice), width : int e8/call is-valid-name?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) - 3d/compare-eax-and 0/imm32 + # . if (eax != false) + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit:hex-int/disp8 $emit:name: # . write-slice-buffered(out, word) @@ -63,11 +63,11 @@ $emit:name: eb/jump $emit:end/disp8 # otherwise emit-hex(out, parse-hex-int(datum), width) # (Weird shit can happen here if the datum of 'word' isn't either a valid - # name or a hex number, but we're only going to be passing in real legal - # programs. We just want to make sure that valid names aren't treated as - # (valid) hex numbers.) + # name or a hex number. `emit` is mostly used by ntranslate, which is + # currently designed to only receive legal SubX programs. We just want to + # make sure that valid names aren't treated as (valid) hex numbers.) $emit:hex-int: - # . value/eax = parse-hex-int(datum) + # . var value/eax : int = parse-hex-int(datum) # . . push args 57/push-edi # . . call @@ -119,7 +119,7 @@ test-emit-number: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -178,7 +178,7 @@ test-emit-negative-number: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -236,7 +236,7 @@ test-emit-number-with-metadata: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -295,7 +295,7 @@ test-emit-non-number: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -353,7 +353,7 @@ test-emit-non-number-with-metadata: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -411,7 +411,7 @@ test-emit-non-number-with-all-hex-digits-and-metadata: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/080zero-out.subx b/080zero-out.subx index 2dee2665..19e8128f 100644 --- a/080zero-out.subx +++ b/080zero-out.subx @@ -5,7 +5,7 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -zero-out: # start : address, len : int +zero-out: # start : (address byte), len : int # pseudocode: # curr/esi = start # i/ecx = 0 @@ -25,7 +25,7 @@ zero-out: # start : address, len : int 56/push-esi # curr/esi = start 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # i/ecx = 0 + # var i/ecx : int = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx # edx = len 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx diff --git a/081table.subx b/081table.subx index 83cd9102..46329ca0 100644 --- a/081table.subx +++ b/081table.subx @@ -1,7 +1,7 @@ # A table is a stream of (key, value) rows. # -# Each row consists of a 4-byte key (address to a string) and a variable-size -# value. +# Each row consists of a 4-byte key -- a 'string_key' which is (address array +# byte) -- and a variable-size value. # # Accessing the table performs a linear scan for a key string, and always # requires passing in the row size. @@ -23,7 +23,8 @@ # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes # if no row is found, abort -get: # table : (address stream {string, _}), key : (address string), row-size : int, abort-message-prefix : (address string) -> eax : (address _) +# type string_key = (address array byte) +get: # table : (address stream {string_key, T}), key : string_key, row-size : int, abort-message-prefix : (address array byte) -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -42,9 +43,9 @@ get: # table : (address stream {string, _}), key : (address string), row-size : 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $get:search-loop: @@ -60,8 +61,8 @@ $get:search-loop: e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $get:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $get:end/disp8 @@ -124,7 +125,7 @@ test-get: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # - setup: create a table with a couple of keys - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -197,7 +198,7 @@ $test-get:end: c3/return # if no row is found, abort -get-slice: # table : (address stream {string, _}), key : (address slice), row-size : int, abort-message-prefix : (address string) -> eax : (address _) +get-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int, abort-message-prefix : (address array byte) -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -216,9 +217,9 @@ get-slice: # table : (address stream {string, _}), key : (address slice), row-s 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $get-slice:search-loop: @@ -234,8 +235,8 @@ $get-slice:search-loop: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $get-slice:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $get-slice:end/disp8 @@ -305,7 +306,7 @@ test-get-slice: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # - setup: create a table with a couple of keys - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -335,7 +336,7 @@ $test-get-slice:check1: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -365,7 +366,7 @@ $test-get-slice:check2: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -400,7 +401,7 @@ $test-get-slice:end: # return the address of the value # Beware: assume keys are immutable; they're inserted by reference # TODO: pass in an allocation descriptor -get-or-insert: # table : (address stream {string, _}), key : (address string), row-size : int -> eax : (address _) +get-or-insert: # table : (address stream {string_key, T}), key : string_key, row-size : int -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -424,9 +425,9 @@ get-or-insert: # table : (address stream {string, _}), key : (address string), 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address string_key) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $get-or-insert:search-loop: @@ -442,8 +443,8 @@ $get-or-insert:search-loop: e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $get-or-insert:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $get-or-insert:end/disp8 @@ -511,7 +512,7 @@ test-get-or-insert: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -651,7 +652,7 @@ $test-get-or-insert:end: # if there are no rows free, abort # WARNING: leaks memory # TODO: pass in an allocation descriptor -leaky-get-or-insert-slice: # table : (address stream {string, _}), key : (address slice), row-size : int -> eax : (address _) +leaky-get-or-insert-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -675,9 +676,9 @@ leaky-get-or-insert-slice: # table : (address stream {string, _}), key : (addre 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address string_key) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $leaky-get-or-insert-slice:search-loop: @@ -693,8 +694,8 @@ $leaky-get-or-insert-slice:search-loop: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $leaky-get-or-insert-slice:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $leaky-get-or-insert-slice:end/disp8 @@ -768,7 +769,7 @@ test-leaky-get-or-insert-slice: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -779,7 +780,7 @@ test-leaky-get-or-insert-slice: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -872,7 +873,7 @@ $test-leaky-get-or-insert-slice:third-call: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -923,9 +924,9 @@ $test-leaky-get-or-insert-slice:end: c3/return # if no row is found, stop(ed) -get-or-stop: # table : (address stream {string, _}), key : (address string), row-size : int, - # abort-message-prefix : (address string), err : (address buffered-file), ed : (address exit-descriptor) - # -> eax : (address _) +get-or-stop: # table : (address stream {string_key, T}), key : string_key, row-size : int, + # abort-message-prefix : (address array byte), err : (address buffered-file), ed : (address exit-descriptor) + # -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -945,9 +946,9 @@ get-or-stop: # table : (address stream {string, _}), key : (address string), ro 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $get-or-stop:search-loop: @@ -963,8 +964,8 @@ $get-or-stop:search-loop: e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $get-or-stop:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $get-or-stop:end/disp8 @@ -1050,13 +1051,13 @@ test-get-or-stop: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var ed/edx : (address exit-descriptor) + # var ed/edx : (ref exit-descriptor) 68/push 0/imm32 68/push 0/imm32 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -1139,7 +1140,7 @@ $test-get-or-stop:end: c3/return # if no row is found, stop(ed) -get-slice-or-stop: # table : (address stream {string, _}), key : (address slice), row-size : int, +get-slice-or-stop: # table : (address stream {string_key, _}), key : (address slice), row-size : int, # abort-message-prefix : (address string), err : (address buffered-file), ed : (address exit-descriptor) # -> eax : (address _) # pseudocode: @@ -1161,9 +1162,9 @@ get-slice-or-stop: # table : (address stream {string, _}), key : (address slice 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $get-slice-or-stop:search-loop: @@ -1179,8 +1180,8 @@ $get-slice-or-stop:search-loop: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $get-slice-or-stop:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $get-slice-or-stop:end/disp8 @@ -1266,17 +1267,17 @@ test-get-slice-or-stop: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var ed/edx : (address exit-descriptor) + # var ed/edx : (ref exit-descriptor) 68/push 0/imm32 68/push 0/imm32 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx - # var slice/ebx = "code" + # var slice/ebx : (ref slice) = "code" # . (eax..ebx) = "code" b8/copy-to-eax "code"/imm32 8b/copy 0/mod/indirect 0/rm32/eax . . . 3/r32/ebx . . # copy *eax to ebx @@ -1378,7 +1379,7 @@ $test-get-slice-or-stop:end: c3/return # if no row is found, return null (0) -maybe-get: # table : (address stream {string, _}), key : (address string), row-size : int -> eax : (address _) +maybe-get: # table : (address stream {string_key, T}), key : string_key, row-size : int -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -1397,9 +1398,9 @@ maybe-get: # table : (address stream {string, _}), key : (address string), row- 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $maybe-get:search-loop: @@ -1415,8 +1416,8 @@ $maybe-get:search-loop: e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $maybe-get:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $maybe-get:end/disp8 @@ -1442,7 +1443,7 @@ test-maybe-get: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # - setup: create a table with one row - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -1525,7 +1526,7 @@ $test-maybe-get:end: c3/return # if no row is found, return null (0) -maybe-get-slice: # table : (address stream {string, _}), key : (address slice), row-size : int -> eax : (address _) +maybe-get-slice: # table : (address stream {string_key, T}), key : (address slice), row-size : int -> eax : (address T) # pseudocode: # curr = table->data # max = &table->data[table->write] @@ -1544,9 +1545,9 @@ maybe-get-slice: # table : (address stream {string, _}), key : (address slice), 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/ecx = table->data + # var curr/ecx : (address string_key) = table->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 0xc/disp8 . # copy esi+12 to ecx - # max/edx = table->data + table->write + # var max/edx : (address byte) = &table->data[table->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx 8d/copy-address 0/mod/indirect 4/rm32/sib 1/base/ecx 2/index/edx . 2/r32/edx . . # copy ecx+edx to edx $maybe-get-slice:search-loop: @@ -1562,8 +1563,8 @@ $maybe-get-slice:search-loop: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return eax = curr+4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return eax = curr+4 + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $maybe-get-slice:mismatch/disp8 8d/copy-address 1/mod/*+disp8 1/rm32/ecx . . . 0/r32/eax 4/disp8 . # copy ecx+4 to eax eb/jump $maybe-get-slice:end/disp8 @@ -1589,7 +1590,7 @@ test-maybe-get-slice: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # - setup: create a table with one row - # var table/ecx : (address stream {string, number}) = stream(2 rows * 8 bytes) + # var table/ecx : (ref stream {string, number} 16) # 2 rows * 8 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # subtract from esp 68/push 0x10/imm32/length 68/push 0/imm32/read @@ -1611,7 +1612,7 @@ $test-maybe-get-slice:success: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -1661,7 +1662,7 @@ $test-maybe-get-slice:failure: 8b/copy 0/mod/indirect 0/rm32/eax . . . 2/r32/edx . . # copy *eax to edx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 2/index/edx . 2/r32/edx 4/disp8 . # copy eax+edx+4 to edx 05/add-to-eax 4/imm32 - # var slice/edx = {eax, edx} + # var slice/edx : (ref slice) = {eax, edx} 52/push-edx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx diff --git a/082slurp.subx b/082slurp.subx index a00f252b..51fba1e2 100644 --- a/082slurp.subx +++ b/082slurp.subx @@ -63,10 +63,10 @@ $slurp:loop: 3d/compare-eax-and 0/imm32 74/jump-if-equal $slurp:end/disp8 $slurp:from-stream: - # AL = f->data[f->read] + # var c/eax : byte = f->data[f->read] 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/AL 0x10/disp8 . # copy byte at *(esi+ecx+16) to AL - # s->data[s->write] = AL + # s->data[s->write] = c 88/copy-byte 1/mod/*+disp8 4/rm32/sib 7/base/edi 2/index/edx . 0/r32/AL 0xc/disp8 . # copy AL to *(edi+edx+12) # ++f->read 41/increment-ecx diff --git a/083subx-widths.subx b/083subx-widths.subx index 7bd7141f..db5b84ba 100644 --- a/083subx-widths.subx +++ b/083subx-widths.subx @@ -1,3 +1,8 @@ +# Helpers to compute widths of SubX arguments based on their metadata. +# /imm8 => 1 byte, +# /disp32 => 4 bytes, +# and so on. + == code # instruction effective address register displacement immediate # . op subop mod rm32 base index scale r32 @@ -11,12 +16,12 @@ compute-width: # word : (address array byte) -> eax : int 51/push-ecx # eax = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to ecx - # ecx = word + word->length + # var ecx : (address byte) = &word[word->length] 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx # eax = word->data 05/add-to-eax 4/imm32 - # var in/ecx : (address slice) = {eax, ecx} + # var in/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -54,8 +59,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return 4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return 4 + 3d/compare-eax-and 0/imm32/false b8/copy-to-eax 4/imm32 # ZF is set, so we can overwrite eax now 75/jump-if-not-equal $compute-width-of-slice:end/disp8 # if (has-metadata?(word, "disp32")) return 4 @@ -67,8 +72,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return 4 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return 4 + 3d/compare-eax-and 0/imm32/false b8/copy-to-eax 4/imm32 # ZF is set, so we can overwrite eax now 75/jump-if-not-equal $compute-width-of-slice:end/disp8 # if (has-metadata?(word, "imm16")) return 2 @@ -80,8 +85,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return 2 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return 2 + 3d/compare-eax-and 0/imm32/false b8/copy-to-eax 2/imm32 # ZF is set, so we can overwrite eax now 75/jump-if-not-equal $compute-width-of-slice:end/disp8 # if (has-metadata?(word, "disp16")) return 2 @@ -93,8 +98,8 @@ compute-width-of-slice: # s : (address slice) -> eax : int e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return 2 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return 2 + 3d/compare-eax-and 0/imm32/false b8/copy-to-eax 2/imm32 # ZF is set, so we can overwrite eax now 75/jump-if-not-equal $compute-width-of-slice:end/disp8 # otherwise return 1 diff --git a/084emit-hex-array.subx b/084emit-hex-array.subx index e284b2c8..29f685f9 100644 --- a/084emit-hex-array.subx +++ b/084emit-hex-array.subx @@ -15,20 +15,20 @@ emit-hex-array: # out : (address buffered-file), arr : (address array byte) 57/push-edi # edi = out 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 8/disp8 . # copy *(ebp+8) to edi - # edx = arr # <== 0xbdffffe4 + # edx = arr 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx - # curr/ecx = arr->data + # var curr/ecx : (address byte) = arr->data 8d/copy-address 1/mod/*+disp8 2/rm32/edx . . . 1/r32/ecx 4/disp8 . # copy edx+4 to ecx - # max/edx = arr->data + arr->length + # var max/edx : (address byte) = &arr->data[arr->length] 8b/copy 0/mod/indirect 2/rm32/edx . . . 2/r32/edx . . # copy *edx to edx 01/add 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # add ecx to edx - # eax = 0 + # var c/eax : byte = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax $emit-hex-array:loop: # if (curr >= width) break 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-or-equal-unsigned $emit-hex-array:end/disp8 - # emit-hex(out, *curr, width=1) + # emit-hex(out, c = *curr, width=1) # . . push args 68/push 1/imm32/width 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 0/r32/AL . . # copy byte at *ecx to AL @@ -71,7 +71,7 @@ test-emit-hex-array: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var arr/ecx (address array byte) = [01, 02, 03] + # var arr/ecx (ref array byte) = [01, 02, 03] 68/push 0x00030201/imm32 # bytes 01 02 03 68/push 3/imm32/length 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/092write-int.subx b/092write-int.subx index 7ebd473a..5fe1c4d3 100644 --- a/092write-int.subx +++ b/092write-int.subx @@ -5,7 +5,7 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -write-int: # out : (address stream), n : int +write-int: # out : (address stream byte), n : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/093array-equal.subx b/093array-equal.subx index 95cff9dd..f10a9463 100644 --- a/093array-equal.subx +++ b/093array-equal.subx @@ -40,27 +40,29 @@ array-equal?: # a : (address array int), b : (address array int) -> eax : boole 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi # edi = b 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 7/r32/edi 0xc/disp8 . # copy *(ebp+12) to edi - # lena/edx = a->length + # var lena/edx : int = a->length 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx $array-equal?:lengths: # if (lena != b->length) return false 39/compare 0/mod/indirect 7/rm32/edi . . . 2/r32/edx . . # compare *edi and edx 75/jump-if-not-equal $array-equal?:false/disp8 - # curra/esi = a->data + # var curra/esi : (address byte) = a->data 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 4/imm32 # add to esi - # currb/edi = b->data + # var currb/edi : (address byte) = b->data 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 4/imm32 # add to edi - # i/ecx = i1/eax = i2/ebx = 0 + # var i/ecx : int = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx + # var vala/eax : int + # var valb/ebx : int $array-equal?:loop: # if (i >= lena) return true 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 7d/jump-if-greater-or-equal $array-equal?:true/disp8 - # i1 = *curra + # vala = *curra 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax - # i2 = *currb + # valb = *currb 8b/copy 0/mod/indirect 7/rm32/edi . . . 3/r32/ebx . . # copy *edi to ebx - # if (i1 != i2) return false + # if (vala != valb) return false 39/compare 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # compare eax and ebx 75/jump-if-not-equal $array-equal?:false/disp8 # i += 4 @@ -91,10 +93,10 @@ test-compare-empty-with-empty-array: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [] + # var ecx : (ref array _) = [] 68/push 0/imm32/size 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var edx = [] + # var edx : (ref array _) = [] 68/push 0/imm32/size 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx # eax = array-equal?(ecx, edx) @@ -123,11 +125,11 @@ test-compare-empty-with-non-empty-array: # also checks length-mismatch code pat # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1] + # var ecx : (ref array int) = [1] 68/push 1/imm32 68/push 4/imm32/size 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var edx = [] + # var edx : (ref array int) = [] 68/push 0/imm32/size 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx # eax = array-equal?(ecx, edx) @@ -156,13 +158,13 @@ test-compare-equal-arrays: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1, 2, 3] + # var ecx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var edx = [1, 2, 3] + # var edx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 @@ -194,13 +196,13 @@ test-compare-inequal-arrays-equal-lengths: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1, 4, 3] + # var ecx : (ref array int) = [1, 4, 3] 68/push 3/imm32 68/push 4/imm32 68/push 1/imm32 68/push 0xc/imm32/size 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var edx = [1, 2, 3] + # var edx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 @@ -228,9 +230,9 @@ test-compare-inequal-arrays-equal-lengths: 5d/pop-to-ebp c3/return -parse-array-of-ints: # ad : (address allocation-descriptor), s : (address string) -> result/eax : (address array int) +parse-array-of-ints: # ad : (address allocation-descriptor), s : (address string) -> result/eax : (handle array int) # pseudocode - # end = s->data + s->length + # end = &s->data[s->length] # curr = s->data # size = 0 # while true @@ -241,7 +243,7 @@ parse-array-of-ints: # ad : (address allocation-descriptor), s : (address strin # ++size # result = allocate(ad, (size+1)*4) # result->size = (size+1)*4 - # var slice = {s->data, 0} + # var slice : (ref slice) = {s->data, 0} # out = result->data # while true # if (slice->start >= end) break @@ -264,14 +266,14 @@ parse-array-of-ints: # ad : (address allocation-descriptor), s : (address strin 57/push-edi # esi = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # curr/ecx = s->data + # var curr/ecx : (address byte) = s->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 1/r32/ecx 4/disp8 . # copy esi+4 to ecx - # end/edx = s->data + s->length + # var end/edx : (address byte) = &s->data[s->length] # . edx = s->length 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx # . edx += curr 01/add 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # add ecx to edx - # size/ebx = 0 + # var size/ebx : int = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $parse-array-of-ints:loop1: # if (curr >= end) break @@ -308,7 +310,7 @@ $parse-array-of-ints:loop1: 81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx eb/jump $parse-array-of-ints:loop1/disp8 $parse-array-of-ints:break1: - # result/edi = allocate(ad, size+4) + # var result/edi : (handle array int) = allocate(ad, size+4) # . eax = allocate(ad, size+4) # . . push args 89/copy 3/mod/direct 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to eax @@ -324,7 +326,7 @@ $parse-array-of-ints:break1: # result->size = size 89/copy 0/mod/indirect 0/rm32/eax . . . 3/r32/ebx . . # copy ebx to *eax $parse-array-of-ints:pass2: - # var slice/ecx = {s->data, 0} + # var slice/ecx : (ref slice) = {s->data, 0} # . push 0 68/push 0/imm32/end # . push s->data @@ -332,7 +334,7 @@ $parse-array-of-ints:pass2: 51/push-ecx # . bookmark 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # out/ebx = result->data + # var out/ebx : (address byte) = result->data 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 3/r32/ebx 4/disp8 . # copy eax+4 to ebx $parse-array-of-ints:loop2: # if (slice->start >= end) break @@ -373,7 +375,7 @@ $parse-array-of-ints:loop2: e8/call parse-hex-int/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # *out = eax + # . *out = eax 89/copy 0/mod/indirect 3/rm32/ebx . . . 0/r32/eax . . # copy eax to *ebx # out += 4 81 0/subop/add 3/mod/direct 3/rm32/ebx . . . . . 4/imm32 # add to ebx @@ -402,7 +404,7 @@ test-parse-array-of-ints: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1, 2, 3] + # var ecx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 @@ -496,7 +498,7 @@ test-parse-array-of-ints-extra-whitespace: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1, 2, 3] + # var ecx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 @@ -540,7 +542,7 @@ check-array-equal: # a : (address array int), expected : (address string), msg 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 50/push-eax - # var b/ecx = parse-array-of-ints(Heap, expected) + # var b/ecx : (handle array int) = parse-array-of-ints(Heap, expected) # . eax = parse-array-of-ints(Heap, expected) # . . push args ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) @@ -580,7 +582,7 @@ test-check-array-equal: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var ecx = [1, 2, 3] + # var ecx : (ref array int) = [1, 2, 3] 68/push 3/imm32 68/push 2/imm32 68/push 1/imm32 diff --git a/094next-word-or-string.subx b/094next-word-or-string.subx index 0fe24c6a..d3734fc9 100644 --- a/094next-word-or-string.subx +++ b/094next-word-or-string.subx @@ -33,7 +33,7 @@ $next-word-or-string:check0: # . if (eax < line->write) goto next check 3b/compare 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # compare eax with *esi 7c/jump-if-lesser $next-word-or-string:check-for-comment/disp8 - # . return out = {0, 0} + # . return out c7 0/subop/copy 0/mod/direct 7/rm32/edi . . . . . 0/imm32 # copy to *edi c7 0/subop/copy 1/mod/*+disp8 7/rm32/edi . . . . 4/disp8 0/imm32 # copy to *(edi+4) eb/jump $next-word-or-string:end/disp8 @@ -111,7 +111,7 @@ test-next-word-or-string: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -184,7 +184,7 @@ test-next-word-or-string-returns-whole-comment: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -257,7 +257,7 @@ test-next-word-or-string-returns-empty-slice-on-eof: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -299,7 +299,7 @@ test-next-word-or-string-returns-string-literal: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -362,7 +362,7 @@ test-next-word-or-string-returns-string-with-escapes: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx diff --git a/095stack.subx b/095stack.subx index 2e2f182e..692dece2 100644 --- a/095stack.subx +++ b/095stack.subx @@ -16,20 +16,20 @@ clear-stack: # s : (address stack) 51/push-ecx # eax = s 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax - # ecx = &s->data[s->length] + # var max/ecx : (address byte) = &s->data[s->length] 8b/copy 1/mod/*+disp8 0/rm32/eax . . . 1/r32/ecx 4/disp8 . # copy *(eax+4) to eax 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 8/disp8 . # copy eax+ecx+8 to ecx # s->top = 0 c7 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm32 # copy to *eax - # eax = s->data + # var curr/eax : (address byte) = s->data 81 0/subop/add 3/mod/direct 0/rm32/eax . . . . . 8/imm32 # add to eax $clear-stack:loop: - # if (eax >= ecx) break + # if (curr >= max) break 39/compare 3/mod/direct 0/rm32/eax . . . 1/r32/ecx . . # compare eax with ecx 73/jump-if-greater-or-equal-unsigned $clear-stack:end/disp8 - # *eax = 0 + # *curr = 0 c6 0/subop/copy 0/mod/direct 0/rm32/eax . . . . . 0/imm8 # copy byte to *eax - # ++eax + # ++curr 40/increment-eax eb/jump $clear-stack:loop/disp8 $clear-stack:end: @@ -343,7 +343,7 @@ top: # s : (address stack) -> n/eax : int # if (s->top <= 0) abort 81 7/subop/compare 0/mod/indirect 6/rm32/esi . . . . . 0/imm32 # compare *esi 7e/jump-if-lesser-or-equal $top:abort/disp8 - # eax = s->data[s->top - 4] + # n = s->data[s->top - 4] 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 81 5/subop/subtract 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # subtract from ecx 8b/copy 1/mod/*+disp8 4/rm32/sib 6/base/esi 1/index/ecx . 0/r32/eax 8/disp8 . # copy *(esi+ecx+8) to eax diff --git a/apps/assort b/apps/assort index 05e615a79a1cddcfb73a0d50a2fa2001c2dd89d5..b8cba438b3aed666003c6bb5116ee4e239756e04 100755 GIT binary patch literal 42800 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 lj6x@RC@zK?k?start + # . var start/esi : (address byte) = word-slice->start 8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *ecx to esi - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL - # . if (eax == '#') continue + # . if (c == '#') continue 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $read-segments:loop/disp32 $read-segments:check-for-segment-header: @@ -664,8 +666,8 @@ $read-segments:check-for-segment-header: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto check3 - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto check3 + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $read-segments:regular-line/disp32 # segment-name = next-word-or-string(line) # . . push args @@ -715,7 +717,7 @@ $read-segments:check-for-segment-header: #? # . . discard args #? 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp #? # }}} - # segment-slot/eax = leaky-get-or-insert-slice(table, segment-name, row-size=8) + # var segment-slot/eax : (address handle stream byte) = leaky-get-or-insert-slice(table, segment-name, row-size=8) # . . push args 68/push 8/imm32/row-size 52/push-edx @@ -841,10 +843,10 @@ $read-segments:end: 5d/pop-to-ebp c3/return -write-segments: # out : (address buffered-file), table : (address stream {string, (address stream byte)}) +write-segments: # out : (address buffered-file), table : (address stream {string_key, (handle stream byte)}) # pseudocode: # var curr = table->data - # var max = table->data + table->write + # var max = &table->data[table->write] # while curr < max # stream = table[i].stream # write-stream-data(out, stream) @@ -860,17 +862,17 @@ write-segments: # out : (address buffered-file), table : (address stream {strin 56/push-esi # esi = table 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # write/edx = table->write + # var write/edx : int = table->write 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx - # curr/esi = table->data + # var curr/esi : (address byte) = table->data 81 0/subop/add 3/mod/direct 6/rm32/esi . . . . . 0xc/imm32 # add to eax - # max/edx = curr + write + # var max/edx : (address byte) = curr + write 01/add 3/mod/direct 2/rm32/edx . . . 6/r32/esi . . # add esi to edx $write-segments:loop: # if (curr >= max) break 39/compare 3/mod/direct 6/rm32/esi . . . 2/r32/edx . . # compare esi with edx 73/jump-if-greater-or-equal-unsigned $write-segments:break/disp8 - # stream/eax = table[i].stream + # var stream/eax : (address stream byte) = table[i].stream 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 4/disp8 . # copy *(esi+4) to eax # write-stream-data(out, stream) # . . push args diff --git a/apps/braces b/apps/braces index 7307be115a295e50f9f37238e0618cd5a5574bfb..ef7eb54af84264509f4728bb8df623ebe91403c2 100755 GIT binary patch literal 42816 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

+7l`0nEOuDx>WL6G>-~l_rHb zB`eOxOSueJ8KDRXMZ*>KRREqeS)kZPJOi3ankcKoti=m+C!3rwZks2uZmXIR)uXtgJrP8(S&0PVFV)u z-%@SF3CP!lkvSrUY+$m)$PPTP$NQ0=!{z>Hji3AR0~9sVifw#b5e>%(9hJ##InD-e zq#7Vhnv7vN1;yfczb!rlhFx(r9~Y$(T8N4p$Eb6|GR+#OsH%_9qyUZrbt&?jkR||5 zrn1T7M}Q@5U8&RX9o(y*o&YwK9_?=(+9pJfZS2{}UK*~e z;SkC{wGC>9MsQsqr!7d+Y_`}%T$P5YrV8ZX-h~_?=%eJ!P` zaKs(=bXQzsouEX)u7Eom3ECzbj2tOhU3e)e;A$BJ9hGKSGg4hW-XE#FG)%K#jlU{X zw=|qS#VV~8&L|PuZ8F5M*~YyrHkcdMW`wgMp~e0*!ZxGID-(j8}ORuY6HrR zB5z7CMPxWk>;|xHcC(PATu>9hP76}4YxUp+<~^MgiNJcpr1;mNJsw+Pv=UUCHUP6t zK~^wfMg=S=+lm}3I0Isk8e+0;wrvXmO$9gaG+;+h)N(w%hRSGGHc%m!Eh{8r3gKvs z(sXNJ3HfaET{51m1CcnHr(++;w%L`8Psy;7c1UcD1^;qCN$rS4tFFjWCNCDXY*0H8 z0(lr;qA+A>?B%JUx-E7sz{YFi!xoMfC|PV7aB#8EoaQW{shz8J$xGpGD<2(*7!iJd zsMI!Ycx4%_Sr(=Y%qFr?u)d{LPH(G~)H^I$P2#o?wt!UB)hrJfR%1ScTcKqIB$hVE zxYASH{r(>V9V)d|(!8mINQ{ULDhg(VMyT{OtDr7Ww53%YX7$rUrS_qMjU+os+SQ}| zA70MD!}JSG{H>6$u8B%P07{Ot+14V76_lkBf)8m2J_abbDlUQ4u?@gF>ZcgQ)zgNRCsHFKm0hw(P_b3LxxT3<~*62W79mG}+h!CQ!Mw zx~7hnZ5+N48{NT48o1&Jffo*9KDI*?i!724m9(MSu$@tIP&*hINL@&v9RHw@!7DlJ z478Osb<3!vLUvkSN!vqQY1-^+OVu_pjlj0r&UVn^1}v2mMzk3uIebjr3{Dc+P!eMh z{%=(~8EbO$l~QUtVU0M0(1s&yk|h>JWm#1XEi`cmSZ(vPy_CV&NP>q_#K2!VoT6z0 zJ*cVJ6<(_45?IMYF^Qc6U3gyd$JOr>@plaZyP52@NGoa>ZnEirRy+7hH`zy6Ct=6Z zvi9g8X;@v203k=0+opV@+)$?nCKP5*>&8!cxU6z{sLD}r*k(-^@D!p_U`s|WKmlwT z05ZoGe{PVnOypgT2&R$T9NSdrhGp&|06b7&Ghkcb0S7ls2!Y%jSO}$)ZAXEt5el7h zqjE~Fj>JnEa`2?zKiD6#oj6MZw6YQ#^DDKQsxS`Ums4?TkhNun6QU3^+mJ~{u$Jq* zgGTQu3Wx6KM$hv54M=mLR1!oqai+Q!g5Z;Om-Q3XkX&mK;_~tlwAtYkS#E5 zpd$7I)uH9QV@3#qdYNr*v7tz3K_Un)k;;eAlN|Q$NGu!TBY(7w1?|l7rVfiDw#$so zE3m*$-e~7mr3Ky$Jj-SwF#J||>>T7q8-gu6C*L+A?4Z^~3~ffLjX&BAwZ%yrXf<@b zgNG7a2+?e*t#w3+LpSKg+hUz?szS6ocg}eD0a_4iXrS;kxWxsF|O`V1c~W!60Ns7zFWCATPV3re;tpM8!_GIm{F$Sgl%psm-E77COii z^1zn_;x|6Chb6O+uy!_xX~N9*izHB1o=s1-5OlB-=v2J2(?n9njE8v!xPIHtDm#Hr zabThG{-t5cYRkf_{ZtYA`F6y37P+jZoHGj23sk^!CVfiN6Jj=JVL&9k$wdG#b#sZ? zP9C;$n0N?u#i^C|xd>o@*VNH+BNDD7t)ijQs<6K@;->@5D!!ftC2T&kVPxmD@h-QG zcX_6P%+EGp^V@hgx{Y^ZOxpN_$=iS(+s3=I+ITn4q&=K?&}q%G)d8DWNk38%^HwE?3Wo-vU89SBjKee#rU!e z3E#RbCT;W6mN}M(R+okm-Pt*<^yjwHFXIh#VU1Sc@=d%OE{LTE<=G)vh-zG`a zCUibBWrS{-QC!dwRg{h{aP^FjNg}kis8Z)7wye%5T+!hO1wU|2iaD{oGEytc)ZDRV zSMFH&D`!<6%Ghy!`dOw2TxPAOBm0$=&fbh@BTu~oLqlSo{(QgRCblc#Rdn0JvQupv;o|FVGUU>mDq+n91;GTv`pb{C(3 zsQUuEZ9xnEBbtWzwp}3?@!bVtrN*_FuggOJB*LXlQS9?_KJ}l-S5gjRC$fr8FY2%* z#4FKui{iv4-*8A8`?IUgX|GNOA#oBawucQ_3jZq-B#q# z$#$}puILp)*)$R_lr*iqWHB(hOfgW>(Q-|rk;_8hOC)R*wwJG$&cvJ*SO6l6dGWp0)+3E!l0G}-}v1?pd zNZG5boC<_o+a6k^zLahs;Ts4M+E0i?=wmr{QLw!i2}HHJn);>udsQq1{ONw8co`iD z`UP_yZ&b_pnXh0-(T7Fk5J|dO;R9^Xi E0Je9&MgRZ+ literal 42826 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 *(ebp+8) 6/r32/esi - # var line/ecx : (stream byte 512) + # var line/ecx : (ref stream byte 512) 81 5/subop/subtract %esp 0x200/imm32 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/<- %ecx 4/r32/esp - # var label-stack/edx : (stack int 32) + # var label-stack/edx : (ref stack int 32) 81 5/subop/subtract %esp 0x80/imm32 68/push 0x80/imm32/length 68/push 0/imm32/top 89/<- %edx 4/r32/esp - # next-label-id/ebx = 1 + # var next-label-id/ebx : int = 1 c7 0/subop/copy %ebx 1/imm32 - # var word-slice/edi = {0, 0} + # var word-slice/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %edi 4/r32/esp @@ -201,8 +201,8 @@ $subx-braces:check-for-break: # if (!slice-starts-with?(word-slice, "break/")) goto next check # . eax = slice-starts-with?(word-slice, "break/") (slice-starts-with? %edi "break/") - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-braces:check-for-loop/disp8 $subx-braces:emit-break: (top %edx) @@ -217,8 +217,8 @@ $subx-braces:check-for-loop: # if (!slice-starts-with?(word-slice, "loop/")) emit word # . eax = slice-starts-with?(word-slice, "loop/") (slice-starts-with? %edi "loop/") - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-braces:emit-word-slice/disp8 $subx-braces:emit-loop: (top %edx) diff --git a/apps/calls b/apps/calls index 418d230e0da0ec505878c13a85ec9a0c1573271b..15bbc5db4a6dcb245660e4a9bd2cca4da7fb9d31 100755 GIT binary patch literal 47526 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 literal 47536 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 CQ?%Rw diff --git a/apps/calls.subx b/apps/calls.subx index 28e2ff63..030509ed 100644 --- a/apps/calls.subx +++ b/apps/calls.subx @@ -51,8 +51,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-calls-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -77,8 +77,8 @@ $subx-calls-main:end: subx-calls: # in : (address buffered-file), out : (address buffered-file) # pseudocode: - # var line : (stream byte 512) - # var words : (stream slice 16) # at most function name and 15 args + # var line : (ref stream byte 512) + # var words : (ref stream slice 16) # at most function name and 15 args # while true # clear-stream(line) # read-line-buffered(in, line) @@ -105,13 +105,13 @@ subx-calls: # in : (address buffered-file), out : (address buffered-file) 51/push-ecx 52/push-edx 56/push-esi - # var line/esi : (address stream byte) = stream(512) + # var line/esi : (ref stream byte 512) 81 5/subop/subtract %esp 0x200/imm32 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/<- %esi 4/r32/esp - # var words/edx : (address stream slice) = stream(16, 8) + # var words/edx : (ref stream slice 128) # 16 rows * 8 bytes/row 81 5/subop/subtract %esp 0x80/imm32 68/push 0x80/imm32/length 68/push 0/imm32/read @@ -233,7 +233,7 @@ $subx-calls:end: parse-line: # line : (address stream byte), words : (address stream slice) # pseudocode: - # var word-slice : (address slice) + # var word-slice : (ref slice) # while true # word-slice = next-word-string-or-expression-without-metadata(line) # if slice-empty?(word-slice) @@ -246,7 +246,7 @@ parse-line: # line : (address stream byte), words : (address stream slice) 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx - # var word-slice/ecx : (address slice) = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -268,8 +268,8 @@ $parse-line:check1: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $parse-line:end/disp32 #? # dump word-slice {{{ #? # . write(2/stderr, "w: ") @@ -381,9 +381,9 @@ emit-call: # out : (address buffered-file), words : (address stream slice) 8b/-> *esi 1/r32/ecx 81 5/subop/subtract %ecx 8/imm32 0f 8c/jump-if-lesser $emit-call:error1/disp32 - # curr/ecx = &words->data[words->write-8] + # var curr/ecx : (address slice) = &words->data[words->write-8] 8d/copy-address *(esi+ecx+0xc) 1/r32/ecx - # min/edx = words->data + # var min/edx : (address byte) = words->data 8d/copy-address *(esi+0xc) 2/r32/edx # - emit pushes $emit-call:push-loop: @@ -391,15 +391,15 @@ $emit-call:push-loop: 39/compare %ecx 2/r32/edx 0f 8e/jump-if-lesser-or-equal $emit-call:call-instruction/disp32 # if (*curr->start in '%' '*') goto push-rm32 - # . eax = curr->start + # . var start/eax : (address byte) = curr->start 8b/-> *ecx 0/r32/eax - # . eax = (byte)*eax + # . var c/eax : byte = *eax 8b/-> *eax 0/r32/eax 81 4/subop/and %eax 0xff/imm32 - # . if (eax == '%') goto push-rm32 + # . if (c == '%') goto push-rm32 3d/compare-eax-and 0x25/imm32/percent 74/jump-if-equal $emit-call:push-rm32/disp8 - # . if (eax == '*') goto push-rm32 + # . if (c == '*') goto push-rm32 3d/compare-eax-and 0x2a/imm32/asterisk 74/jump-if-equal $emit-call:push-rm32/disp8 $emit-call:push-imm32: @@ -741,7 +741,7 @@ test-subx-calls-processes-calls: 5d/pop-to-ebp c3/return -next-word-string-or-expression-without-metadata: # line : (address stream), out : (address slice) +next-word-string-or-expression-without-metadata: # line : (address stream byte), out : (address slice) # pseudocode: # skip-chars-matching(line, ' ') # if line->read >= line->write # end of line @@ -830,7 +830,7 @@ $next-word-string-or-expression-without-metadata:check-for-comment: 8d/copy-address *(esi+ecx+0xc) 0/r32/eax 89/<- *edi 0/r32/eax # if (line->data[line->read] != '#') goto next check - # . eax = line->data[line->read] + # . var eax : byte = line->data[line->read] 31/xor %eax 0/r32/eax 8a/copy-byte *(esi+ecx+0xc) 0/r32/AL # . if (eax != '#') goto next check @@ -1191,7 +1191,7 @@ test-next-word-string-or-expression-without-metadata: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1264,7 +1264,7 @@ test-next-word-string-or-expression-without-metadata-returns-whole-comment: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1337,7 +1337,7 @@ test-next-word-string-or-expression-without-metadata-returns-empty-slice-on-eof: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1379,7 +1379,7 @@ test-next-word-string-or-expression-without-metadata-returns-string-literal: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1442,7 +1442,7 @@ test-next-word-string-or-expression-without-metadata-returns-string-with-escapes e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1505,7 +1505,7 @@ test-next-word-string-or-expression-without-metadata-returns-whole-expression: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1568,7 +1568,7 @@ test-next-word-string-or-expression-without-metadata-returns-eol-on-trailing-clo e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1623,7 +1623,7 @@ test-next-word-string-or-expression-without-metadata-handles-comment-after-trail e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1678,7 +1678,7 @@ test-next-word-string-or-expression-without-metadata-handles-newline-after-trail e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1733,7 +1733,7 @@ test-next-word-string-or-expression-without-metadata-stops-at-close-paren: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp diff --git a/apps/crenshaw2-1 b/apps/crenshaw2-1 index 7103908f39ee7941d11d57b316939004571941a4..a579ee456fab811169d1a5843dfc5d5530aeac27 100755 GIT binary patch literal 42208 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

0~=m;A(_Ir_!jLGOHsoNK+1;3{IUt#IT163 z74V^bi)#awo4ZJ1IY1+}z_5Xe*bml5R`7`#AqeUfwzb8EBAo?^Ah<-T970cW+PfpM zY>1DNQ8pHIGRKEHEQ&ZTGY+r70w;N+oJW-wcr)-UhlRihSmm*EkOyrDw!)$k+l;V- zS~oFt7^x2a=rq(8C+(os(e)0VN^l`Wv!%AS5hV`Ynj3G6b;7BM(COTHeGw z;-uT0W(pIm)~vnKW>Fyvy~q>tz?TFPFg^><%w!>9?Q9U!gjpC6NuZ*#ke+NI=wKz# zsd#0liKL7b59Wz+Y#eg)2sgHa zaMF1=pb|5W<^oF3Hs?387$rY1ePCwTQl{Z};1?EI01OF}qt1}8$ zba;h=zi>^8HL{nM;#_1nvHev9l zZWN%4>EHWq8{7bq&?O^J2wgG~3nIl!A%q=gt7aU+NFZ!C&4=PKwi2NYl;SZ~oRX0p z!71U3bfZSwYCZ@3QKJKA)z$^fI%Jrw)|1s0-~EM}Ma6-lk%6L;0CK(9Tha?k$EMM? zagspBO9#X(s)sY^Q#wrmq0*CQ;&O9lmMXYqV>@w$Cb+ijd|x6i;Mz_&T|m_>SXRzf zrAlyh_c&&&xJ>|h31|fo55_fD#Bp(8WT3>Bdc@mwW{GP=WIVpUYICOxj8L*;Q1DX# zoC76+fK6;y!fWWZh2^B$Hp9jJaUm@$CzXO5u}L0pb)(vUa$dzdqC(@{uyNSNuN7&} zYrI_@d;)A^S8SV8E=LdEg0AeOPjFW69Tj`2kA(TxcF`%SrYmmjj>@vkbNk`i?jb<(j zfiID;VQi&HJ;3PY09~21?f9r$}QxMM@#zCe0KX-KMlVdrc66@CXbfxHUz@OWtqAx2u}`Nz42+jq z7uVG-NAY1?%EX!V*e)}7ZtU*N^tq>oT;-g%A#OishTztf;`Khw{{{W!a B`zQba literal 42218 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 ZQXxJn#YegLh&J$8x%i0I@Ka^Y{{a$+6}$id diff --git a/apps/crenshaw2-1.subx b/apps/crenshaw2-1.subx index 2217e430..228f4696 100644 --- a/apps/crenshaw2-1.subx +++ b/apps/crenshaw2-1.subx @@ -57,8 +57,8 @@ Entry: # run tests if necessary, call 'compile' if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $run-main/disp8 # run-tests() e8/call run-tests/disp32 @@ -67,7 +67,7 @@ Entry: # run tests if necessary, call 'compile' if not eb/jump $main:end/disp8 $run-main: # - otherwise read a program from stdin and emit its translation to stdout - # var ed/eax : exit-descriptor + # var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # configure ed to really exit() @@ -90,7 +90,7 @@ $main:end: cd/syscall 0x80/imm8 # the main entry point -compile: # in : (address buffered-file), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor) +compile: # in : (address buffered-file), out : fd or (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -105,7 +105,7 @@ compile: # in : (address buffered-file), out : fd or (address stream), err : fd e8/call get-char/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var num/ecx : (address stream) on the stack + # var num/ecx : (ref stream byte 7) # Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes. # Sizing the stream just right buys us overflow-handling for free inside 'get-num'. # Add 12 bytes for 'read', 'write' and 'length' fields, for a total of 19 bytes, or 0x13 in hex. @@ -187,10 +187,11 @@ $compile:end: 5d/pop-to-ebp c3/return -# Read a single digit into 'out'. Abort if there are none, or if there is no space in 'out'. -# Input comes from the global variable 'Look', and we leave the next byte from -# 'in' into it on exit. -get-num: # in : (address buffered-file), out : (address stream), err : fd or (address stream), ed : (address exit-descriptor) +# Read a single digit into 'out'. Abort if there are none, or if there is no +# space in 'out'. +# Input comes from the global variable 'Look' (first byte) and the argument +# 'in' (rest). We leave the next byte from 'in' into 'Look' on exit. +get-num: # in : (address buffered-file), out : (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor) # pseudocode: # if (!is-digit?(Look)) expected(ed, err, "integer") # if out->write >= out->length @@ -221,8 +222,8 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a e8/call is-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) - 3d/compare-eax-and 0/imm32 + # . if (eax == false) + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $get-num:main/disp8 # . expected(ed, err, "integer") # . . push args @@ -251,6 +252,7 @@ $get-num:main: 8b/copy 0/mod/indirect 7/rm32/edi . . . 1/r32/ecx . . # copy *edi to ecx # edx = out->length 8b/copy 1/mod/*+disp8 7/rm32/edi . . . 2/r32/edx 8/disp8 . # copy *(edi+8) to edx +$get-num:loop: # if (out->write >= out->length) error 39/compare 3/mod/direct 2/rm32/edx . . . 1/r32/ecx . . # compare edx with ecx 7d/jump-if-lesser $get-num:stage2/disp8 @@ -337,7 +339,7 @@ test-get-num-reads-single-digit: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : exit-descriptor + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -426,7 +428,7 @@ test-get-num-aborts-on-non-digit-in-Look: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : (address exit-descriptor) + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -468,7 +470,7 @@ test-get-num-aborts-on-non-digit-in-Look: ## helpers # write(f, "Error: "+s+" expected\n") then stop(ed, 1) -expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) +expected: # ed : (address exit-descriptor), f : fd or (address stream byte), s : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -488,7 +490,7 @@ expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (ad e8/call write/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # write(f, " expected") + # write(f, " expected\n") # . . push args 68/push " expected\n"/imm32 ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 0xc/disp8 . # push *(ebp+12) diff --git a/apps/crenshaw2-1b b/apps/crenshaw2-1b index 31b9cac194855dc78cb48c9962c06529dd00fcc3..a398a0bc1591b60b5de6cfe519ffd367303cacf6 100755 GIT binary patch literal 42755 zcmeHwd3;pW`S%2dWC#NRL;@%<0)j|~B!n#>g<;iJa0V1mP@E(aZc0c(X2Q}EG;OsE zW31Y`TeY@zskODPL*3XEa7PqD#e(a#K>@8*-10u(=iGbFy?1Ux?C<@2-amdXEoZpr zKKt{W=R9Yb@sb&5&&MD;1 ze>>rQcMs!tT29YhJ-PV%U5UqozuCt7Gzh$KX}TkSY)yNOPvF0B>DDyh@aZ!?bB)iT z#^(j%^D+AH7_`nyz8{XvotL`MmzwQw+zg7T^Zcov2JJ}z&AS2w7hQ1v!sMX~w?5WF z4+geY-_w(;L0xY2p7gKAZGLJqc+5-9@TD&Fm+Y<2*RBB;jG{NRw6rvC1Nr8H)a>pN z(YsXkYA}Q7oGUw9I^|ODA|Z}`<5Cj2KYEl(q|y8ZsRkdblB)MNJ_E%z(qB&+4NF(D ztD)D1oDBn5$3$O}?8MNlna%o!9PX*lVS3G-7-Pvrq(9Wxu7~h_h@Ji$DUo(FI^mtL z-i>=Q_>P+!3IK7qRXg6>2`w?8@s-A632VF{b3U>BfM(A{8x z-5_D#=xfDOijveXEH18sgMg5kToAb%{^}bYtKh>=y zuYS02e%8^(?FfRRO+~MiycqXy$lj1&@^XEbnX{UY*d1;7c|24(gBtyAW#cL66#f|c zt@2$Jy5oRdt6*25lQ@!}zxqbO-i7YJ0yeB*A4aF3`=SN*b#%WC*dYq`eRK-CcPLm4 zpMs#?Nn(0bJiXjY9nBhP-(7*AzNzw`n0c2xBZ%>-kM2i9Vkr)rSXc=S$IB8J zFUS*^5iVy*s-{mP^HXfbRJWFu-jX@qhDn4wU*APRD@Yn?biV!yW%kBxpeI@}x_Zyo zH_8{yPyTwQm-8y;)J(GuqbW{HLivL{%vkwf<9UTL>$Nb37&JE?JFY!nCGOe-AaSK4 zna1-v_538BMFwY<+Z2nj$7ituEItE?5sKt7JU=E~p|#-oUiI9mx8c&TzWdALYS9fW zCKHOjgGV$=Im0AjM6Op)N=n*q0X$LhyD0;Bu>>~4oFYSv#`FA5b>38mCVw_frcF!y zshp->9aFQsO=onZ96EqKSn_)ObV{mkVk#}!%U$(-X&!yMXcNt(2ssXbgmWH!6>^+M zV^VKom-+}&J7@|Q)}Q&pG{#n~OTGykRj_&JBqYkOH(6jyBZ3DosP~d5RqsB|)4TImKz}0x4#Df+bjNu(g&FG#& zD)&a3&h$o%EYO7j8n@9T?BT&@I-5Ob)J*l=Q?q-Khr5z`K&LN$g2DAS60rGnt~h7=Qaw`V`{;Gk;=ai8Jt)i1Vy!VZ zWMxV7T@8C&%)^h(_X)Uj=WmtQ{*BI1DT#nL$g!6(M^Ricbbm#nYaf$DM3LwzJI_#^ z`RJTB-9k60=(6oZwUOO)ZZ_4KU`LflNltw~S#Rtt*%Lp3>W#dT9ra$WHwef>g(WPu zyMAFxhh1 zIZTmVhE50@*2lS%-N_?_rA0!XdRi(lOlkG9>|Cvk^*TC*4|1iTHXq!g$ad*Vz#Nq?a~@}7^_HEdD6;+0DSYtY zrw(HY3NsYhd6L2!MRtkod{!D&tB{=!tIp-<6e`Se=e3W6pDlB%q|jCIx<_`3bp`8n zzwA6q@p@G8dh@8OUdt6PT~f$V6b>m0H%bcH(0-<6-%<`c9i2k4Y6+@}ATFElli(`i zLK4`FxG*JE{}+3krg!oq%V%v5!5AJ<$EKza@ivafbA6Z8;vqgG9j4A6;tM6u^riwR zy4acABoAmn4(orE?hfmxP|rfG0sm`aAfzTc}3yGJ}=giT!F*&%bdAwXhWj9UF_J>n5z2bA0uW5P?J?HR;PP-GvWRjJW zHPgG~B7^k*m8qw5=G0@%R=~fDdLAK}Om}0lTaF8hd7f0A zML;LxQ5^UD#54~Aot6x=kelP1ILEs-*ff)>oSS(#!6rpJ!!2X=)sl+2b&YSAZL-~jP;a}Oe9=ie$iA9!!{Z1xfx%iyi z4AVk8Yw;;OTF4`nt=J=v0wJKDXMg~Ap39W6~1^F{T-Xg_$k)6v0E~b?`=mk~N`X!PI&12}O zmL0rbg04lX%bXXcP!=?kH#_zm@5FQbYx^(IhqKe6Wz#Gg#Cv$~;IU{Y4b&O__0#jZ zx6JY`F_#mVB7MBzDAdz(go_zc*zGrxgc!=dP|t`$5ub782aeY}_?eA;A8hcdG{n>F zMoXn%tmyIB7_6T60gF2q@La%tp)F*C>37Q7%rvN&z6;D={i)$#2rH(@b!@V{iRbtl zdYDG>x8w+$Xaj-8A$x`1ddN2L&|?MJ3e4tqWrazgvRDf668q3}Kh{(Qe@gWRuXaQM+&qN*`KfIM3v>Ojg%Y zh7$ALIr5!FhA~P8w&bbmnPp;6H7S|+c{)>K!KXpIGAZLyt`ww8}6AAv{nE7o-I%a5ed{(R$l!)RA20c#-3ucSbG zc(Qg1bgd!K5ydJ~Ade|fZ!XtZY!`t(<59}SU<@S)*riH9e(t~|8R=%o`nVMM zRGYvwP-*3mig;6<#Rl50_}R35*0=HNAX%n9DkZ?eieftbEQugCfI300NSMxF^ffFu%lR@y#5f7-3*IwFk1+|P zKXgMrLm_{nko#pIpE%HkbBjzq+R5}@BgVve|GQ4kGu@CaWzlSfe7h5wiE;y7n-s^D z3Tc@WDg7Haj$ws-GmwR$MrI&yb3;BsAwRE>kG|v7_1|vDdsN!|Rv|y+L`KRldeaQ1 zqW@3^&zi(RlpT5!($XV`Q4bMDc&(x+Z$p;8hbE=X?|QSg(xzqOckoA|!xwKR_nNCH z1W`f2#g*$+9E_&-8WIcD|4s?hi`KcY|$>#rSj+Gf2QvR5Hr1!SBZhV>gV zkRNhG-mbi|5y;RutS`zy-s^@ePE~o}ybWZMnve%%AZMN8VzAkYvya|u9Zk+Q-`sKC>BWt)UR(;))@gd)JHP@ zRI=Hsfwq2)0-FXf5!&-4m!1e6IB+ z>08E}0v&E)$3RW}!kKQz=SV17$t@kv^G}R;5#GQOZqjZ8Ds>XU z>m{c4tjUH5UMjoIwGG(~mgyue%CH>_X6RJrFmu!0R+YJK`r*>4zz77)f>I$xd0pSZx+a5lDX zhVs_U0UlbATWsAt!R0yB681ZRCLh|fSwB7BADYU0@AXe4=lGKOIN%V)={BkAPFx9t?MDtGAP{SLg6;1@RY^Tio$`{9a^w#+|UfNgE22tm@g^JJDr&6kLjgjwWEE;6s9Q( zUnmOYP6{^O{f5H!ofYN)>M(47x)U=!i(Wc;!^#nT`?qow%?1Twdwq{XZ?S!Y{c`UJ z+Pk5QQ1a|0LsMgoQ)Jp{D|(Y|EOw=HLE(HC3Kuhlq@u7C6ogwM85B}36s}&?7u=Zr0{V<0k&MzK?6A?$p1~%-C8X7_xshzG4z_`Uf#3 zQrSCmHQWN%0~{Sb>QB#g(RHqVw$k%_0to9PB!+e|Sc>s_5A(E4X5ok^-WssuKVLtK zn2D*I@<|ijhDhdc|6R0ZwfED${Y9calMecvSweLdUTAPoTMPDV;{I$8Xc5r@0OQ`3 zEIMS;ehE;N^r@^y9WTTB7rRWiXm{W(tVuVh%-4J6YjbvHnm=(B#md#AxIRgATUL0f z>fhj`MuTtxU2spG*FDwHYcBi#C#0ZJ59G{^g!N_e?r4&1V$`f;lk`3!Yf0@En|!!{ z)hA?8JwPYzAhbhZr1D1Wi0CaZOTBZ4(;JvIb&eOW-jlCPo#~wsFa~MGOdrdNGK(S* z0xSsSMf97UgwhKL;&?K@&-sf9E^!e2k&_@NF+R=prUuZh`jUMOT}6>fcc|&c+hHnA z)d?ND?r*!HI7iWCAkUreay^B}u>{U7D(0yI7REDfae4KpUNY@xl890}D-ocP zaD~O{JpqZ3mDV{+$swQ*@`z%o$4a^8Q9!^=R`6e<}kVn_zD@_tcGI2-yjehuyk`o!LDqI=`lo$={w{8|ivDb2eV@%k%W zK!hz)lfafepK(^MpFSrA23J>uB&-HmW+!c?TZ=*JKp&GLw7N#oPv7Q_YB9*2K*c65 zP#0KG_qwB=rEK{&PzjS!PgbZIwk)>V@+8BSCm6QuB5VnbOJ1u)-LHi5s}Y07ENa?Ic=9vh5vgXFr6b2|_GKW1=!SQ0Yi zR$TXHa9uBfZCv{)t}T-59L3cibm}@;5)xdm;xxo^hX9QIG-;Tg64=J|k385IrxG}9 zfW5M8WOVup4KlEJH$pL44Fp(3GP!Su!=M;Pv^jE~zi1QAc}}ELoWZ+u%B<2H`L}r<z0pFHy3`<|Y** z8%L=jx}y6q|UkAb;;qz1|WJG zI%zm%#$HB#)7km7J>Y9vJkY;TETVJi3o$*`XVGQ*PiVKAvX0pO{~bg?iqqF`HO*pO zFpGL{4UZlc9OZ`SoUgRo3M%iS;qvP_RmF>r5`|Cb27YgauLHGfk%^yj;veIvW&Ugu z=CVhXo;`s&RpS5HiN8_de?eS@P}eE^Gl9B7;&*Z4uTl8_k@)i!{wko}FY%vKbvoC* z#wLKD3nhf$luu1t(+%#4*=zH*V~~2b&w`4c<}>8>fU)Aio_KvXaif#g!O5B4=02cv zr#xFUF#W8J0rLP~LwQ;N;XzMfGTQcRL;v|_yNVV7cnd~K8B{%w%mX$wPbakGTS za5+d4MJP4`*Lo=1*^Vj9bE5fP2ID44+XFc6pG$YB2OI_hOk?(~^6H&cr~cFjrX)N* z>&c(~1$yC!=!FQPH>Y_MpG=58%eRu!*O7#_gq-|9yMy}X>lZ2S-3v9u-c(no2I-wH z6m~I%lNE(Mpg`i#!NhYV`a6AsQu|Htj^C%fY?+x2O_k>gIbKQ`|$vPu1Qpi_kAYb8zT%|bw7RbV95hpSqJD%kw z7lm3T;kJw0@nd?E8waw0nE`ev@eV(3>Xv@j4Qsu^`j?Vxqr@_j3^wHW%JGHR)TC3! zT@6F#EzloTyTt(#c7Z-pt}-?^(+$DBYCh&_AeYA~n~*Dzubz@JV;E@nqTz}{$i;gQ z{M<`zG-Zz=`$bCwo-}CUtCzV_+^wSOxI@upKG&#cUiFNoUk(v`0<6E{^B1*2Gz@&s zM#Hkd#8W*W4JMNmQDzcU&&)(ABfgHUn9Nd4=7au9$>b+aCVM%smBn_bXJ$g;w+Kx{ zR!~gd;mV6KF9rSEC6i8y31)FVec^!Q#!U9~y?aXc1s}mfobL6z<&9HOc@3G5sd_x; zdmlX4jS56`y(Jec%>x$bTX+u(g3#?FzN2#Qw`Ne9>7Q#h5=NN%T^<%n>D}@<{b$m` zo>vd@D2@mt{D90MrZe%pp9>zQbU*ZeRvN*>l@H8i&ZF#QO|sJ1sSD+EdY21p_`qQO zcOK!&{-uib>)?7+vcAk&&5JQDJ;lLVZ1yrG z4P390tb4h$UMpD%t*hj7`sTJ-KmCne>y>Js=Pq!4U9!HB7ata_DU;$xN6}7fu{H>4h`biz0suQ&6~2oD|ZJ&Ai?bMy}8-X3a%kDv~w zJA6l2&u0FL#w3Oozd^*kGXUL(L;>_(+JJJFz2ucl^R0f%w8?SJ7hsyKzyk1M^L3G( zFdtv)%sFV16wf8RKH#`jmpXSpWCDF3bFN~gZy_a(B*@ZS!o8Qv-t@1iBh|g>-0oh! zr$0BGe23jJH=>LCQEaeZLkai}2D^*pL4W$L*0CQ{iRf>@HqBirv0IDQQ$)1>MMjau z+#@+!i#DaGmi5Jl(JV4oe}G3I)T14QWCywtnU$S^)C;W(h zj*7Pib^f| z4dR1T_Z8^An;Hn>|L~WEStlA3xGJn~d)xGoyDxi@Fv6Gr_`3<&zJZYr5o#;J zUZ8w?78sc37d+TPE6{J4{}0TXyKhAIW@=#mBQmMFaPmBi=ey-|Yx53~G`5P~VN=c3uYJ;_&i>OrBVi-@{I5;(&DENTwDvWu z#oBb32!MTTcUW7?r4AWAYyajz9D=uuID!%JW!&>cQGJ0{jF-q#Ep=W!BvBi;4WT~% z<%QN}_Wg44bsRs;=2Djhm`&VZ_6f4f@I#%v(kuPYTf%UK4L_u~8U`h&9|}2pC_e<` zb36Qyt|zfleVP{c5fjq9aPnQlH^;aVW!brDU<>}^n8U=E!HNKw7twdZyo*GJyFj}F zZ_I&x@IDhS{TJ%z=_1*&6A;2^ z5?4ZE(;RQ#Yhr7^LO+Beb8J`Le?s?GYG96Dazv(|qpnt%WhrL6fi27vmoyFYp!VnA zikzdq^Ds+&=i$&_AsWVz_|C)5f7q?ojW^AW?>sbbaeUq3C>V3ObN!!9JnIxG&IZ;? z9^y9SYW2+5^)>a}a}p8cE$&-*YJjCIUw05oZSFh?kU=y|<4>|;;GgBdEfoG$FdlB= zOQG1*7OIM{FmKjl|4SQ7lp=a9?>vA$4;lWMhWf?YWPUl%?d4?cEPgrG@e)R~5K`;;@9M$hz(EFz=dc8?67D*$zpg1Vle*aK@6)IR|AIi(R} zk^3}5fvi4HLFs^cNkM(iP|Pu?p!)rgpe);vr_pm*_&i5J%>mRe6s^S!#T*abEv5fC zpw!p%we<|e93PWVDsFl6kA9!;N8VJ=tY?ch(E>A{EkfT7UZB6xY|;%izi+wBC^j8> zahhOD@}7!UJ!f_3=;1?neAS3I`kL6F99H~%(v#A350Qx4OK5m6<9-=tQcU%$2)(c@ zn4afv%mLpe#-ZR_KxPlc?*dt{$s8l)JZ@RuXlYrwF$R=eUxLbsld0j+@d%e3C<~1% zgG1c#7c2Z&#Zpb6&QhKIL2src8dXGTQlQ;e^QbM=yClDUjQEjR^RhneBb-dXPlSv5 zCyDFE*7wZ^TD!Nek<9q!9Dlq+tG}z2JaZum!Xd2Rd#CAL!_eH%XWLffa}{y}kU=%9 zS7#vOz6Lu%kb&Wh-416jM6&!s#$S|3ecY+C&mgpR9IAKo@PPZZ7nH19{^U^9u)DvB zZbbH`u&1v?#7FaCCrNe#Uq@s{o2ma~v;S&d2Z?_1y`1J9$-SKXc=t0$*0;&+$v$i* zq8~{fY+C3o=@CCi(4jeLoMMngFUE=&VZBf>2zeuV=@xT@Bs&Uzbhekw5`oZsU-C;4 z=kn(iQ9HZ);5(Rt*JB>(%Wy>h8E>?)v2v!!sJQlz4r6J<@RHFjC!8bDNp|+M6zZiJ zDA+L;C|4?vL@X!;87S_euadlHNJ1p~Cb>3J#} z=jTPn%Ryvw+|8fEQG}5J7PEQLfG3lf{a~H%e3bF%;=x3K@?iZfXu|+0&ftiMi0H5s z1MdL}xbkYwvO7$3YlA}c(mZtssjxm@VHf#JJS@sz`u2(#+0u(ON;u{h|>ep_UD!+)gSjbxJ{)l{SQ|e52 zDRQToQq(%7=%J*@2b5ikb0iz>0=zxZE=8eyEk_N?$uqt5E3>}s1WRS)COFyUm%_!j zG{?|Ou}tbk|HAh*scbNcv4z^r;7R>7Q9XT|X^(|k8r>ip*8ghh-m9Rmw{(A_x-XU8 zQeOW4W;gl?>vf_g>E>(9h8K<7Sz2H^@#2kPQ8$CFcorMVfVI{rNZ-^YMy1dUk2Hl& zrH_dIs}|@1DhstAf;I?*^$%`U>Ya;jq25cD?&atPk+7b&bZOX**EkZa=zC|=yZN@$U-TNksCO4=u#%hPhPZg1$ZLyMm4rA#Nr1q8m$QC&(wwU7@MUS4TZsJ#ipobxUj~S-?9*6ut<3jCw$bY4he=Mj9 zgU_-_L@u`cg2DwHRFJ%}f&Zf&>xOA_2o?E!9pmAh*jVVQe@U{4|3F3a$i_o>lRO|s zidZU$s%talUgN)?frOj!-_HQ;YNBK;(hi*fItRChe7MgQ(L+2gp*8-|~_ete*FfWP->*oy_%6Wfdcb;m1i?AK=Q)Mb;I(CRWCtOO>REiVWE={#MF98H9`JJXacf z$&IZV`{P^iN-3~kJ+lHYsApE-3H4kl6*$V}l8XZO%LT6piK`J%%q>HK+rE(s#4{AQ z^#(Tu9w0aj@H)w!s%3OUWry~J0W(K+p&Uo1DJJ2}2@}sFxrl%%k~|R2GMo2G=|@5f z>CM`1^bh`>9kF`@eEkKIPX9NWlgQBeR5X=nu0r!DnrkS8^o?i^pvk$Jn#E|QlRfn$ znzzyHp?J}UP(bTHM{@wpBQ${Z{b;-T)-OYIA*D5aGbyi+qxjM{qgh9zLVpd-8Ds^09hw`cnAN{TGlF)V^~=$W zqn$eaWi%sbk5WH`W*OyIJ)iQCj9GKNHPrH20&?(OgDzu>J&^ z&(Q>Fiqm6geuoAJfcj`OYth__<^wc8OH=dQMr!{44{A<%j2c|$&=)*T&8ujwsL{~ehGq|%sV`FVAetdBQS)as2hsF-nVLp4*X*L^1vI`_sF{Xl9h&0Z z)I5Y{%&XM2pgH3;YSy561kGn?R_>wZuV_9%Gl1?>>GRQCiKZFN@AgvT*+DC`ZEEiNCpCu;Q1i$;)cpQEYKDA3P4$P=XgW2U zKBDHGe^E2+5H+u%>HaY_kD~b(nn9mX6GwB)VQLPc>34*hGtulrbIVa`CVWcGUNnO~ zqvj82&iOYrLq4Ylzc8ggh33&Osfiz>rr%f8?4f2W(gm)`a}gB4Q-LQ`T819}Lld)S z5dCeTKcXkIMQSwvnE%FSXe#}WiHo=9J3N{HX1Gu&luLgF6#sYB%ztKlnt09^)_xQU z=6ig(%kc+F{xAQ7<*I1{Wg$!sFb?}82W@h zu@&|?eS+IJ^ocbd{`954vAVjNxiple$r}YAQ(u* z;)!5c&GOo4T`X8#UsV-c7OSg{RR!aTy2|RM!Bv$BEf`x~n^+T!*40JVKnlv<dN7dUN zHLGf>mzubQ!hcSqHUn2U!{Qg=DZ??q`@wP0ls{~!2898x*z5!W9%sPvG6Nprlp$ng zHHVuKMMm%it76ql6Pmy;HSvXwv4tq9B>UJzrK(64!9%nd9}d8HS+qJ>QCSyHD8RCE{JX4tL@VI&WtFw@Ac)6<_0@^Ws$fM; zeKjM6N)?$<=~x#6v9g-#@*uN~C!%#UI#+2i8h|VVnW-WXtf{CFRDS$l;}_J{F{8>v zC5^y}Xk}G>oiN4f|6ZuhBu;5nR12UPYL%@zwmQKE2`-N&DDlK62dituzk?V;o_0fz zV$DPChA&1gdHhr!9>y-WTi=APRWY1@q~b&8dw>vs*mAt zMsl`52^uPM+fpvWRmLeoqKQ~VeHDPGO&2J(5zm085{0Y=CC!=&%92$^M$Z(pbPWx- z()x-DN~fmKg7%OMVePQX>#Gu#wN)|O&|n$ta5UkVLKwkF!M9X9{W#?7V#pkELpCs3 zVq^y%*b@TC&$04Aq9(xo_y-g<(u!?-TM-S%2pyHlZ8^>cZ=@O^Oq-5jIRnMwgn%tR z1cqI4H6Mqv2`x&+jbqfgVVPzPR#er;X;J`3fw~m=O-K_2rwM_Y`b40nA`q{o=|A@* zdMks=0%oZTLKylqZf*J65W*e;1|XOdJRF8&07>3~!^IU9&9S=WvGPg^Qz1P0h;=9r zAPZ0VZwS;^n8f-fG0B}L)t z!ou<6OG=_q0c(p73#=rZiBvoq=Sfmr8p0$c))p{s@#yGa_qRbUT3ud6RZ>+fK^Eoe zuXywd+fY}u#Daqgz)G4mmeLFqtpoWL#iLJcg*-c}ic*vbZ_73o$~?7W0xVoz9Bqx7 zDQw~DAXQHlm8*deB<*bJ!$Q?WsE#d-CMs9PP>KY>!B!Wyfk40pD~w*d6=_u#kC|pR z0zX(@xwO)>`5;1(9tahu0awc)=%_Tqnvv@234wU!Ph&I-)ebxUKpGpy2D;fxZY-6pfm z)K)_ASRx(}rEj3DhU{OKs9J*&##I0pw`OHAA%I6A9WC5>GbUP^TUKrxIhl9}k|-|^ z%gSvPVjzE1V@nyVy&@@v2H% zv5N(FqOLw>U%FUcRz$1fF{A~WhK&!~h%*Rby8*9ht~Q|DDDtKRQ$&Wt#BKoFW;Y8- z$^|t+?6e@&x>gTPVBXU?o(QZrOp5=uw8vvhj8=kb(*|I+DaZ;Y%&33`Wm}PB1!q7E zQbSDE&9-eJpv|2I?C6PFj;GgX8O_QDD#Ws7g-lE#9F0+$ZVfCUpKZR&#FKR(5-0O? z>;u_0yE5@98CKE`iH)(~UmhT-9g%3&6?B%JUx-E7s zz{YFi!xoMfC|PV7aB#8EoaQW{shz8J$xGpGD<2(*7!iR$wA40kcx9QWSr(%V%qFr? zu)d{LPQKMj>K&G>CUIK`TR0AC%}e>Pmc9hg*c=eKi!|mDR%ULMYo*+ZMRZ zthW6nH!LNW5blAKM{{MHb12O4?{`%+4q?s2z+9q%I^-VPH_y;FTG62HL8cx@A;SAv-Ovr0pTD zG;MaZrD~g)MqpcQXFF(d1D47OBiam-89t_N1}BMZD2Xu$|F^20j5WFWN+~s$uueaX z(1s&yG9?y8Wm#1XEi`cmSZ(vPy_CV&$bg4Z#2`>QoT6zWJ*cVJ6<(_45?Gl-F@v20 zU3gyd$HnpE@plaZyP52@NGoa>ZnEh=t{wcPo9rX3ldxlHS$lMlG_0;hfRLlhZBxEc zZm81(6AH7Zb>pWzR#v$@TIDD>Y_p~dcotD9u_YrHpddC409j~@KQ~BOCh{&v9Mecq zp=~O3!!maf03Ix{8L%zzpo1GGgkVu2EQHd@wxht+2!&3$Q8{H+N8%+7Ie0P<7#xV& zPMjqHT3LyW`Bhp?RSbvk%c;0E$l9{PaZ!kwZOCLISj%s}7}|_f8-KJLYKxOL&}!&<2M;B<5Te;qTkD7thi=VH zu*EvzR7GibZt?{90a_4qp&yekYU7>tLvAS#_9@+pk{F)g9S&m z4hA7BVjzfr1xFQB)YJ@Wg{au+HiwzQ1gq6+ermI*kcAHNggo#ifdq`tf}xo#B&?kc zVwx}u0wM{Nl^4*HEd(8`1UeP3>@<;-G2>yL0dByyv&v4OQyf@mLSSi(vf8rPngCVA z0lpnEfkiH>Dd&uW^a2&|+>Jh^=?SrbvoIhs-V`AKn7X;dY$p#}IZQkRy5iKz`yvD| zz-#Jgxe<@mkyeRlX;myx84u6_W))w_f)X~L*)R$U+jv*h#=B9bfy~b~V2j&$H@b~? zV@%rkgvr~09oxpcac#UCZ_*x4Jm|D$*_xouK&C6*4LgL8WOTHOT~OFgxT1E#N#nN@ zzPO!mquU9W;h1*fjcq5~xOT!x=V60Nj650(C_P&p-^gN={Jivmkzq@jhU0->P-p=} z=(P&SKC_H^jK(%4Fj*T6Y_kR=5c_2Ym4ZSf#CU8eN-@4HL&CQ%i%Hx3v}KOv(KV$p zM0Y`9EB!^S^vieyU09E*fiF)H=Wo5D8s8>bTIwqc9;-yc9s#@wRHlL0tl2 zxoJKWjkT2st)LW*wc-?yY7b5^U!)s7##Zw==#L%~IIX%SVAdhSZMB}PuK4aR)GRCt z6pjiM76*{)#oCe%C>@JN+rmi#8HWytSyT_F(x-Hq079iF_r&Gm%q&%K%f`0j3Qcfr z*?C?fF5udBI9)*1Em&60R;5aCb@w=KtGG=7Is~+WhzH}EE8@5)Fe*@NOFiN=omt`< z5gCuKuiD({0wa`c9~Ar)0Ovq)AYc>QmGEl1ZDHA|wvBLce_Tk*%1Nc*Ml6yiSly`B zpPW~5MpR&&4I7(ne5^=oUgLCi@Nuw>Rk3YMxiFa!ur9m9$06#z0B>8+lK+aPA--)_ z$VGg2fmo^W?d9vT(CxUe2e1k+HO&t*yI}yNn?L@ z_2l;IWDpW3p<;X3kY&>Uhy)2_OHpN1QlgrOmMx>wzNXeTU~Mmr+W}VYw)dE{7Zr{i zS$tujZJ5y`M~=G?LyfHZ?<>$f zrB!rGwsZ|-U`nWajQgM{Hv+NMwR8(6R?Y{{vFK_P)3Gw~Q7%48#YeoB-<67wcqKoT GSNH^!47@XB?`_WaS9^ctVQf91NyB;fFwVSHv9 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

K#4eeY#G%8`%u;L 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 diff --git a/apps/crenshaw2-1b.subx b/apps/crenshaw2-1b.subx index 58467aa9..374625e9 100644 --- a/apps/crenshaw2-1b.subx +++ b/apps/crenshaw2-1b.subx @@ -57,8 +57,8 @@ Entry: # run tests if necessary, call 'compile' if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $run-main/disp8 # run-tests() e8/call run-tests/disp32 @@ -67,7 +67,7 @@ Entry: # run tests if necessary, call 'compile' if not eb/jump $main:end/disp8 $run-main: # - otherwise read a program from stdin and emit its translation to stdout - # var ed/eax : exit-descriptor + # var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # configure ed to really exit() @@ -90,7 +90,7 @@ $main:end: cd/syscall 0x80/imm8 # the main entry point -compile: # in : (address buffered-file), out : fd or (address stream), err : fd or (address stream), ed : (address exit-descriptor) +compile: # in : (address buffered-file), out : fd or (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -105,7 +105,7 @@ compile: # in : (address buffered-file), out : fd or (address stream), err : fd e8/call get-char/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var num/ecx : (address stream) on the stack + # var num/ecx : (ref stream byte 7) # Numbers can be 32 bits or 8 hex bytes long. One of them will be in 'Look', so we need space for 7 bytes. # Sizing the stream just right buys us overflow-handling for free inside 'get-num'. # Add 12 bytes for 'read', 'write' and 'length' fields, for a total of 19 bytes, or 0x13 in hex. @@ -191,7 +191,7 @@ $compile:end: # no space in 'out'. # Input comes from the global variable 'Look' (first byte) and the argument # 'in' (rest). We leave the next byte from 'in' into 'Look' on exit. -get-num: # in : (address buffered-file), out : (address stream), err : fd or (address stream), ed : (address exit-descriptor) +get-num: # in : (address buffered-file), out : (address stream byte), err : fd or (address stream byte), ed : (address exit-descriptor) # pseudocode: # if (!is-digit?(Look)) expected(ed, err, "integer") # do @@ -227,8 +227,8 @@ get-num: # in : (address buffered-file), out : (address stream), err : fd or (a e8/call is-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) - 3d/compare-eax-and 0/imm32 + # . if (eax == false) + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $get-num:main/disp8 # . expected(ed, err, "integer") # . . push args @@ -292,8 +292,8 @@ $get-num:loop-stage2: e8/call is-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) loop - 3d/compare-eax-and 0/imm32 + # . if (eax != false) loop + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $get-num:loop/disp32 $get-num:loop-end: # persist necessary variables from registers @@ -355,7 +355,7 @@ test-get-num-reads-single-digit: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : exit-descriptor + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -444,7 +444,7 @@ test-get-num-aborts-on-non-digit-in-Look: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : (address exit-descriptor) + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -527,7 +527,7 @@ test-get-num-reads-multiple-digits: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : (address exit-descriptor) + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -616,7 +616,7 @@ test-get-num-reads-multiple-digits-followed-by-nondigit: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'get-num' below - # . var ed/eax : (address exit-descriptor) + # . var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # . tailor-exit-descriptor(ed, 16) @@ -664,7 +664,7 @@ test-get-num-reads-multiple-digits-followed-by-nondigit: ## helpers # write(f, "Error: "+s+" expected\n") then stop(ed, 1) -expected: # ed : (address exit-descriptor), f : fd or (address stream), s : (address array byte) +expected: # ed : (address exit-descriptor), f : fd or (address stream byte), s : (address array byte) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp diff --git a/apps/dquotes b/apps/dquotes index ec6808ec8058edb784aa4d474a110a9971bee9f2..ae526a6c0a064ad7b14b0b230046e080f94585e7 100755 GIT binary patch literal 46450 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

p2FNqflw$FK;Ti2wT(~VfR3H|MRzmb$l~SU= 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≪2kFeEz4*A1J_>ZZr z^P6?ZP+P4ht1G_yi*DxR`g8L9Ir)C%da<{p7nF`oqiy3PiHw&H7_+Dz2Ggeunjk`@ zC(p#?=FBWraLdMa;)JNVOzy*63|OPD~Wh8 zuDN0y=lb*f`L@&}-lnrkTq7dq@%2?(I9+H&C)-DbIQgO3pYQkE%yt#Lm~LBGPO5D) zT-+ZQ)^g`$rw~SLl1E#^sP>rNn{PZ zy=cIZ5bs3WZHkkdV#7nyIGn50IPOeI~MJ;bA}DepW|P}a28$Yx-6nP#A*qwShTGnb9Pmq^$#wo;@XWb|@?u1wnY ze~c$1lZl0m7EMIe9!*RpG$G^Q>nd0eii-FS9)DA2t{5gA2tC@0@DXC5pE5OSI)83D zRyG{VnV3B4TO~DxD$_wqB2lSQ!H}Dd#Xu3}6JfZTnu30#LgY)Cx%?81^1DUma3bZK zAsDlM@?)rhq>>Iw^QIO=1!YM(7WCo%5n^(t+h4>)%NGYK7e?!-!vQ)^A?*w5>4C5R z1?V6@NUqNYi{~Kt@Gj%gP^P$!tL@Bj)M=Tw*?q*2=77Y z9BFvUjP=3D7-btDeuwYVF%5Dly=P@FPDgsp^Jn4PVN25OZ`!Obs&A;nEi=5-6W{JK z5_~v2$06N+FhX*%;N<#^`Iwu%_@JcZK}wz}B`)=!20k z0^3JiyXAj!jU~7sH#>Mx9V)OGly^`Djl|tFX%O$6^7H%!dD-Rug8b|XzRPG>X{)z* z6JQ@O{52H6Rb0Nce@dpUUT;m1sBODj#pM{{#uHLb_g4AwH6!zNMHN+^DD8ta^>j5i zx**h0T@l8)h3vV_)Vv(w0b6O*sv`5UuXrOH2vbQMs--E_hJ3@rw&Ll4@{Mn(1caW} zrRM~N^%(55r^=>q_%)@#l zCFlS->m&9-gtN!cvG9grmbsXRbYXJHyAd`4COv=k5Vwc9 zmc`bK4}g$kiE(yC7G96rGrggy6;2~KeC03{Tnw*7a!qjeyXhg EKQhBSZU6uP literal 46460 zcmeHwd3Y36)^`F;2(ck-65OB-h#)pu2?WeQ0KtW&6O^DL*hxC6NJv7uTfi64jLX=x zaU31D(QzEdaT&K!U$qfs5fyL;M#OPNMlB8QBeV<@j1fy zJXd_KqmLAW*V(a;0%hfM)PqT zpw|A;D9>~Wyi_L1m>WMeJ$}Bocy}~Q`x;bmioUA7y}ji*uy4zW&+1zy zptTaJ!3_dfE`jYm3JH3iP)Gk=1F3u*Aj%}NXkJBpRXUpzk9u2PfMILtUrGW6YgfE| z)xb49*9>7BBS(>DN0!c*-lnhV$&hGI=GWGPDHbgx`(eKJJ(Qn9;`HmKM%qsRB02%R z4@2RD&02njiEA;b7(i$d&_DbI<_p{?z*E6@qT;&}K*9G33+}@bH&fw0q4=(`;C?D` z_c9dD);?Fb3oW?5BTOBhRJbDm6#C{{aL<#tafMr@aMLWfpk@}aJ!KkNx}HT45%_rO z7V0D^DY4BeegU+WSdTNw8|!8uvZCcu`-ye$PBl|K=W$!qe_!twe2RTEJ-*5t?^B!^ z9VLRF`gO||G=jX1c{_?<4SUz5t;s5WJ$l6S8Es$L18v0lCYW+775cr($A1D)#AC!k z6}y)J-T~Z|3U?QPB$49$)6WVw%}e0kROkVPI}kv@_f-pS5x^zD9j#AL^57lFwtaNaCAZ|1=O{q(f-)|u(vEfA8jWis5B(y|fF zw0LVc?S+(-$!*_@-UkXIFmRZ)U@|LRtD?Y_>0_ia@g9K0dMu){p|IhoUHaQX{4jaQuR#q&t@{2(|_ z&6p;10OwDCIwa@e;JgK#-eVWCjxT`|DXVn+lamwqU#O`sl5|GHztqIV6N zr>~V2ZR>wK-NWN5kEzLSJ&~q3O^5M&xSO%@U*LJEa_hh04AE(B*?&lX{)41z{dyCN zYZS{YJg-*I$KhFw;4E?&JsTp54lQCSM3jTYXvK0qp4Z7xXbbUtzk05Q2yzw;6FYxA zq!oQ2;&!mu$~~I3yvt-^v|NuKlbp0~fjm*k+noLYwHjc0pXn?3Pvt==@6 zOj{Ru<2_pkc8|~Sw4TzP#?T=g!QwZ=C()q#Hm1_z-3*EzMf2!;c^hdaMU&$O5OL0< z1%1fwOQ=uktsK&H!qg@MD4g-a52iCVYZpq~pu%lXxPP$V-Yjv)D%{%@Zi5APtHkZ4 zaJK^}n$;AA%flKaO0&{i%e?W_)?>THOFgaLZn0;J-wJ0=A!Ae7*hu%%w$BMGR^~A? zChdAyxsD}pyuLTJNuVY^*%Q!rf3K{)2k2KT^sG!$2svH?HH?0rLRbC0ggY%H7~Q)p zern%1hH_6?>uH`cV-z@o5L%w2NjQZ&pBZe9oRKp{`^IMtqzLz>;PziLm_2_Nt|)cN{{!8pOa42tqYFADBq7p z`5A0A=7!W%>ArRF#|7N|*nP7goq@ksQJV{3X(g$E8jP`5utf0MEU=GLEb1kTGR0!4 z1fHUR7XdhRnuV`l@nzqMY$L7ptTf6qA&xSS;-1l?WxlbkcvpA;A&> z7MSg32|Q7;eGxz?8_>tOv)#r$gth%layZDNAG7^h0$*3M_A9m@eCyEGOk(~l(Nz-j zm_(MdQn~Q{Y!5j-ZwJPqiG5Zbvu0W!ujq|^CuY&(f-DcE_XA3&wCyRKn6*-@6k@YI zGP!re;9KrqY}N3-ZIGxc3F5T* zL5Z$fT&YAhTU>w!RqqeGTc`E#Vw6waQVM6Jh&(nvZMdgpJf5RR#1{-tH-^Lb%;D*! zvC}+pACfK(CKs^}G!O^$yJWZn`tbyruRRZiF~YVtdGvK(nf?(&E$41X-G&o_NV2qj zAfU$-_NjiABr#hcTn(D}B+Gy~$LK#XJA|xlyj(-2wN6X(2IA8_;&VoN>$INq+><}_ zVkW_4lG-zMx@XZsgZ2NFsi#-+)MLz6w5E@z#pltE0!?pe-cipQdm^c6a-Gh7_9X6z z++5$pEONAZ9?;)xsk3=rfY}<5M5lUJwX>suiC6^myf4j2Xp;b~K*5|#AX*l$iJN`0ciCp+*0-;EUL%D}a}%;t z_6v)9)+^w(ASdsTd-{K2x(5xNmJGCzo1H#!wr8ckbvk7^w{mxaPx7_}+Kcq%l8d?J zLXES%trule)B5ynpPs%@?746(7fNESXAg?yZ1wz{WV$uIjHvTjtoS=N>6nb|zc zL1i`r2M`;$B%nX(WHU#RF`G&1c@oIjXJMWi;En`%Z<(BqJwlD;oU7!V2?F7oIZ6(N z&^ba(Cu%VUwM_`n5J6jP=!u;U5x4R%ZW$ufP|DkM#9*~2K8U;Wue_svvTr^1CW$<- z$aHW8ltp*cC$+(~u+Ex%3d?i3r?M9(rcp!ispq@EfPrVRYTR1zEGT<$SQ+>?V7`cg zy?MS`4hX#P(AkziTS)6=0ytgpTImI)p?bJ%Ly)~mDGWh z_eQm13SkvagKN8aTWR~4mzxCok5*=7k3^! z=53>ndaC!TX_Ac{`)f2LZiy2b*?Rv>Vbmhy`Gg_f&pJ5dTZm)Op zGdtT$rfLN!I4;j~7%iE8f#Sz~W0-m#4=M&$@La%gsg**1QQl^uekF7YD8o`{KncZI z$1cm9I46BoKhr7R_MXBg+Gv(ivAIVDN(vxtV|q8~o)a?Z zS$~Vf@ZMOqYz|Z{>Yg#{#0EFo4-aU^2k}-6OaS${1R8 zINOx7SZ3E!hhnpCj;yojFjncno;*Q4vrZhTR;3d^Ph(E3_?=MiS*c?!X9`lsvbD#; zu&q>&bg~~$JMcowekxK{jvy^}>cUsQBloc%|0(rs`4lqRc36jl%RiM)``ay78BV)a zDflXM`B*BnizjQRLjN`t`bvpPRw%_(Xb`7sthS3n-*PWyXRrtNs%KV^J$9*5ke|CT zOD6gWx*jvgjPeOKg{h;`${}9niT4s4XxqaxY5VM`mIHqBOf($ zi2vJ3j3GboZL=}ueNQ8JY6&-@w9@s^mL9no^%Knq)v6U`u1VE*(WJC#uP1dgZCbYc zf_Ox_{qS~dx4DW!Bf7>-!_}%CTn`N~uu%T*)G+as8*!;3-UQ+^s3`~ZH}*Jv^NAa= zM-hJsVw@cY^qZ522Ml(J$`%!s!BlUw!1I!b$GH)UQ&sLbB_PHzd_W(PM0|l8@hl~| z7Q_@`%If!g;IO%jqS>+^L0frT%YLk`S08)ABKm0AUqj_3R2ihtRXus=F!m6|A}NR9 z`da0kH4sBE((z&`X0ry~`gIEJPN0dVJy)V>kgV4$tS1$gUt(?6CIIbJh4!+NnPx$Q z%K8w6_Nn6b{`;l}G#F?cUb2&aQCMpw)@BXKn!a7RbHGv3&g&E!H~f{ym$284E`dFl zr1@d|<`Ss0GR@CZzcw1=oSS|19#l!E%7B(b2m1OxZqCqUen1-y$kqEz6!F}LlRz<+ zV(WnU+$;H5mnGDdv{I6V^n0dUmKiDfLwv1h`D+c+>VQ$Kr_+wnODl+@U>-Ou(;Ec1lZWBrU1@p9>@ z7v449;It6wlZF$9*dFd5W%_*_c8Jr$V1UYit}_SB;o7r+_MzX}^YrZ!Y|KKMl_9dd zGTy)vVbXp9DFKP$O_EX@b+jRd7+xyD=Gun*2G8`DYKiGHE4Ha+6SRz_$2N7J<)!U9 z(XB$@#&Lc9oer!nr*oFP9Y2J;Ek8k-=t;3>d%!eKeeUCy%A5n~G*Gek5u|fDFs+jP z(vH}(g3nq}Yhp$Es+rij8NpjOA8^-#-eT+K8BWh(mhj&IntW)_=BjB~-qI<&_a1#FHak6* zg#!+eoDMt2^yHOqyLnQi#LJ{0u}rH~&%AL}p`K3%L(Ze)ADIlr9u+5KmV=CPU@k?$ zJkmHLhEt5)v2KbfCw$+qf4M6$!H4R3nG`z6P3WUC+}bK&J}HF`RZ9@8H>A69bPI@(@f?w6*#!1=Jnf6sC^Q~r8XJ-16CA9Lp95c0M1SC3;!ND&HF^hT6y+*Viner;lQMBPRXSzE%VqkOgR&Prpk(X2 z9CnNC8|;^RM$_I6jR?grUNRzHWSk1LYnf^N!$bUi|VbD2FbrQXXBpcM1U}gFo#bF=;3=UaI945JNn9dw}D-JUihd17E zxFoUKg~Juh;UyK8s}+aqlQ<+?IBZ}JF~#8pa1dRhEQ!NsE*!pQ4l@*o9~6g7CkJC= zj&`~G(3ruya_RA*#b1Z}7Vlg&7)v(Vbn{LvZQBxvhN~Fg>RJDVuHU?J|`}4Gl1vvDrEpa-=MaPYGKP&(xAlqj%Fl=Y%dMj z3q7&7Mr{|joar`9y59Rc)3svo9u-S(83{WAbIVgVm9=c--}SdRSL#df`R0hN{T2c_ zK5KWFOq}sSn-W9Whvgb>f$KhQ9q9y5JmO+&xjs|bnIMFKK3Y;}8z55j*ZWweWiktt ziR5h+cKqk*r;{)-b<=p#O1B|mJsExvZyG_q38#Jgg(5$b0s4+b!gN+%Sg=QX8{)am z9LN3umom)T$%keW{1C{xwc+)Cnu-f_wbzzVTH9%Q^NJl7U7((6hWOpf8qpM`Pp@BWER_ zB*qh4ORuu{lXmp6G(kAMyCb4A(mtp5bK3gBYLYdg4RqR(_R`h6NYmu`WM)9Joj=wl@2p~C>VH~YV-Sm3FjHNxIFrX*G&Hz zsd|Ot>pkA&8+YS7P4VpyOk%6})+)Xf*yZQ5VGwAVOxohC?ZFSn?!y1+#u4k zq&ER!^P6n5)#RtSSF*|Dq-tOB_{=7=wb!s#j5G;IHfy(2?rOXcz*-sECe(6x9rp}f zyk4wSxKOIFM5zFalDxh&NsrT&9s+w0_bAr-2FdqGH@+6H-v&$)sJ#C5E7Cr}H>UVL zFZn*hGlHX)>{HY2OG*0PqWB&nnuA3&`-x~~a5Uk|6+% zo#*lTD{+loG%0M^^SRL~^_!QZ!jS6fkcibGFWOm~!>z?3+rb}`A{=s^;-C1%oz&ux z9>a(fo46pYu#k?U3hRjPBOJ2obmhwukP?(hk5!~ezAUi%@)*OH0}NjtA$$poOkDA)Fqi{tgjr%&c z^9Lb-ffHoXsXb-dnm`Q>Q%6hD0(m7nhB>?sWWK9xBLA|@)YF{hSirU1H<;!JDfKxX z+qvU+A8vS9N_|{1GW1qb#{t4bX|_tKyJgzQPnDdepj%9K3QH6u(XLRm zlR#^BDNhn@V-jtNqFrgF-MYnLWa7ajTFaiquXc63{M{^T_9UJ$MGYGgRPnFdBI_(pb0Cf(?G*g@8S7~rIrB*bEVXq zB_n~HraH&9Nm3U}WLq;m$gP)ceO5}%lTwqLsko!f1lvK-)2dOLQ-~O$%vS29RyvCC zG53BI+bS<$Co)cSw#|*IjSQwr_8{8kUC%q5mzb7BD~5aFG|)m>&}vDvS0~Y)rsUoL zS|VlIlby7*_)^#4TBmz)%#P*dLtjBb2p6Sgp;eoP(Fv@D3nMK8%TfdgqHpbOyZ;)9bVr8f0p!TI_cLc`X5NDQ0hiSe-B7sm-I(C=~pQF z?_NzRd^Il^Uz{`men&9MbOkdLt?ultDGq<3Vrfi|NYU!u#6muJ( zr?KL}o_Ms6xY0@L;MjCe+hFjyTb?bN6fPSFPjkm$=YczS7}~`hB-Q;FXG&T!!^u7To-~*wClkExpqK5C5gjRE*v&9hclH9TfsqC@zZ*T72;}q zAL^6Eo5IqY_~ncop|c*iLa8>*i)w8&VJ;E_r20! zxl@D0aig7)AmX4R9zpen`V*6g18&5_74dvU{L3>A+Y>9@h(GxSXsq^SAQrCQltlcP z8}Z*1@l%TU@+9ImH{vCV_*)Q*kj-!s^8w`P9tu%udkOBnxE(|$hMw%=RdSzc+lf?f z*!I!WrehLQ+^DWnRHuVV==HFqGKL#$&GF^q^Rc~2=Z)J}4WC<~KdAPNeMDKI50~qW zO>J~naJQP7IWI`zuFC%BT;!__QfGuhyB`JT7D6xHjo{}DX3Uf!=ozf^r6j-;FJY!g zb?M>`a-N$NUzT%~dgk>{A$^C4kmF3crMIgpWeWyf&YY0As+*Og?^vBdn$6U;qx$QkKuto9g!RFp?DBz2ipfw z+mH%9!Mj;dgzh2nZI$~EnvK#N{dr55lo76ei@SwtCfnq5qL)9Z>2pgj6HYjp+#x15 z@w}5$ALf)vl-ej19M12Z`LzHql%h2D_iXu`$aN8o7#N}-;U2F1KVOM1g4BQ%{a@~) z_i`&%R_~P0iE}#_UE~n`uG(y=hSW7ubc(xZO^Om$&zH}M-*+y0-9fvRj~m zKijRYSEAF#kmw>5Y~F8q8Dg=TMpE4E$lHdk_U)^BzL1tOy|nE+^ZpY0K;hV;aq?yx zEtknZ+`XoPEBS969X|Db($v84reNDTn~oq`2lk^Knvv~!l!EDjwI;pjv^`o&>5b&> zv--BZZM+mtH~++v>Fg&=RBb*)p>gYzC6KrYkY9rMRUZKyEP>Yb7Mats52FXC)lgn0 z>}*mq$tly@c#nj;4nr?y=o=2`uNm4;_3$-N63j$syf0hIAfqQ`ZBC2iwZ6f_A z?%c&j-$q7SUGW}6uawZl#{`J?Z9S{6hi~kc2Vx)c?q7MCE^bP(!@htKrhEU$`T(9t z%juB%F*OkNAuQ?cMUuKBcONfW>z%R{S=>E_TWj9Nc%O;0)59myEK;sN$~_RyroDt% zH@X{{nihMV%`uv_HUb)O5LP~RIL@3w^yWnrcE}tsG#zp^^JMs9z@ZBD%cuhX2H?L? z(Z1BHKg)(OI=7Jf30|guqx|(4uubMUipy(&8_WkQa2voqa|QE|gLx*w%k&!*^DF|$ zVC;Al-e6S<0EbZ0e4PT%0eCSL?Mnyh>5};&VmDPDk6L2)D{JgljpNvT&#w)$P1GlF zX;^>iJu^b?u?#~aj^*DUF)_Q=F%owWX$OrxM~x--LV)RhA%i{iI^c%;Z(-34{t;kb zo^b!ivUQuiXqR&RNJ5f~D-?$S;0EK#3cMWPI}FCHl5yf*0(D?Tof7tUP@7}iXMdM* z-VL}B=bZ|il271~R3OeiDXgP78#Br;+)$vpCC<(nr9C=We~FV>AZob~LZE~M(QpXB zJrclk2|&MBAS?>nqsQvKHkd)@_0TJqVw#MlQ^R?Py95uON1-9zE}uJ^cZj7i2Ytw{ zD%a!dP3{~Jt(=rC)8`#9-B+$1NvySV;Vrf%$Ovz--{Ebo4pnCBX@1y2c$p+z!-RM( z_Z*Q_pQ~MmO0?|uW{*BjlD0fIoM8MN3?0qvJKr$XK13X*a=y=+KS0vp<6H?c;-JaP zy)q77iNhH-;?Tm`FgQ8mFoGL}io+oJ+=VzK{y}QR2e&R5EGDG6f!JOnHeYfk%DQv$ z4twya{SFuZ3tj}m+%kO|+dWy2hM!sB~#ODNv?A{iA7xXpWN^ zx>^lpr$JBC=DiO{>Yus;eTv?f^~U@_Pj-O6B`N8!Km1vG~No0O?Uj`ev?}J7;wWK&nU2`kigkg zz#SQ~M(pP`}|m z*?ii7b&SILp0PLrjSB0iv4r&<4I{=PcQ`!<_=HeDU17}tme^WmiDxkurayg{!dd~W z`xLL=FcwQZc(2s!L10~`u+}ja*y?X8tUbU|FY0TbFcwREL}ICS%bS1nO?_v0;{8)! z%-cu{%q;c@y(L_s|Fg}MUfTAN_geh0+hO7DLp5hL6j1i=RRw6WXaghD0DcV!$g zPO8+$ovUb5;C~3N_j30@__dS4m3|>z6MuCWYWUsTN_Qg%QM0F)Bf^Dz>`9tk!xs}- z&?bT(Yr=oS>mUIaZ|JmbjqT>ak9R*0%DgJJB{rBv6aTW4X5ao{DL|DTJEj*$_(J}$BBm+}{1zLG+D0rvoZjHXTPMyDlRY0Gr zYVSoY5;Z=57uCaMwK@2(22XHTO;Yg{sp5M)2wPN)$#$Xb0+#KH)cQY56;CQoQt=K| zTZ>wGI4@Lek<~U82e_(eIP8GxQ+I+T8EqcU=ex6ej(b9q#qWWdU9wN6eTIyil#DNd zg)6mqS3+q0(jC%d{{*VVLe}E<2V}L)s9(8jQ3npJMU7L7eoBjrfMwU>R4GPVi`paY zT8xm@vezJ;Jk3MjH=DkNa4C)4h#pDARw_4m-eQzV=7(27`e9&h5&)#{dRK zK!4r>ei>je3Fr@5z@Gw4Py*j1!G?K!#h~R^s9k+@%NU5FH_)c_N#8>M05!f_FYOfK z!A3qIH^jwr9q`kFwg=iW%L$^lZZUZo2h?6YkAnueZPyw5U0(fI3H)?!dwV;$>6h;^Y4LOg z@6$s2mgfeNYt);R$kAK&@nt@F$&r0V-EtF$s;@qi=K~0BAA3JJjPeP6kL0htY@nT> z(4zFk)qVAYlv{`nZK&E;Pn9^@4kq*J3+1k?;7)HeOWx#bufA4p7gD0= zpij$lgGe{I261HCT>%=B3?G_53a=CZ>eBJZHdg?Q;nf6A1&; zOH9mB3Ujao4phKm32f&SjLG@XjJ5qt0Vhe!Hx#fz0yiq)Y6-kw0kQPdPJqQ<$ox;N zPg{6Hh&^&OC^w>DUksAVX6-ouf0Q*p-(z+P?PmaUe`V5qsA?ty7?CwwRn2k$ACNT< zshURt{8-lfUe$aC;E+jFux=Ntnh^k=D{C%LH5USSyR4ZmYm7lsMDvu}V2o-KC#z=` zb*y^kCgD}j4}dpEYBFba9KNR|aI^w$mB2v?sDg41@69tgZxZa|y;#=i4NzuGrh>I; z;lT%sG3{so=g68`RdWG=H^`b;1{yyC0QfW2!2V=OJBr=FNK&_uFt3ZRrFq7RBqvITlPrrDPn4PhjS-@ zrr--AGB3N2eqEE%vOk+XGcUiD%9j27^2XpPs9s}K)1Nv@iT2>j+B`^4lY7@?dLxK9 z_+q-r)=G>!KMhhE6V2v`us-IkpqUb5%G8zvlZn&HBlF%i#6Bmp)b>DZXl{XUWBQvfW}d8!m_FvRh=seFF2mrP@0o7(yoZ;u>DwYY{X-r+c6 zF0!7dRNlauuC=iUrEk1RI+RDDE9G-yE2-$*kQQTm1+_b4rsZKpZ1(c7vJ-ZFE{#k4 z37AQ)@<}P;Mp0k+ocOLose4poVW~rT!BO0@2_ zE_O)0k7qBIItBvEq|}#hceS-pN)fgWm(PjwrPMO9?SAyqqF^cyndiu%KT=g|5 zbQJ5UEg6n9XD>qsAIm>uR$@1LZ|OWfhME>8%3Bp ziawO~8}$28G|`TaelLm-PzBLK4g5s|zj;7g8 zKLy3*DDFn_1&YfapZ52KsJEk7^f(popzuCH#SJKSpvZiZikT>4DAuDm zfFd_R#ZxGLKvB4silrzXLeYle*L3!$k6A~>;HRm09>tl@Q1KdyvFoW=f#N$9r){9( zJroNzQt>c~ZkwpM8O0ILQc;THNff;|Q!y3A3KUb0Qp?K&sDrUA(@fnK3eN;S-BKSEKMPE=c=u0ZL zqlkY)#V!A)V%85-+=$|R6eEA6VkwH__fv5litayA5kc`0ik1UZJVC`~>~3TE$(sZ| zJmsX6R#pMRKNx;6gtgO;fFzel*~}mFcYKykq5qh0rKP1A^iN>%UmP`m zP5LzHoE26$j@Zn4yaw&~fsy~qf3To3U7$RKSq{$Om`uUnmJ-kS#E;d-0zzds`P={h z<$tLMkZ78wtJY*fE;WDofA|@ry%|%y($Ly;UE6kwFJ-bphReG zr#e)Vol~pT9Yu(t=H|v`UtNQ*N()sj_SZE;!v4_GXs{k!#?U|hW3|(LeqSUMj`*t@ zmox>NL;i+neZ7BisJS6j?+-_s>l$kP%jzPUKeVJNvcey1ZVs-1>NMn!r;jd^H#9c5 zu)vxtiG`bR=xq^RU3D0gB#Y*%|5zXbR$7_YMZ&Pw*c=Hp3tbUga#VG07m4c|8){8j zBH^ErR3^Dd1j7;+5h)`upgZ{xWGWsuQiH<~S85J|Ko2uwb(MjS=9HvlT?02aqZJvA z&tD&EsEufXzS5)@KE}D67{_JeuYA8m-#)%$B2qYX?{ zTB+ESRu;K12vs#URQm;=NU)iD=Q1rs9guY(H`PS^jWsob%bABwpVQRLg6bl5)B|gR zb@kC^;fm#luT(Emr?Nh%`B03o>edii9$|<0mjoj;@PsG%8ydy$esrOfE@S7j<)vN5 zFTeoG3FPsIP>3}<&WeOM`jzV3W^7%+flyOdUmvQ*xJ>!Tsuc#x7USb~Qd zxotx(q{WYiN|LH%9biH7i$8hpUX%)X;Eh zDlK>qPg2&7yChm4scWha*}4YnV8^2g$5g^-jMVsQwUZ9PzBz=EBW&mfA&ZRBfjjmD zAI9fUwJ*}>V>o_+p~kRc>)%#FBQU~7<#O8?XTvv!8W2pKhHiN(lEn!=Tl)|ccEir=nAjn{?}_9kE;LO9_gU^rir>>V_mTv5^-YF-kmuA^oul&2W64b?u3!jlh& zLA1eS0gJ(gGwKM|-o56l*LE#A0*2zJEHR5o|HpR%W# zy5%77lXbS?!@|`hXb9B?BXt*rkc#*r!Il?yLO{rdDD+;t7im=%4w-H?8os}}uC~tf zc{Y*AR&2-Sjwg@}qYHfwa+lxcZjogF^hIYcuun3{^=XQo^y3N*h(XJ{( zlvDY0aTQV;2sot_uE1hj*cr2uQZs+CKho$Ay0LKu)+8wsWHvSQjUFj=4K(f5Rr`oL zt*nDIXj;ZkIAwwl{VG^r-&jSXhILFgVHvh`-h}$Y(W!LES27>U}c81x*; zy*X4%2Do|#jgC??tQje?+fu>>O!`9;rTx>U>n&xT)%Z(#%N-#%^aG2N)WZUd!VM${_qaQmh z7;0U!2PZP`=^RQ0wi_-jt)wEwHZWQls!bc9*`^>XnsB2+7MyKKjuo8|(Mb(8**4p@ zg}|nSn|B(pqbG7Xo?e4hG%FjVP|G$dBvT6I#7>YwCG@k+cgb`z55&O9G9CLsw#}|& zdKwJtXotimSjeyTk=BluXtfoilqriKEgS<v{1`($36!Ue!zM(N96#*&*&gNT- zCRS9|MkqeK3!MEl4GTpw?Bjz{-Ns$1?;3E6QoOH*1iY?6#9b(5n`%2lx4G4}zvM=x z^pf%n|BmX47fc-uN81Ok4qRckGT0ql<~ydF2xzO8;t-+o>2Y zYkwi8M%_do6 zkyKXIH_}2Ahky;XNZV5x^o=BZ7)1hnm7~b>6X`)s#jg0$ESH9r+!d3=ImkuirF^`N zbtw6+jlk|EdoI#}8Ah0F_K)j=d>JNt59=ZPSXtE-8zc{FsL?4Axb z+0(l5Qyr?RTN12yBpkL`(*-@1xD?w4BNrq;HVuH8YioaQm@-Y|U5+rOk-S{nROm)! z?jiu)Uu<(=XXt*1G)xHoyj*w)sgrF-fwK{6I@Lzzl$;%jO6qcmq|Z0Z7qp!?O9r&E z5*zc&w8r`n4&Rqha%-@)jS7b(Az`*IlT2Vu*Le%Qu?8bpurjA^$&!M6sLH?C+Kd*Y zv?vq_@?jH}bE3`UR3V1;C9VxsF7ARkl|T*J8ioy3w0(a=a0&025rN=dWt&@UBr;gg z2#QOh>f!VxyS+OR>xTAGP-qiDJ9E6L!>WkwGGp@!BCwNJ=-jHb;F}H4vRMcUpH&~b z1i8_M#+H*?VCxZfRO=#!HY3%>AMJ+P+DRv5jdZ<(yAnbO)oeps$AprGuG&qowRNJY z57O@3qzQ-vtRNKIIznNv(`{2~Xh~g!H#ChED7L|EtwbWoa04YL4@VB<*t~q7ZAg;n z7-DDws}`7)YUk#5fN91|VAj<5=zne)xr0cCY(~tvA-be8)SQzCGYfJV&7a>f8kDRF zfgyhL=jYTkHfDFgRP1z{-AqwJ)bbS<+dL|Cp@Tf34`N9uKI1cIM6w8pYZrqyO_Vu4 zF$h#u=g^a_2|7dxa!Ot~Xkt*tjE8v!v_9L;DhGj1ap0i|zS!ah2{tmk`NFv1oy8%0iTCv|z9)a9EFGCw=PE$F1Ku#>v6CU1Pg z<(=Rbby7F3lRA1yOYj~=pLANYc!l5QATyNijvY=!vUPMwos-)|yu2>rN#}PFzo3hF zgv|wPojd ziMW7k+u?LURkvW-I9rw~(be7Kur1>@5$F)miXtA2Yp!U=dA@vKfolmxX?BqNPny?DO(?>N`}dq#njjWIdf;G-FGMSE5~3#Ys)E;U;P9&n}TFg6J3s*Kno>t`HgNN)I@A2_oAM3JJQNmK!s8^i$sOerlU$$ z1HH>s11TLX*EH(6tOQ;nVaM1~ktU$g;Q(Ekw5|UbPD&;t3mq+z2&*fS7)?mRh=bQv zFdvkZ@EtsUQ)ZE9Cfx`;!3yvaV3?0aYUFgjybR22*p@RP`D9x)RfVcEfJ!WpsZzp_ zmx0MZAr=r~xQ?oVJ|jcqOPP6mh(_bPg=Zn5^34#mSs(c^)J$AS1`YG36hsASNd_kL zLf=@?IWz1BG11E9{_3UCMl#q>`za)SNfSNr^*=vt+?vI`MkNUcz?p;aFRQ28Zw-hRkt>r_5L%4v+D+_Th8*J_Fq#kB0Z` zoaGr9Uh{p~csp!GhW(_?>Y}FRM%*&Pp`LiV%NXFpIk^t*zQbXXhY2UoXY|LsoaKkb zB_CY!O)mL4D-MfG0Wx@FlsFt)3gJ@Ik_m^yVJw!9xOU4wdBzl6l$R4cEQ5+H3gsV` zLgR2ZO)A7Ir-FQ6QGQOPuc#oWitjQSTH5k0UIf@148Mlrv$89&+NXHh^7W1wiQKlI zm0hmEZYlv~ckhrMuNj%g6*ZK3BDD|JH__GH=#o%#T~!$S7SeK?s`nh)MlPlyS?C<{ZiJ12iO;Vd;`T7-vRHcY1`x(rB3w|FjpK3qNN-5$fYJyK gUpWi~m&2=}D)CV*J}SjWxQXj3#Yeb~pQ`Kr52HXjJpcdz diff --git a/apps/dquotes.subx b/apps/dquotes.subx index 5186eda6..4b985fbb 100644 --- a/apps/dquotes.subx +++ b/apps/dquotes.subx @@ -46,8 +46,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto interactive - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto interactive + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-dquotes-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -56,7 +56,7 @@ Entry: # run tests if necessary, convert stdin if not eb/jump $subx-dquotes-main:end/disp8 $subx-dquotes-main:interactive: # - otherwise convert stdin - # var ed/eax : exit-descriptor + # var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # configure ed to really exit() @@ -84,7 +84,7 @@ $subx-dquotes-main:end: subx-dquotes: # in : (address buffered-file), out : (address buffered-file) # pseudocode: - # var line : (stream byte 512) + # var line : (ref stream byte 512) # var new-data-segment : (handle stream byte) = new-stream(Heap, Segment-size, 1) # # write(new-data-segment, "== data\n") @@ -125,13 +125,13 @@ subx-dquotes: # in : (address buffered-file), out : (address buffered-file) 53/push-ebx 56/push-esi 57/push-edi - # var line/ecx : (address stream byte) = stream(512) + # var line/ecx : (ref stream byte 512) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var word-slice/edx = {0, 0} + # var word-slice/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -193,17 +193,17 @@ $subx-dquotes:check1: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $subx-dquotes:next-line/disp32 $subx-dquotes:check-for-comment: # if (slice-starts-with?(word-slice, "#")) continue - # . start/esi = word-slice->start + # . var start/esi : (address byte) = word-slice->start 8b/copy 0/mod/indirect 2/rm32/edx . . . 6/r32/esi . . # copy *edx to esi - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 6/rm32/esi . . . 0/r32/AL . . # copy byte at *esi to AL - # . if (eax == '#') continue + # . if (c == '#') continue 3d/compare-eax-and 0x23/imm32/hash 74/jump-if-equal $subx-dquotes:word-loop/disp8 $subx-dquotes:check-for-string-literal: @@ -287,7 +287,7 @@ $subx-dquotes:end: # Write out 'string-literal' in a new format to 'out-segment', assign it a new # label, and write the new label out to 'out'. -process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream) +process-string-literal: # string-literal : (address slice), out : (address buffered-file), out-segment : (address stream byte) # pseudocode: # print(out-segment, "_string#{Next-string-literal}:\n") # emit-string-literal-data(out-segment, string-literal) @@ -300,7 +300,7 @@ process-string-literal: # string-literal : (address slice), out : (address buff 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 51/push-ecx - # var int32-stream/ecx = stream(10) # number of decimal digits a 32-bit number can have + # var int32-stream/ecx : (ref stream byte 10) # number of decimal digits a 32-bit number can have 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa/imm32 # subtract from esp 68/push 0xa/imm32/decimal-digits-in-32bit-number 68/push 0/imm32/read @@ -846,7 +846,7 @@ test-subx-dquotes-processes-string-literals: c3/return # generate the data segment contents byte by byte for a given slice -emit-string-literal-data: # out : (address stream), word : (address slice) +emit-string-literal-data: # out : (address stream byte), word : (address slice) # pseudocode # len = string-length-at-start-of-slice(word->start, word->end) # print(out, "#{len}/imm32 ") @@ -885,14 +885,14 @@ emit-string-literal-data: # out : (address stream), word : (address slice) 56/push-esi # esi = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # idx/ebx = 0 + # var idx/ebx : int = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - # curr/edx = word->start + # var curr/edx : (address byte) = word->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 2/r32/edx . . # copy *esi to edx - # max/esi = word->end + # var max/esi : (address byte) = word->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 6/r32/esi 4/disp8 . # copy *(esi+4) to esi $emit-string-literal-data:emit-length: - # len/eax = string-length-at-start-of-slice(word->start, word->end) + # var len/eax : int = string-length-at-start-of-slice(word->start, word->end) # . . push args 56/push-esi 52/push-edx @@ -920,7 +920,7 @@ $emit-string-literal-data:emit-length: $emit-string-literal-data:loop-init: # ++curr # skip initial '"' 42/increment-edx - # c/ecx = 0 + # var c/ecx : byte = 0 31/xor 3/mod/direct 1/rm32/ecx . . . 1/r32/ecx . . # clear ecx $emit-string-literal-data:loop: # if (curr >= max) break @@ -955,15 +955,15 @@ $emit-string-literal-data:emit: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # if (is-alphanumeric?(*curr)) print(out, "/#{*curr}") - # . eax = is-alphanumeric?(CL) + # . var eax : boolean = is-alphanumeric?(CL) # . . push args 51/push-ecx # . . call e8/call is-alphanumeric?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) goto char-done - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto char-done + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-string-literal-data:char-done/disp8 # . write(out, "/") # . . push args @@ -1027,22 +1027,22 @@ is-alphanumeric?: # c : int -> eax : boolean 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # eax = c 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 8/disp8 . # copy *(ebp+8) to eax - # if (eax < '0') return false + # if (c < '0') return false 3d/compare-eax-with 0x30/imm32/0 7c/jump-if-lesser $is-alphanumeric?:false/disp8 - # if (eax <= '9') return true + # if (c <= '9') return true 3d/compare-eax-with 0x39/imm32/9 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 - # if (eax < 'A') return false + # if (c < 'A') return false 3d/compare-eax-with 0x41/imm32/A 7c/jump-if-lesser $is-alphanumeric?:false/disp8 - # if (eax <= 'Z') return true + # if (c <= 'Z') return true 3d/compare-eax-with 0x5a/imm32/Z 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 - # if (eax < 'a') return false + # if (c < 'a') return false 3d/compare-eax-with 0x61/imm32/a 7c/jump-if-lesser $is-alphanumeric?:false/disp8 - # if (eax <= 'z') return true + # if (c <= 'z') return true 3d/compare-eax-with 0x7a/imm32/z 7e/jump-if-lesser-or-equal $is-alphanumeric?:true/disp8 # return false @@ -1381,7 +1381,7 @@ test-emit-string-literal-data-handles-newline-escape: # emit everything from a word except the initial datum emit-metadata: # out : (address buffered-file), word : (address slice) # pseudocode - # var slice = {0, word->end} + # var slice : (ref slice) = {0, word->end} # curr = word->start # if *curr == '"' # curr = skip-string-in-slice(curr, word->end) @@ -1406,11 +1406,11 @@ emit-metadata: # out : (address buffered-file), word : (address slice) 56/push-esi # esi = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi - # curr/ecx = word->start + # var curr/ecx : (address byte) = word->start 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx - # end/edx = word->end + # var end/edx : (address byte) = word->end 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 4/disp8 . # copy *(esi+4) to edx - # var slice/ebx = {0, end} + # var slice/ebx : (ref slice) = {0, end} 52/push-edx 68/push 0/imm32 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx @@ -1790,9 +1790,9 @@ string-length-at-start-of-slice: # curr : (address byte), end : (address byte) 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx # edx = end 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 2/r32/edx 0xc/disp8 . # copy *(ebp+12) to edx - # length/eax = 0 + # var length/eax : int = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax - # ebx = 0 + # var c/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx # skip initial dquote 41/increment-ecx @@ -1800,14 +1800,14 @@ $string-length-at-start-of-slice:loop: # if (curr >= end) return length 39/compare 3/mod/direct 1/rm32/ecx . . . 2/r32/edx . . # compare ecx with edx 73/jump-if-greater-unsigned-or-equal $string-length-at-start-of-slice:end/disp8 - # BL = *curr + # c = *curr 8a/copy-byte 0/mod/indirect 1/rm32/ecx . . . 3/r32/BL . . # copy byte at *ecx to BL $string-length-at-start-of-slice:dquote: - # if (ebx == '"') break + # if (c == '"') break 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x22/imm32/dquote # compare ebx 74/jump-if-equal $string-length-at-start-of-slice:end/disp8 $string-length-at-start-of-slice:check-for-escape: - # if (ebx == '\') escape next char + # if (c == '\') escape next char 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0x5c/imm32/backslash # compare ebx 75/jump-if-not-equal $string-length-at-start-of-slice:continue/disp8 $string-length-at-start-of-slice:escape: diff --git a/apps/factorial b/apps/factorial index d3cee9da40d9bca1e2004275c2a824cb370a8dc0..dd981d0d743f648d55ec76a9f873fe2537c54311 100755 GIT binary patch literal 41227 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 h;tSy5v${OW#S`N#ZMJg{|5`CxTF98 literal 41237 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%0DBa{RP+;5wRz7*XMitfM2ZWld{Nac#( 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 diff --git a/apps/factorial.subx b/apps/factorial.subx index 26cf3f9d..019329e3 100644 --- a/apps/factorial.subx +++ b/apps/factorial.subx @@ -45,8 +45,8 @@ Entry: # run tests if necessary, compute `factorial(5)` if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $run-main/disp8 # run-tests() e8/call run-tests/disp32 @@ -77,10 +77,10 @@ factorial: # n : int -> int/eax b8/copy-to-eax 1/imm32 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) 7e/jump-if-<= $factorial:end/disp8 - # ebx = n-1 + # var ebx : int = n-1 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx 4b/decrement-ebx - # eax = factorial(n-1) + # var eax : int = factorial(n-1) # . . push args 53/push-ebx # . . call diff --git a/apps/handle b/apps/handle index fdc96dcfccae0daecceb1d90a687280efa61031d..23993ca6384c962ebd33aae3ee0fe07c00f87fd0 100755 GIT binary patch literal 42125 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 diff --git a/apps/handle.subx b/apps/handle.subx index 7c4657ec..07611596 100644 --- a/apps/handle.subx +++ b/apps/handle.subx @@ -44,7 +44,7 @@ $handle-main:end: b8/copy-to-eax 1/imm32/exit cd/syscall 0x80/imm8 -new: # ad : (address allocation-descriptor), n : int, out : (address handle) +new: # ad : (address allocation-descriptor), n : int, out : (handle _) # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -55,7 +55,7 @@ new: # ad : (address allocation-descriptor), n : int, out : (address handle) # ecx = n+4 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 1/r32/ecx 0xc/disp8 . # copy *(ebp+12) to ecx 81 0/subop/add 3/mod/direct 1/rm32/ecx . . . . . 4/imm32 # add to ecx - # eax = allocate(ad, ecx) + # var eax : (handle _) = allocate(ad, ecx) # . . push args 51/push-ecx ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) @@ -96,7 +96,7 @@ test-new: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var heap/edx : (address allocation-descriptor) = {0, 0} + # var heap/edx : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -110,7 +110,7 @@ test-new: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # *Next-alloc-id = 0x34 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id - # var handle/ecx = {0, 0} + # var handle/ecx : (ref handle) 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -166,7 +166,7 @@ _pending-test-new-failure: # . *Next-alloc-id = 0x34 c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . Next-alloc-id/disp32 0x34/imm32 # copy to *Next-alloc-id # define an allocation-descriptor with no space left - # . var ad/eax : (address allocation-descriptor) = {0x10, 0x10} + # . var ad/eax : (ref allocation-descriptor) = {0x10, 0x10} 68/push 0x10/imm32/limit 68/push 0x10/imm32/curr 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax @@ -282,7 +282,7 @@ test-lookup-success: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers - # var heap/ebx : (address allocation-descriptor) = {0, 0} + # var heap/ebx : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx @@ -294,7 +294,7 @@ test-lookup-success: e8/call new-segment/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # var handle/ecx = {0, 0} + # var handle/ecx : (ref handle) 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -350,7 +350,7 @@ test-lookup-failure: # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # var heap/esi : (address allocation-descriptor) = {0, 0} + # var heap/esi : (ref allocation-descriptor) 68/push 0/imm32/limit 68/push 0/imm32/curr 89/copy 3/mod/direct 6/rm32/esi . . . 4/r32/esp . . # copy esp to esi @@ -362,7 +362,7 @@ test-lookup-failure: e8/call new-segment/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # var h1/ecx = {0, 0} + # var h1/ecx : (ref handle) 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -381,7 +381,7 @@ test-lookup-failure: # reset heap->curr to mimic reclamation 89/copy 0/mod/indirect 6/rm32/esi . . . 3/r32/ebx . . # copy ebx to *esi # second allocation that returns the same address as the first - # var h2/edx = {0, 0} + # var h2/edx : (ref handle) 68/push 0/imm32/address 68/push 0/imm32/alloc-id 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -422,7 +422,7 @@ test-lookup-failure: == data # Monotonically increasing counter for calls to 'new' -Next-alloc-id: +Next-alloc-id: # int 1/imm32 # . . vim:nowrap:textwidth=0 diff --git a/apps/hex b/apps/hex index 785d81f8e5742ab1cfbd4e005f3719496ef11e4f..d349dea865a9364bbef730902bd24b7c85abdc33 100755 GIT binary patch literal 45047 zcmeHwd3;pW`F8?CGQhAY0wT)@C?F0=2wOmu$mRyjAe(~VB$;p{A&Hq877J*sRfcJ_ zY89>4wRNr5)@lbqS%Ly?h=_u?fmW}L3TV|LO5W%DoO{o?_s&g-{@%~${p0u2dWLiE zvp>&y&U4N^Gh994qKTQAnHlDv78xxw(EF-5qxDd8kUocI_%m7$>r<*T zGVot3Jnxvn_%~7irWP4(@Sip&BLn|s8P8K7@Y*%0mi$qd@))1Mf9;yO6yWgbH9p%I zpQjt2mx|AI^pRoEnvwWdFf{Gr6$-#zJzbE6&5#s1a%Sq&(7*Q&bMl)w6S9n>KWZYNt5)@lY|7E1m zuyh4GS9D&Ty}B3c7(1CHJE?He#Cm;oHjl)!nO=P>#+W~k^oROd0Kz{&?DSiuL|PsO z;hmt~o=0JWI;~8?T2!jSAfyQD2aZ8~0s9vWKM1;`72T&5-DfSZpGw#c3ieAyceMr9 z-`b@6F^|I7T0aa58Rl7FXGz$9D%i^u><|m=EfO}VVE>?Cvn;US#OxCLLmDDo?@A-W z@yX1sG)Xct5_QUdK}1WU)#GH1bq~X{B62By5-nTOlX0Fo9E)QzxTB`qZepqH(kZP3rFTJTq@wg8`U6z| z6Hp%4X1tIAlt2IBxRm>W@-a~QfKA9UwrFekUdni{lM>lqh^fz)ct&7gJrI))nGB9X zxb)^xkS8!BT+WwNO`nElCfSV1_6>_Y1yejL#t`mIeJ2I2AZeu0nfjZQu4}e{o@mAF z>M~PbD<9OqaMMH&=T*+B>1ORuOPto5l-2k1G-KsYL;p%;)Mzg+4wKM6cn0vlmYks)T|3}0=vC)uLb zmqm+d?R;M{yS8)7b2}rFF|TcOyPq1OW&KusMGG3uwe!JX9fEQ3+xUFJ50guR%SzZM95=S zOxiclavgJEe+9q+E>Gb}a;zt)@A*z?o86MYf2+W!030=53QrjPQ3bB%`xu_I;9yMe zP;x@YBvQF2RC}H$WMqN11W>bu7U2w@e5SM6b4JY+@0gt2nLON%oO{CRUaNYKrDgJ< zs)4E?5k+E#zW!Ut4d1Q9OjJvF%?b>9qbC|%ZQ; z{3O;IYeQzHG~X$($K^cz*nHQ4I}iR|d2KZY3yVkuJVB2A4RaL56+`z_Bp#F`LW;yA za_}rQ_yh*WjknMZD7tJrQEg<^PS2t`6YQw+D9Da?m-WW>g14h5QoYfkU|Zb7^#%cD zP+vFME zNKEm_;@;tdZ+LpKR&%5R{gqawa&W0K)*=iFAGDEz+I(=gB7482@CN5`Hr8L{;Hir2 z(-;&!c=~IHv4puND6*eR3dxa_|{7*s_CEVUjzqy&U{(nV|q?f45V- z&XI#+U%`4!l!NChUXvBCeTQB3TBLZbloYZRg=-asJ0%5ey##$vIc%c>t&pIq2;#E& z2??$uu22G-5f`MS>id3A?f6zcWckdkg)l~jsAH4k`*~_cq91RYoZHW9q{HMz{k(;V z^E^pEiY|60H;IolAP4n7Np}bJQ)y(j_9FyFhHa?w=<5!d_7SO;Yd4f`{Rlu5Sz6zY zMwoC2>Z>G*8G(pQ;LIjo#+Wll-^=9Svigy750zCrKFb$OPV|V+N#5G=+0@VG550g< zu$W|KXHN9YpJ$N%zq0hSPG5SA)r$7?$*kl|I#HnIEz37>vvDSpnI-q>9GPeEMC5QC zfmNit>R$kZG0+rV7dTP@BnIDCaTWw5d=b?14w|0O7Gv~AG)%cr?iK0;fxq$uQmpS) z{ohO0qT+L~E>f)Tl#q{d{&ql)RFL-oa-9_C@3Me5#PKWkEN@5E-z1rgcVn_k&I{I5 zX!n8|+zNEE4w>hKuT1kG&}qv+8@Vao(NjFj1GN*W%DIcD6Ks;VJ=ic@Un;4XM=lhc z4fU<5ni}7}W5Y!6JaOj2Zki{NwFU6y6xBa0HMo}7BQ{epfZ{x}*bCnSsF3Bn;!7!~ zP^X2W#k9ZX>BDF}I}sWSaJqx`$%;1f5;Y_v^#u|YBV?0fUpRQ(u4pr_>s6o0Y-Xo2 znF~P%CJE~Qbds5>(3s3Qs=ru@9Ob0}=176|*0Elk5o*lmQpM+5APCb;ReZ>W&I~b; zutg549~Gn&K}T$uiA|=6yEu(oQiMvSd`w3KR(g_Mcq*Um8~B6$=&>DfMK{RB3bGR*he&Z=XXkQ(i)CdbJ)mk@zgkkE zbqoU)a)8fEFf>OEnd`z>%7SL{X2(wTjGpRS-gA~dkev=KYbVhpew!x`x_R4aqE7Iw z8sDK~!z9mqb31`0(#so;TsLUt8d`6WYI9?y%J{x-+Y;c7% z#Ea}kOQoN$=<(d>tNN9|;=x(G7O-CyNT$b>wV7!^Fv z(6gh#&%SIUS?28{v9nf<@7;0S#QIkWR-K;-pMA)a zjiqDr?NI&iArqU+>9eoc{fu-BK>ib{VZAyj>BYd+iXPLiRQ>+IV)`d4YYf34vYFWM z5Kz)5LvEj3^ zJ~ABWv3T~p`Ai&eBYrrc2`$$C8$z(cIQkHSe^gTc6O!#h!&Yd^F(`d#m0^a-XQ8aF zr3?k;v#Ii#MTTKY2DapBs?Rd9C2N&T+#k=BSn$0N?}(If0aprA#?aaxP^^KTqnzx- z%MPqibA+0V<)@RByL4fzo5_4^$9JWiHJ^h={hQWwaNXz9Xph~w$}rmRlz^=|lR!Pu zu+iS;#o8&*AbJjg4k=dY0%e#2b>VW2#dZ|lg=*w7cma`NhVx9!`S)Z7* z$5;eXE8LLJQpndSzLD9%>D;|Y>Iz8tX z&q4i;G~^51khdzYOa(GD4(fB#kSpAf#amULI58mOHGEL-m4>{=4SBNSd=HSx!&KGp z|Hz?ph`d>I1WsGtv*rkP*DHIRHlIFfj+9b+H9ZW|=Zb7j9mW}=*d*o9xV~0dXA{`a z7|D2*WK*YswtkBO+Y2xe+80YO4V?9I1@)DJ3P`9rZ4|&JD6p1YCC@Ai7(~{4DKJ04 z1kVpYG%cV(LF45m8+n+5S}URIG!$$4PG!yu6wg}}7zh6HQ^&B?x{rZAS7!yFeBBs` zvpg%nOTShGbgs<~eE?Cs^f0L1ludhvFF2eb%j}?*#K>=tm>{Cxo{K=1R^3#1MAETt zOK2)-ONkfC?~CNN%qY=E%K`1z2Fw6C)DZ6sq=>x2Z@AFy^*ItsW@2;88NSgWPt=>}WV{hiNK3u+zG()hhA5vj zykSV}=lK!RA7!_Lo%R?A;9*eLnF7{u?FdHO)888M^qq3pScNnzK~#GoKEM)g(uQ>- zR2n3LYb2(2IYz;T2wo$H&AkoT4VF1UiY1oMu8B=Gn;>Pvo7mKHvX74I#I(8_)Hpug zc&`zyr_p#IH3AZN~T@hnEqY5Tl)tfzmiOQt1Srj8`9i(b&-U*JJe#Q zP46$dvMp&}Ep6H1H{`AcdShX==YK$&?K%8iQ+?}v6sGB~L}yjHs(z>LM1bvgAs2A) zrsa%pCb2XoT6aL^qG1{@aXoCY-)5d>%3gn0{o#_yr(8KXm>gF2It!4CB$I<|US>k} z!orx$EGYDFjcdG3HcuSX6*Lrmue01NOcd0_LbG@;v;jFYwe*F$eD#Qs?o>#>0}?%> ztWxMiLdk_w%`VBsp2VSnZ_t&bnxlY?w-)oDe|@ilmh|$kj;G4TyzK>F)62h>tJ~n^ z-?($>vJs$-h1*(YJxN?0C8+icjfM2zC_k)M`aHD9p-<{97Yh5B!Z=0Y04P9&pk9(j zA>)*E8N4(W(lZr>4m4m;=#xev*M-6`rm(@{Xhq?pcN|(UWo~E%na7yFQJ4{h`H&Mc z^=o?Qv|xfMj8hb96@?Nf1sm_D7_+s){0A^aES=%ROubJJoxEY?kiPXNIg374y!E#o zdW+*5oR@nB(b)}Ugo2l^K0P_yc#BLYZF&3X#$r2qkKCKyW%>&7MxN(_e2Hn<__gYh zE{>1JLi)|hk)3G3Q0Nk;IH|EN6ecl+sfxmdibB^k3X5GRtY8Z56op?a3cGhZOp1&5;@3wEvOhAkT%y7|Tx)_;-cZ8>wB4w9VQFL}!hAZv0*ImxMe z63;2>%WZqbFpUuId0BBwFR=Q^doTQ^cwCFY>PX|W&5W(R1cvONwQrh4 zoc=*fiBxuAnuc58x}T%NOXDfsMb~NiMM}?u1Q65*Net~fuoMaCQRZn`%z`0Nysf~A z|4jXSVkVYu$|tpS8zPa-;}7$p5%`5fGGnGE+XGZW znjc^sNsC!@$fR`#C`$TdW{r-ALH+xkrdza;cnWLM4Jz~T9{Jc@otfqpuA*4EW+<-H ziEhJ{9;*6RJE_qmoJAMhlQTLdS9G4nzQ2MLH0puuX`!ILP~II)kWGx5m28r#B(j#& zZn4Q{vsisX7S#iE(w0Cw1V*yMplu<&;SH(xeRu-1CZ~Gv=o9(K)R~?c0b`I>%=F=` zD6`lKLVyLK4k7(6C!y4r&5-$DoWGdhw+@0AI0dXv2D&yTsDLgZKi=WZ4AeE|vM8MnAR`i32*{ftt5mZCdO z(oMS29k1w~4@g){(p{kFl9PiWQP$BtqF$uiX+pO#e!_^IByJM5=l2G&>@j#F37y|z zovkXb=UK@rS4hzgaeii%*#tMTR1CB@P1~JRyBc2zV5y916Jj~6j(dhKRxeN@+%H8~ zq(p#5!W9;)KawWL`AQA}y`N_kOZ}>(dy*Sni`91lk{BwhAAU{hC+H>=-5(|0=XphN zM9CLwxozQhM#-Iu?s2@?O?b1D@MatKCTyAR&98V8u*zqEA$zZn63yw&yfmp=+N7d& z2zTo_3sEh%E!ui@w}M^qmSgL`F)FvzbgKsG340gM|#qAXbN8R}jwXZZ${2Jw~56+l_UsIocYZ-kPIg0*tNSHHY_K zsTb|6Nnp#F&udn$U%w&+23J>u#HIKhrG4ZJNc&3%O(EQKOksP2MpX6;BukRqn0*p8Lr4=@m%LP{{#$paFi@MwZo>a zDLlc;)IpN90A9|9VG3RP5Cy)gYyuzKZpvw{a?Id&JU19;FmQNq3+Hy8_@gig3rnug zNJ56(ifct0*HseO#r#^dW>;+c9(L zgI*{W*6W3dZI_P^v%Q{Y4u*I!Al5A%A&Tvw%Wy+aZb6tdLh*qX+5p#-*t z=}#QJtm_fUHBWL)4^weRn-RRHk!smiJ7hVThzw;$sgI&`Ai-npJ(SocFJPw%iIP1w zH>wz!3O2AHV)IWgI*gb4RT{2H_rhqvHRD=K!>vohJx}p{6}ZHf`JU;-rOlVR23I@L zhu7@bUOssU0)n|{EgLQRE+V~6;t9g`dnb$f%T=G_tX%b5olXMq;C-B~StIndUBFzT zMCJZsJ`iTg?SMH54fDK{{mDy#@f|QqAG6l-#Skb+w>Nk%yrRYTd+z-HNX_P48l1*M zS0Aid0mO_Itu(x4##u(!+Kal<@qo8>Zg1agv59U&Ux?|nDw8hTe?_O&a#N5G5s>2a zRduFWtQ%%gUoGR=!-AvS5Q8(7c9($4GBjL%y`rjkF;JlJ3EjZ&qVQJ&^+AcBbmAZ3 zsAc|a66W%@Dm@K=)Ip%Z_t!vCJQ3ZZUS_#Xf@yT2)aTPOZ9h5wzzpQ-TM0d=Cp ze?`^lT=yD>06r=c#S6f(Uz@h38{DI_mUq~SNt&^B5>(8nKg&D@$ToI7eQ7k_Ufk%U zeQ;u;r@k9P`62mk(Zp~$I9SgUgN+C3JYnb*cd``s6RwmHyT-ZHB;}bIfU=(%)NL{+ zxK@p)*sEI34E`h^n`w-_HQZf_S}Damrxcr%eQ!^fVvJ;?ZO7A2b}4$v$2KXR+5*{~ zwlLHdH%oX9{{WIi5sD4MwI0fLw$~Kqd!m^h2ID3{#{+oXKaK8C_c{m!n8qAi;?Y~H zL4CugrX)N+A zs-07V)O;5T3z$L=MWGxNNE~`G@yZ5=4N^%L3b!zYca`tfC<=)*3hP}cyvP*pP!wJU z1r*ppeNq~Q!!8tlU<#J`*#HVci&jnw;y!$PdZ!vajb`J(ZDWuQV<+Rtl&|f?+KXEY z?ZtHk+Z_*a6P_k{s{cTzKlX?8KQ@?7)&lh05aHSvoQ9n4hJ3j~zDyxcNJGBC4Y{vE zzDXf_(~zHbL;jR)&$Hw?APd{S^1M^*f4d=zH|vaiSRvn-hTP{27lV~6&S%hb!(bsN zGQV~_-$O1cY#4*vE^e#xv>0;erI*ibT{M-7x^<%poyAf5qo7 z>VW8Z@Hv2nW#7R|Js=GxV-!(l5>S0+qLdL|$5u=xDJEZlzHgApt?Dv{Fp4iu2nS4oGgyWKZ9_r*xn5IXuMaUVlX1I2Dyw zznNI7M{>UR!c%v&Ab-%%dve24-)ok>na{8w2;Dy7J1UR=WCo>~{`nx6gb}9xn5TtO zdY9~{#*!Aca-9}@gic5p;Y>1zSk6TMeJ*&I(nRQgximrsS3WS8xsI}zHOWe2r_PrB z)B+dQ@PWblZ#=`5{fiXqMc{gaWc?dwK`*ralA~B@{l4s{Zf=_Oa0lzp)Dg>F;JQh& zZsX3nTCx&a7s-C=m8My*`^j$ba>e>haQ#ZMzKJW8G=qP?4g{3epUHmeyQW!>b+8tP zy-evCxDGgz8g^=Dch<`#E1`9{?5FYw*BNFOU%&XHUF*f_oM#NUE|RS86flG@x`QVRa;2kLvA^_WBoqktKf9sPi&OtKWl<&H-Qxt z)-RBQL`@8hkVBT=OX?#Bt-CBzr{)V}4=$!Tzi>n9u}Y5;pO9WpGuW85Jo+~t-R&4% z%cGst4BrGHL44r0pq|D2dHOMpT?{RLgNR4>0lJ$3y@w8ou78+7KgXQy0x;*@q@>lHC-La@ax~SG z29h0Xr+4)5J^g9H!~u54w2&_DN3p?9BPeO!hglwsr>J&p4Et%7h$aBrGqxxY&t5H#cMcBaXOdH~}Ph34heYWM{Vze`QSl|KDdM|d8f@sR$tve&-> zZ4xg~RI&yu;(gR`9}J&O4Tx7dh)<;PkbavYJ_XRGGv50AIEo-R61?+|Ju!Jeah`ym*Z<`+EJLfJVqZus^=X3fJn7@kE9%zsEmw>gX6R;Hg1NRx0_ zQMkcE_yRTjR}8;n5MCn*r#_^iMzknX%svCQ>F57ECH>qX*ARmI{Jt6K{j&2=UKwFO{8L!0Fgr9%w-O%51e7VW0rqlQq~HN<=9 zCvGsE&ikR)uE8?-c@_muiiP3ixeS5yi0n7E?hr}ymJFL}ntt00CUy3omLOq6`pl!I z`KD=cBCXvFYq2(WFu-26JFKnUhexK9m;cp)_?$%C#EAGZ?j@qAzEs!<0N68_>57qKYuk=F~3BwgO{E*~o7?hlT z$mQ&z{NR`UX80l1HjkpaTkYI#VnMn%nE2T6%@M9dS$1wtB*>8d+!2R~PoZJ<&BY;o zJIp&rWVlPUK6qlfX8#i=Ug}&L=j9^NvK1)PkNg>ao?@Z3!bWQbo|wM6P135_a%Q8x zGS;=X*s#NcO8+-?ihxAhw@pk|XnS=T*l15`G!%%<7F39jdR{tQ&@;se% z3-6}Br-4SYVug~p0TP?$_~3C9TkAPQnPaOO9*yBksDU{;%Ndyp(@-PKG8MBjU<>m^ zB~8OTsQvl3BB!YDJWNvGdHCWo}+!p4~IJ* z!YJ`Rn$8bTc6%s(8_N_z`J+S`C2dP8#=C&P%3Wu@Q;3(&tDC&s&x^TvS|Q%mF3WjiB;48lD}`a>;?R z(6}<#&kcXB!jF_L&;;rvHTX2>y(fu=6;WCg==9Zm)t2m1&^10x{K%|%S)a}kdeH9^ z;iCR2;<~Z*dHqL?-P_klW_)vwKMv6D?`9>B4p9(*LH+TEOz#?o=5c$iQ&MX@_$ZB3XVR<6KY`B6V}8%02^xb{wjY@brNDwPGdf=07_W zHSF%Ir5ll5DD3Gg5z(RivXdmcgRdhpqfIp4!yLbv_d#M@d@rYdTVf9A`UEAgJdm28EuGUbNYqA&HiPAHCa4WQstj zeV=ia=~qXau`c{UZPvxaBecq+mNdl zrJ>-&Sa7^idE_$-N=_PzyXftPn}jAvLL~Y|c}$>n2ZV^8cOP_!PJS^qqU!hF5}Wu^ z#Y#zm_O1s0A0)m!w|1B6Lhvl3CZyjkEh@8>Ii=aJI5%%0%Ouyg=d;Xr;kLKu9p&5e zWES3^=NYfo`%rM>ZvGUGBFqf1n9Q37^h{#*7wdfIqnKwGPbLDCFV?G}4Fe=OgCinB zV!%=iTm>lL$}36>A27|WrSQ;v>kd*ueX@G`A)ca8!c zBI=xkEg~jlTxjh8WxE))?S3g@7!U0tKBk`DgQxP9ybv)dAKOIi=_;aOu%l{D?FC6v z+I%H{mOHuEc_yT3e9}n5W|Mp;%RYn08pY#uK;a@Sz9Au`-hH1`xdczKk+sYxD`juJlR)VE6awDAV@=M|3 zTbje@q1YyMroZ9)np8Fz#n@~uuYh>cI4x8!-fP-pwl)RBARE-5v1#|Qe%tmu1ZF!WgALvln3HM${k2aB75RK6Nc9SI+}mJ}n+Yf;YrEVXf3B^6?Ic*T02+ zTpstBDya!S>;Z;BV9aN%i@R@b{|EXN1?OewWc?3nr4{Y|Ta%M%&LdWJq6PNoafy z$X^KT-eAtMOSGOKLh@$Nx54z4cbO4avkW3-#Jgxy0D$WNL4Ce@%yX1a_=E&satJFm z-dBBA<2BW1HJ+D!!_B6|FY;axs)WSJB}=RwQxY$-O8n{{(j~qJ0Hh-QX3P`nu~XvF zQUY<9Fi7=T;!{+gC2p(w+rfYhe-5uGE`~qG+fb((_y45ScpXG2blC8%+~h&KpcDZQo4CBFzO!*YA2tC>Bo_I z>vQsl4243c{n4Z?ta6g-vsGHDK3nD6yCr-9krhM+a*63;75!mTf2(slS;BEFh>+ZD zm4kNx9Gejpj*9>grlFwzhI;ID?mQ(H&#Eb^&uW~l`mDxa)n6smDB|kPMU7Kk)wtl8 zsoW*n%~mxAC^_Y<+M(2FtsXnoSi=)e&8izzpVe5R`mDwR)julLxQk0NsG+qOW4h>i zIp~;w6S#Z^wADowKPlb3AVSaCMHj6}chNWi2p0v^W2bKGIOLUXkE=fGc9-h2Zb{WI zmuhU_5{q?<%E8CvphLGZnI^5e-SVT-?JBEoRkZDKhTj&YTSz^2>h|HCz=Ur6ql#kt ztZ$d2;`Ps3)n^SKRsA2OGVkAON~d|wHodn^4mvcvLFOZ?hEE+eXL^p0P6=FC=;OThOdU^AVbCa)mw^%?vcT6!ZElG%L~k8O;x94v=_y zf3l{&98HWOLEntVPt#UkiDo*bDE(Jx9ze4l%^*t2`V2Ielhpb>XwD+@>o=nL2+iN9 zvd~-JOU(>4>(TV39Ht*dGoM_d??yA9VodKrGhC0Nc^6F&va>#%a<+aun(eeQ>HVno z(08M$pkhkjj%GC#f_iHzCiG{}6w(=po<%PK^|R3|M)M?^PtkOt_bB=lG}oi)ORtgi zIcRQ0^9q`l^rlT8jpivdZ=&f=Hv#ms&|HV+~pVT~n zW>AV64b7j?96-~1Ej828+>GWWG{NVnsYUZLn(TGdj7L+0rrUaIwxD_Pd1~goK+S$M zkqy+mf~LbpYLaL^Koi?U&DUrqY^LT8G=uA?xgX6tXeMu==0P-j(R6r`8eD+X>(R`8 ziJI5YoV}GA+_BZOwox+%O$^OPXhPem*^K7Am#MiL&9i8Fzd}v!tJEw+^AMW-XnMRx z%}zAaUZ-Xknm_KK=3O*h-=JnXnw!yd-bu|xXs$!E9?gHyocSg-2{fa3QF9NPV`%2R zMa_k~so8{P#M{(7fu`>})ZB?CZx1y`(M))kn%aHTOn;x6b3UYI^GDS94p5WzF*Wl( zq2`)@QS;)b)I>j{=1DX&bZSsxA$q1pHyHEX`7rsBWUTzG_8(7AamBD65D?1CcA^;c|fB?2P}7(~16oKNg9`0>zb!s>0QgKt;T~Jg_iQ zT@fh{L}S%u6$=7O%3@j|vZyMyED)})4$~B;3|v$^l0KS^UQt=$LIU3yOe5jO9CBNj zmlXd3OyWgL(9dQFKNJ?>jI%kCMzzZ7SfpCW3YU?gN^+ZtTwYnRz{DjK{xg8uG{(Xi z7QYBj8IA$ona4p>{;;7M6neR0vl9e(lmSa9>_$!YfV#lEw-z6O+TvZjRD2dX841~RdfUs0K$s%}&)&($H z9IgnImQ_b_6ir@3TU;XALFsfEJi4%~DjERsXdqq@D=QC_R>mtBNf0pG;VuLs#g!E$ z0YN7guBO?!M2pY_WEsdzrLjO|X{iwA!e5M^Q&r83%3@_S153kYU@=>31k6c z1hO%ujF0YCQi5BcBpeHiRBnSU>Cq%?V2A;2W~Kg3gNun8;MD_b3?;HQC6Q8th%KeD z=?vj88-#E)@hfS1gkxmdB^Y*4A!0+UA~cgqU)*tYfbXJO|I=}Y)hao9Z|a#M9A7O$>| z2C(`rEsHf1OeCE?R+<#%l&m-#kMawu{>9<)cm%J^C1(qiprJCiE#)#?S(G9q9E+63 z%KGPD;eSfirb~O=_p_cK7RV%YCMmJEfN}GOhWold4QSztl5(n&$|EtdC|7^^L$9<=bwx{TIH&+Dqg7)8tw7;w zkiRm2=xL3RXJ?gDiZbDC*~UVdmv$_Gxl8lIjZrg&&0QLx>Z!DBDG&mroh^M>sG0~B zkpf$C42-skS*=x5V?aHDN)67QT2TIBol$kc~LntzU?9e>%1hAp> zP=DjlHX-O|(;FpwRiwI-Lnyy@<3PEFMsQsqw<$=|Y_`}%TopyArV8ZZE}c{m<5W_( z4i?zl&X7e^ngt31vC2T$jg0Fc{TozHhD@fEei9<1tb&%kvJyX0r=4|}lBOkp!YHHs zm{;NQ^2%b$8rGa{jrLAI22Mu6|ip8=DI{skhVw*`7 zBd8RYAmAlhqXHprDB2C!{)vyh}*P#M5U3sS9X_22~NGo9m!zxcQ_3Cwiim1)g83y1Lzc!~o*Js#V%Gv}JT^XT;b?)9#g+jF7Yog4%@Ug0 zxmvfp6z;b2(Se8=;rEA&Z1aY9ma)o(5z4@9A{zzkQ`+TpwOUC%!*J#J;mMc|2fd%B3mWRhdPMFs5qdaU`A+!i%zu)>Hm#WG6|ddUXE7+ZlM6ew51J2>FW2m=pw{#bCHF@|-DYXq@oiTvW1|n?IB^E_xad{m)Mqkquk&~=eGwY6jo2`!B0t~xNK3l z+);4YR!tZ1Orla?OGYk00UR0tGS?P=ZjiD}aZx{xXd`b0t=kv4Rsz>THwvVvm6!z!*7+x&OsiuA=q+q^KCQ2 z4r<-R&|#!H_@mQMTbwk3R!P@8cq+k#5Y3j_8b_2kbc1e`E!GLAJWQu^=Zu0Mpap^0 z_7Mt#jc!{~Ba6yne4uIUKyeIiixLSS-3^eOJiKxs!{!a~+ftGQM~a~ZtVBRkshykK z2&CyV0a;q=r~h+cDYLbDAkkuv)t8Dw{=xEc7Bz$OB&zh~N0kIX#_)gtfClOcQ2~UnGIzk{s&ULeRlV zpi}Y6P7_HPD<0Mv;QDPRtLy}NivtUd@-K)`R$CZZ=BJ9-&$lB+vB<@hC7e-^UZ4W{ z?demRo)B|53j-qUNge`#sheBOX7aF=!^A_ND^86(&qDwMyt10M8_`HLX%!0>l}G$# zQ9r%FEa&T4P{QUj8%9oU6VLLRcs9f|konmJYd(Vdgq$ar2O<1*er7uIM5 zF5l#9e%h)x$=}RxO+L+Q@@bkxO+x1*Q%32Q8N~&?qKeV03tTH!B(|*1 zC|uFu6$<{sH7VA_lCo%(EK~D_n?rfS;ji4KLr}(!^wZyEdcbAYIK8r8QdSbvM)^$` zyr~-s=)B>!O|1jm0Flu7LyilbKLiUR#Y+x^9cim(9MmNcwwq=rZ@8^QXaps1xD_XV zNON%V`6AuWVYZsjL4W8l|A2~0zgdS2wAFgDy5hUPP%}5rpF6~#o9{=i7kf*3LFw2u z+BQxS$av|1m__w)8huKq2_RH@@=RQA&dgE;w`^=DuFwS6mYwfQ#06a238xFFx&_P1 z*{W0tuI?U3Z56i(KraEUAfjVjb448I`G@%PZK+4Rq-U16MnuNr>#H_*y1)n}n+F9y z`N7$r@Auopb|t)&Zd+JRs%xDlJ=QC2sq{U_&Dyd%mn-VGavZTwo1 z_Poa1)xO8UHg?6fIpxA+l;67T4jzZ7`v$yeK?{BnO+$R!sgR5K?gFt=Bb&?DWuxDY zaOqGK=e(Rx>6cn8Q?4mFjFZT6dV5igBO%_2Hd_=YHu;7_(m0=8dd|-jL%azU$HRs! zWBx}ZNFZB^DyEVW)kL^>A(i%(RkjIhduZGauyVIO$D%zacktl+%lu8l3>`dp#ATRj z{8f!n{wlg0H;Oh&;_@5aLMV;d-rS4lB-=?=x?)raWz$GJP|`H^kj234GQ~hiN82@x zW-beXFOjfeY^6vQ!06=wU757)|9G5)Oa~S+S~w9@b2u@W;Dn5Wud86UOZVsL+BI$$ z)1C85dV@_%5GA)*S-9MfRYYtzQTowRV@rWE!EgzjO)qj4OhCS43L5#c``s zD_cF%6so}xAEfET#w}+kYH$qDHAu@co38ZGUr32pVrhZn%cBg>A~kA|8Gou#%@b_WwR8;yy@H*}3Mm*cV| qV#_G}rck`tGQNs{Sc-&~@<*}wC=nk;;v-tc&x*uHw2XTtW&a0fb&ym5 literal 45057 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 diff --git a/apps/hex.subx b/apps/hex.subx index 80469961..09e394bd 100644 --- a/apps/hex.subx +++ b/apps/hex.subx @@ -44,8 +44,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto interactive - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto interactive + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-hex-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -54,7 +54,7 @@ Entry: # run tests if necessary, convert stdin if not eb/jump $subx-hex-main:end/disp8 $subx-hex-main:interactive: # - otherwise convert stdin - # var ed/eax : exit-descriptor + # var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # configure ed to really exit() @@ -247,7 +247,7 @@ test-convert-next-octet: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -337,7 +337,7 @@ test-convert-next-octet-handles-Eof: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # don't initialize '_test-stream' # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -435,7 +435,7 @@ test-convert-next-octet-aborts-on-single-hex-byte: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'convert-next-octet' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -604,7 +604,7 @@ test-scan-next-byte: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -702,7 +702,7 @@ test-scan-next-byte-skips-whitespace: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -808,7 +808,7 @@ test-scan-next-byte-skips-comment: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -914,7 +914,7 @@ test-scan-next-byte-skips-comment-and-whitespace: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -1022,7 +1022,7 @@ test-scan-next-byte-skips-whitespace-and-comment: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -1120,7 +1120,7 @@ test-scan-next-byte-reads-final-byte: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -1210,7 +1210,7 @@ test-scan-next-byte-handles-Eof: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp # leave '_test-stream' empty # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) @@ -1308,7 +1308,7 @@ test-scan-next-byte-aborts-on-invalid-byte: # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # initialize exit-descriptor 'ed' for the call to 'scan-next-byte' below - # . var ed/ecx : exit-descriptor + # . var ed/ecx : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx # . tailor-exit-descriptor(ed, 12) diff --git a/apps/mu b/apps/mu index e95a43f1e9732c097bf0e0851069c945200ba6ca..0e2717c7d3316792ab3489a06f699f9f6135dcbf 100755 GIT binary patch literal 63183 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 eax (populate-mu-function-header %ecx %eax) (populate-mu-function-body *(ebp+8) %eax) @@ -743,9 +749,10 @@ $parse-mu:abort: # ✓ fn foo x : int { # ✓ fn foo x: int { # ✓ fn foo x: int -> y/eax: int { -populate-mu-function-header: # first-line : (address stream byte), out : (address function) +populate-mu-function-header: # first-line : (address stream byte), out : (handle function) # pseudocode: - # var name : slice = next-word(first-line) + # var name : (ref slice) + # next-word(first-line, name) # assert(name not in '{' '}' '->') # out->name = slice-to-string(name) # ## inouts @@ -755,14 +762,14 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre # if (name == '{') goto done # if (name == '->') break # assert(name != '}') - # var v : (address var) = parse-var-with-type(name, first-line) + # var v : (handle var) = parse-var-with-type(name, first-line) # out->inouts = append(out->inouts, v) # ## outputs # while true # ## name # name = next-word(first-line) # assert(name not in '{' '}' '->') - # var v : (address var) = parse-var-with-type(name, first-line) + # var v : (handle var) = parse-var-with-type(name, first-line) # out->outputs = append(out->outputs, v) # done: # @@ -775,7 +782,7 @@ populate-mu-function-header: # first-line : (address stream byte), out : (addre 57/push-edi # edi = out 8b/-> *(ebp+0xc) 7/r32/edi - # var word-slice/ecx : slice + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -875,7 +882,7 @@ test-function-header-with-arg: # setup (clear-stream _test-input-stream) (write _test-input-stream "foo n : int {\n") - # result/ecx : (address function) + # result/ecx : (ref function) 2b/subtract-> *Function-size 4/r32/esp 89/<- %ecx 4/r32/esp (zero-out %ecx *Function-size) @@ -883,9 +890,9 @@ test-function-header-with-arg: (populate-mu-function-header _test-input-stream %ecx) # check result (check-strings-equal *ecx "foo" "F - test-function-header-with-arg/name") # Function-name - # edx : (address list var) = result->inouts + # edx : (handle list var) = result->inouts 8b/-> *(ecx+8) 2/r32/edx # Function-inouts - # ebx : (address var) = result->inouts->value + # ebx : (handle var) = result->inouts->value 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "n" "F - test-function-header-with-arg/inout:0") # Var-name (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type @@ -902,7 +909,7 @@ test-function-header-with-multiple-args: # setup (clear-stream _test-input-stream) (write _test-input-stream "foo a: int, b: int c: int {\n") - # result/ecx : (address function) + # result/ecx : (handle function) 2b/subtract-> *Function-size 4/r32/esp 89/<- %ecx 4/r32/esp (zero-out %ecx *Function-size) @@ -910,9 +917,9 @@ test-function-header-with-multiple-args: (populate-mu-function-header _test-input-stream %ecx) # check result (check-strings-equal *ecx "foo") # Function-name - # edx : (address list var) = result->inouts + # edx : (handle list var) = result->inouts 8b/-> *(ecx+8) 2/r32/edx # Function-inouts - # ebx : (address var) = result->inouts->value + # ebx : (handle var) = result->inouts->value 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type @@ -941,7 +948,7 @@ test-function-with-multiple-args-and-outputs: # setup (clear-stream _test-input-stream) (write _test-input-stream "foo a: int, b: int, c: int -> x/ecx: int y/edx : int {\n") - # result/ecx : (address function) + # result/ecx : (handle function) 2b/subtract-> *Function-size 4/r32/esp 89/<- %ecx 4/r32/esp (zero-out %ecx *Function-size) @@ -949,9 +956,9 @@ test-function-with-multiple-args-and-outputs: (populate-mu-function-header _test-input-stream %ecx) # check result (check-strings-equal *ecx "foo") # Function-name - # edx : (address list var) = result->inouts + # edx : (handle list var) = result->inouts 8b/-> *(ecx+8) 2/r32/edx # Function-inouts - # ebx : (address var) = result->inouts->value + # ebx : (handle var) = result->inouts->value 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "a" "F - test-function-header-with-multiple-args/inout:0") # Var-name (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:0/type") # Var-type @@ -967,9 +974,9 @@ test-function-with-multiple-args-and-outputs: 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "c" "F - test-function-header-with-multiple-args/inout:2") # Var-name (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/inout:2/type") # Var-type - # edx : (address list var) = result->outputs + # edx : (handle list var) = result->outputs 8b/-> *(ecx+0xc) 2/r32/edx # Function-outputs - # ebx : (address var) = result->outputs->value + # ebx : (handle var) = result->outputs->value 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "x" "F - test-function-header-with-multiple-args/output:0") # Var-name (check-ints-equal *(ebx+4) 1 "F - test-function-header-with-arg/output:0/type") # Var-type @@ -991,12 +998,12 @@ test-function-with-multiple-args-and-outputs: # x: int # x: int, # ignores at most one trailing colon or comma -parse-var-with-type: # name: slice, first-line: (address stream) -> result/eax: (address var) +parse-var-with-type: # name: (address slice), first-line: (address stream byte) -> result/eax: (handle var) # pseudocode: - # var v : (address var) = allocate(Heap, Var-size) - # var s : slice + # var v : (handle var) = allocate(Heap, Var-size) + # var s : (ref slice) # next-token-from-slice(name->start, name->end, '/', s) - # var end : address = s->end + # var end : (address byte) = s->end # if (slice-ends-with(s, ":")) # decrement s->end # if (slice-ends-with(s, ",")) @@ -1030,12 +1037,12 @@ parse-var-with-type: # name: slice, first-line: (address stream) -> result/eax: 53/push-ebx 56/push-esi 57/push-edi - # var result/edi : (address var) = allocate(Heap, Var-size) + # var result/edi : (handle var) = allocate(Heap, Var-size) (allocate Heap *Var-size) 89/<- %edi 0/r32/eax # esi = name 8b/-> *(ebp+8) 6/r32/esi - # var s/ecx : slice + # var s/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1160,7 +1167,7 @@ $parse-var-with-type:abort: cd/syscall 0x80/imm8 # never gets here -next-mu-token: # in: (address stream), out: (address slice) +next-mu-token: # in: (address stream byte), out: (address slice) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -1201,7 +1208,7 @@ $next-mu-token:end: 5d/pop-to-ebp c3/return -type-for: # name: (address slice) -> result/eax: type-tree +type-for: # name: (address slice) -> result/eax: (handle s-expression type-id) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -1227,7 +1234,7 @@ test-parse-var-with-type: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1254,7 +1261,7 @@ test-parse-var-with-type-and-register: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1283,7 +1290,7 @@ test-parse-var-with-trailing-characters: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1314,7 +1321,7 @@ is-identifier?: # in : (address slice) -> result/eax : boolean (slice-empty? *(ebp+8)) # => eax 3d/compare-eax-and 0/imm32 75/jump-if-not-equal $is-identifier?:false/disp8 - # var c/eax : char = *in->start + # var c/eax : byte = *in->start 8b/-> *(ebp+8) 0/r32/eax 8b/-> *eax 0/r32/eax 8a/copy-byte *eax 0/r32/AL @@ -1354,7 +1361,7 @@ test-is-identifier-dollar: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1375,7 +1382,7 @@ test-is-identifier-underscore: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1396,7 +1403,7 @@ test-is-identifier-a: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1417,7 +1424,7 @@ test-is-identifier-z: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1438,7 +1445,7 @@ test-is-identifier-A: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1459,7 +1466,7 @@ test-is-identifier-Z: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1481,7 +1488,7 @@ test-is-identifier-@: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1503,7 +1510,7 @@ test-is-identifier-square-bracket: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1525,7 +1532,7 @@ test-is-identifier-backtick: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1547,7 +1554,7 @@ test-is-identifier-curly-brace-open: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1568,7 +1575,7 @@ test-is-identifier-curly-brace-close: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1590,7 +1597,7 @@ test-is-identifier-hyphen: 8b/-> *eax 1/r32/ecx 8d/copy-address *(eax+ecx+4) 1/r32/ecx 05/add-to-eax 4/imm32 - # var slice/ecx = {eax, ecx} + # var slice/ecx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/<- %ecx 4/r32/esp @@ -1602,7 +1609,7 @@ test-is-identifier-hyphen: 5d/pop-to-ebp c3/return -populate-mu-function-body: # in : (address buffered-file), out : (address function) +populate-mu-function-body: # in : (address buffered-file), out : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -1614,7 +1621,7 @@ populate-mu-function-body: # in : (address buffered-file), out : (address funct 8b/-> *(ebp+8) 6/r32/esi # edi = out 8b/-> *(ebp+0xc) 7/r32/edi - # var eax : (address block) = parse-mu-block(in) + # var eax : (handle block) = parse-mu-block(in) (parse-mu-block %esi) # => eax # out->body = eax 89/<- *(edi+0x10) 0/r32/eax # Function-body @@ -1629,10 +1636,10 @@ $populate-mu-function-body:end: c3/return # parses a block, assuming that the leading '{' has already been read by the caller -parse-mu-block: # in : (address buffered-file) -> result/eax : (address block) +parse-mu-block: # in : (address buffered-file) -> result/eax : (handle block) # pseudocode: - # var line : (stream byte 512) - # var word-slice : slice + # var line : (ref stream byte 512) + # var word-slice : (ref slice) # result/eax = allocate(Heap, Stmt-size) # result->tag = 0/Block # while true # line loop @@ -1670,13 +1677,13 @@ parse-mu-block: # in : (address buffered-file) -> result/eax : (address block) 53/push-ebx 56/push-esi 57/push-edi - # var line/ecx : (stream byte 512) + # var line/ecx : (ref stream byte 512) 81 5/subop/subtract %esp 0x200/imm32 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/<- %ecx 4/r32/esp - # var word-slice/edx : slice + # var word-slice/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %edx 4/r32/esp @@ -1791,14 +1798,14 @@ $parse-mu-block:abort: cd/syscall 0x80/imm8 # never gets here -check-no-tokens-left: # line : (address stream) +check-no-tokens-left: # line : (address stream byte) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 50/push-eax 51/push-ecx - # var s/ecx : slice = next-word(line) + # var s/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -1838,10 +1845,10 @@ $check-no-tokens-left:end: 5d/pop-to-ebp c3/return -parse-mu-named-block: # name : (address slice), first-line : (address stream), in : (address buffered-file) -> result/eax : (address stmt) +parse-mu-named-block: # name : (address slice), first-line : (address stream byte), in : (address buffered-file) -> result/eax : (handle stmt) # pseudocode: - # var line : (stream byte 512) - # var word-slice : slice + # var line : (ref stream byte 512) + # var word-slice : (ref slice) # result/eax = allocate(Heap, Stmt-size) # result->tag = 4/Named-block # result->name = name @@ -1882,7 +1889,7 @@ $parse-mu-named-block:end: 5d/pop-to-ebp c3/return -parse-mu-var-def: # line : (address stream) -> result/eax : (address stmt) +parse-mu-var-def: # line : (address stream byte) -> result/eax : (handle stmt) # pseudocode: # # . prologue @@ -1897,10 +1904,10 @@ $parse-mu-var-def:end: 5d/pop-to-ebp c3/return -parse-mu-stmt: # line : (address stream) -> result/eax : (address stmt) +parse-mu-stmt: # line : (address stream byte) -> result/eax : (handle stmt) # pseudocode: - # var name : slice - # var v : (address var) + # var name : (ref slice) + # var v : (ref var) # result = allocate(Heap, Stmt-size) # if stmt-has-outputs?(line) # while true @@ -1921,11 +1928,11 @@ parse-mu-stmt: # line : (address stream) -> result/eax : (address stmt) # . save registers 51/push-ecx 57/push-edi - # var name/ecx : (address slice) + # var name/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp - # var result/edi : (address stmt) + # result/edi : (handle stmt) (allocate Heap *Stmt-size) 89/<- %edi 0/r32/eax # result->tag = 1/stmt @@ -2017,13 +2024,13 @@ $parse-mu-stmt:abort2: cd/syscall 0x80/imm8 # never gets here -stmt-has-outputs?: # line : (address stream) -> result/eax : boolean +stmt-has-outputs?: # line : (address stream byte) -> result/eax : boolean # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx - # var word-slice/ecx : slice + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/<- %ecx 4/r32/esp @@ -2063,7 +2070,7 @@ $stmt-has-outputs:end: 5d/pop-to-ebp c3/return -parse-var: # ad: allocation-descriptor, name: (address slice) -> result/eax: (address var) +parse-var: # ad: allocation-descriptor, name: (address slice) -> result/eax: (handle var) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2099,9 +2106,9 @@ test-parse-mu-stmt: (parse-mu-stmt _test-input-stream) # check result (check-strings-equal *(eax+4) "increment" "F - test-parse-mu-stmt/name") # Stmt1-operation - # edx : (address list var) = result->inouts + # edx : (handle list var) = result->inouts 8b/-> *(eax+8) 2/r32/edx # Stmt1-inouts - # ebx : (address var) = result->inouts->value + # ebx : (handle var) = result->inouts->value 8b/-> *edx 3/r32/ebx # List-value (check-strings-equal *ebx "n" "F - test-parse-mu-stmt/inout:0") # Var-name # . epilogue @@ -2109,7 +2116,7 @@ test-parse-mu-stmt: 5d/pop-to-ebp c3/return -new-function: # ad: allocation-descriptor, name: string, subx-name: string, inouts: (address list var), outputs: (address list var), body: (address block), next: (address function) -> result/eax: (address function) +new-function: # ad: allocation-descriptor, name: string, subx-name: string, inouts: (handle list var), outputs: (handle list var), body: (handle block), next: (handle function) -> result/eax: (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2137,7 +2144,7 @@ $new-function:end: 5d/pop-to-ebp c3/return -new-var: # ad: allocation-descriptor, name: string, type: int, block: int, stack-offset: int, register: string -> result/eax: (address var) +new-var: # ad: allocation-descriptor, name: string, type: int, block: int, stack-offset: int, register: string -> result/eax: (handle var) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2163,7 +2170,7 @@ $new-var:end: 5d/pop-to-ebp c3/return -new-block: # ad: allocation-descriptor, data: (address list statement) -> result/eax: (address statement) +new-block: # ad: allocation-descriptor, data: (handle list statement) -> result/eax: (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2182,7 +2189,7 @@ $new-block:end: 5d/pop-to-ebp c3/return -new-stmt: # ad: allocation-descriptor, operation: string, inouts: (address list var), outputs: (address list var) -> result/eax: (address statement) +new-stmt: # ad: allocation-descriptor, operation: string, inouts: (handle list var), outputs: (handle list var) -> result/eax: (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2205,7 +2212,7 @@ $new-stmt:end: 5d/pop-to-ebp c3/return -new-vardef: # ad: allocation-descriptor, name: string, type: int -> result/eax: (address statement) +new-vardef: # ad: allocation-descriptor, name: string, type: int -> result/eax: (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2226,7 +2233,7 @@ $new-vardef:end: 5d/pop-to-ebp c3/return -new-regvardef: # ad: allocation-descriptor, name: string, type: int, register: string -> result/eax: (address statement) +new-regvardef: # ad: allocation-descriptor, name: string, type: int, register: string -> result/eax: (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2249,7 +2256,7 @@ $new-regvardef:end: 5d/pop-to-ebp c3/return -new-named-block: # ad: allocation-descriptor, name: string, data: (address list statement) -> result/eax: (address statement) +new-named-block: # ad: allocation-descriptor, name: string, data: (handle list statement) -> result/eax: (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2270,7 +2277,7 @@ $new-named-block:end: 5d/pop-to-ebp c3/return -new-list: # ad: allocation-descriptor, value: _type, next: (address list _type) -> result/eax : (address list _type) +new-list: # ad: allocation-descriptor, value: _type, next: (handle list _type) -> result/eax : (handle list _type) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2290,7 +2297,7 @@ $new-list:end: 5d/pop-to-ebp c3/return -append-list: # ad: allocation-descriptor, value: _type, list: (address list _type) -> result/eax : (address list _type) +append-list: # ad: allocation-descriptor, value: _type, list: (handle list _type) -> result/eax : (handle list _type) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2326,7 +2333,7 @@ $append-list:end: 5d/pop-to-ebp c3/return -append-to-block: # ad: allocation-descriptor, block: (address block), x: (address stmt) +append-to-block: # ad: allocation-descriptor, block: (handle block), x: (handle stmt) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2373,10 +2380,10 @@ emit-subx: # out : (address buffered-file) 57/push-edi # edi = out 8b/-> *(ebp+8) 7/r32/edi - # var curr/ecx : (address function) = Program + # var curr/ecx : (handle function) = Program 8b/-> *Program 1/r32/ecx { - # if (curr == NULL) break + # if (curr == null) break 81 7/subop/compare %ecx 0/imm32 0f 84/jump-if-equal break/disp32 (emit-subx-function %edi %ecx) @@ -2394,7 +2401,7 @@ $emit-subx:end: 5d/pop-to-ebp c3/return -emit-subx-function: # out : (address buffered-file), f : (address function) +emit-subx-function: # out : (address buffered-file), f : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2422,11 +2429,11 @@ $emit-subx-function:end: 5d/pop-to-ebp c3/return -emit-subx-block: # out : (address buffered-file), block : (address block) +emit-subx-block: # out : (address buffered-file), block : (handle block) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp - # curr/esi : (address list statement) = block->statements + # curr/esi : (handle list statement) = block->statements 8b/-> *(ebp+0xc) 6/r32/esi 8b/-> *(esi+4) 6/r32/esi # Block-statements # @@ -2451,7 +2458,7 @@ $emit-subx-block:end: 5d/pop-to-ebp c3/return -emit-subx-statement: # out : (address buffered-file), stmt : (address statement), vars : (stack var), primitives : (address primitive), functions : (address function) +emit-subx-statement: # out : (address buffered-file), stmt : (handle statement), vars : (handle stack var), primitives : (handle primitive), functions : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2614,7 +2621,7 @@ Lit-var: 0/imm32/no-register == code -emit-subx-primitive: # out : (address buffered-file), stmt : (address statement), vars : (address variable), primitive : (address function) +emit-subx-primitive: # out : (address buffered-file), stmt : (handle statement), vars : (handle variable), primitive : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2640,7 +2647,7 @@ $emit-subx-primitive:end: 5d/pop-to-ebp c3/return -emit-subx-rm32: # out : (address buffered-file), l : arg-location, stmt : (address statement) +emit-subx-rm32: # out : (address buffered-file), l : arg-location, stmt : (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2660,7 +2667,7 @@ $emit-subx-rm32:end: 5d/pop-to-ebp c3/return -get-stmt-operand-from-arg-location: # stmt : (address statement), l : arg-location -> var/eax : (address variable) +get-stmt-operand-from-arg-location: # stmt : (handle statement), l : arg-location -> var/eax : (handle variable) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2720,7 +2727,7 @@ $get-stmt-operand-from-arg-location:abort: cd/syscall 0x80/imm8 # never gets here -emit-subx-r32: # out : (address buffered-file), l : arg-location, stmt : (address statement) +emit-subx-r32: # out : (address buffered-file), l : arg-location, stmt : (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2745,7 +2752,7 @@ $emit-subx-r32:end: 5d/pop-to-ebp c3/return -emit-subx-imm32: # out : (address buffered-file), l : arg-location, stmt : (address statement) +emit-subx-imm32: # out : (address buffered-file), l : arg-location, stmt : (handle statement) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2769,7 +2776,7 @@ $emit-subx-imm32:end: 5d/pop-to-ebp c3/return -emit-subx-call: # out : (address buffered-file), stmt : (address statement), vars : (address variable), callee : (address function) +emit-subx-call: # out : (address buffered-file), stmt : (handle statement), vars : (handle variable), callee : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2782,7 +2789,7 @@ emit-subx-call: # out : (address buffered-file), stmt : (address statement), va 8b/-> *(ebp+0x14) 1/r32/ecx (write-buffered *(ebp+8) *(ecx+4)) # Function-subx-name # - emit arguments - # var curr/ecx : (list var) = stmt->inouts + # var curr/ecx : (handle list var) = stmt->inouts 8b/-> *(ebp+0xc) 1/r32/ecx 8b/-> *(ecx+8) 1/r32/ecx # Stmt1-inouts { @@ -2805,7 +2812,7 @@ $emit-subx-call:end: 5d/pop-to-ebp c3/return -emit-subx-call-operand: # out : (address buffered-file), operand : (address variable) +emit-subx-call-operand: # out : (address buffered-file), operand : (handle variable) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2831,7 +2838,7 @@ $emit-subx-call-operand:end: 5d/pop-to-ebp c3/return -emit-subx-var-as-rm32: # out : (address buffered-file), operand : (address variable) +emit-subx-var-as-rm32: # out : (address buffered-file), operand : (handle variable) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2866,19 +2873,19 @@ $emit-subx-var-as-rm32:end: 5d/pop-to-ebp c3/return -find-matching-function: # functions : (address function), stmt : (address statement) -> result/eax : (address function) +find-matching-function: # functions : (address function), stmt : (handle statement) -> result/eax : (handle function) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx - # var curr/ecx : (address function) = functions + # var curr/ecx : (handle function) = functions 8b/-> *(ebp+8) 1/r32/ecx { # if (curr == null) break 81 7/subop/compare %ecx 0/imm32 74/jump-if-equal break/disp8 - # if match(curr, stmt) return curr + # if match(stmt, curr) return curr { (mu-stmt-matches-function? *(ebp+0xc) %ecx) # => eax 3d/compare-eax-and 0/imm32 @@ -2900,13 +2907,13 @@ $find-matching-function:end: 5d/pop-to-ebp c3/return -find-matching-primitive: # primitives : (address primitive), stmt : (address statement) -> result/eax : (address primitive) +find-matching-primitive: # primitives : (handle primitive), stmt : (handle statement) -> result/eax : (handle primitive) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx - # var curr/ecx : (address primitive) = primitives + # var curr/ecx : (handle primitive) = primitives 8b/-> *(ebp+8) 1/r32/ecx { $find-matching-primitive:loop: @@ -2936,7 +2943,7 @@ $find-matching-primitive:end: 5d/pop-to-ebp c3/return -mu-stmt-matches-function?: # stmt : (address statement), function : (address opcode-info) => result/eax : boolean +mu-stmt-matches-function?: # stmt : (handle statement), function : (handle function) => result/eax : boolean # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -2954,7 +2961,7 @@ $mu-stmt-matches-function?:end: 5d/pop-to-ebp c3/return -mu-stmt-matches-primitive?: # stmt : (address statement), primitive : (address primitive) => result/eax : boolean +mu-stmt-matches-primitive?: # stmt : (handle statement), primitive : (handle primitive) => result/eax : boolean # A mu stmt matches a primitive if the name matches, all the inout vars # match, and all the output vars match. # Vars match if types match and registers match. @@ -3080,7 +3087,7 @@ $mu-stmt-matches-primitive?:end: 5d/pop-to-ebp c3/return -operand-matches-primitive?: # var : (address var), primout-var : (address var) => result/eax : boolean +operand-matches-primitive?: # var : (handle var), primout-var : (handle var) => result/eax : boolean # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -3153,30 +3160,30 @@ test-emit-subx-statement-primitive: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var + # var var-foo/ecx : (ref var) 68/push 0/imm32/no-register 68/push -8/imm32/stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # operand/ebx : (list var) + # var operand/ebx : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %ebx 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 53/push-ebx/operands 68/push "increment"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # primitives/ebx : primitive + # var primitives/ebx : (ref primitive) 68/push 0/imm32/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3226,41 +3233,41 @@ test-emit-subx-statement-primitive-register: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var in eax + # var var-foo/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # operand/ebx : (list var) + # var operand/ebx : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %ebx 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 53/push-ebx/outputs 68/push 0/imm32/inouts 68/push "increment"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # formal-var/ebx : var in any register + # var formal-var/ebx : (ref var) in any register 68/push Any-register/imm32 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "dummy"/imm32 89/<- %ebx 4/r32/esp - # operand/ebx : (list var) + # var operand/ebx : (ref list var) 68/push 0/imm32/next 53/push-ebx/formal-var 89/<- %ebx 4/r32/esp - # primitives/ebx : primitive + # var primitives/ebx : (ref primitive) 68/push 0/imm32/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3313,41 +3320,41 @@ test-emit-subx-statement-select-primitive: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var in eax + # var var-foo/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # real-outputs/edi : (list var) + # var real-outputs/edi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 57/push-edi/outputs 68/push 0/imm32/inouts 68/push "increment"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # formal-var/ebx : var in any register + # var formal-var/ebx : (ref var) in any register 68/push Any-register/imm32 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "dummy"/imm32 89/<- %ebx 4/r32/esp - # formal-outputs/ebx : (list var) + # var formal-outputs/ebx : (ref list var) = {formal-var, 0} 68/push 0/imm32/next 53/push-ebx/formal-var 89/<- %ebx 4/r32/esp - # primitive1/ebx : primitive + # var primitive1/ebx : (ref primitive) 68/push 0/imm32/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3357,7 +3364,7 @@ test-emit-subx-statement-select-primitive: 68/push 0/imm32/inouts 68/push "increment"/imm32/name 89/<- %ebx 4/r32/esp - # primitives/ebx : primitive + # var primitives/ebx : (ref primitive) 53/push-ebx/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3410,41 +3417,41 @@ test-emit-subx-statement-select-primitive-2: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var in eax + # var var-foo/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # inouts/edi : (list var) + # var inouts/edi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 57/push-edi/inouts 68/push "increment"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # formal-var/ebx : var in any register + # var formal-var/ebx : (ref var) in any register 68/push Any-register/imm32 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "dummy"/imm32 89/<- %ebx 4/r32/esp - # operand/ebx : (list var) + # var operand/ebx : (ref list var) 68/push 0/imm32/next 53/push-ebx/formal-var 89/<- %ebx 4/r32/esp - # primitive1/ebx : primitive + # var primitive1/ebx : primitive 68/push 0/imm32/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3454,7 +3461,7 @@ test-emit-subx-statement-select-primitive-2: 68/push 0/imm32/inouts 68/push "increment"/imm32/name 89/<- %ebx 4/r32/esp - # primitives/ebx : primitive + # var primitives/ebx : (ref primitive) 53/push-ebx/next 68/push 0/imm32/no-imm32 68/push 0/imm32/no-r32 @@ -3501,23 +3508,23 @@ test-increment-register: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var in eax + # var var-foo/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # real-outputs/edi : (list var) + # var real-outputs/edi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 57/push-edi/outputs 68/push 0/imm32/inouts @@ -3561,23 +3568,23 @@ test-increment-var: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var in eax + # var var-foo/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx : (stack 1) + # var vars/edx : (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # inouts/edi : (list var) + # var inouts/edi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 57/push-edi/inouts @@ -3611,29 +3618,29 @@ test-add-reg-to-reg: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-var1/ecx : var in eax + # var var-var1/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var1"/imm32 89/<- %ecx 4/r32/esp - # var-var2/edx : var in ecx + # var var-var2/edx : (ref var) in ecx 68/push "ecx"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var2"/imm32 89/<- %edx 4/r32/esp - # inouts/esi : (list var2) + # var inouts/esi : (ref list var2) 68/push 0/imm32/next 52/push-edx/var-var2 89/<- %esi 4/r32/esp - # outputs/edi : (list var1) + # var outputs/edi : (ref list var1) 68/push 0/imm32/next 51/push-ecx/var-var1 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 57/push-edi/outputs 56/push-esi/inouts @@ -3667,29 +3674,29 @@ test-add-reg-to-mem: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-var1/ecx : var + # var var-var1/ecx : (ref var) 68/push 0/imm32/no-register 68/push 8/imm32/stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var1"/imm32 89/<- %ecx 4/r32/esp - # var-var2/edx : var in ecx + # var var-var2/edx : (ref var) in ecx 68/push "ecx"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var2"/imm32 89/<- %edx 4/r32/esp - # inouts/esi : (list var2) + # var inouts/esi : (ref list var2) 68/push 0/imm32/next 52/push-edx/var-var2 89/<- %esi 4/r32/esp - # inouts = (list var1 var2) + # var inouts = (ref list var1 var2) 56/push-esi/next 51/push-ecx/var-var1 89/<- %esi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 56/push-esi/inouts @@ -3723,29 +3730,29 @@ test-add-mem-to-reg: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-var1/ecx : var in eax + # var var-var1/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var1"/imm32 89/<- %ecx 4/r32/esp - # var-var2/edx : var + # var var-var2/edx : (ref var) 68/push 0/imm32/no-register 68/push 8/imm32/stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var2"/imm32 89/<- %edx 4/r32/esp - # inouts/esi : (list var2) + # var inouts/esi : (ref list var2) 68/push 0/imm32/next 52/push-edx/var-var2 89/<- %esi 4/r32/esp - # outputs/edi : (list var1) + # var outputs/edi : (ref list var1) 68/push 0/imm32/next 51/push-ecx/var-var1 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 57/push-edi/outputs 56/push-esi/inouts @@ -3779,29 +3786,29 @@ test-add-literal-to-reg: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-var1/ecx : var in eax + # var var-var1/ecx : (ref var) in eax 68/push "eax"/imm32/register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var1"/imm32 89/<- %ecx 4/r32/esp - # var-var2/edx : var literal + # var var-var2/edx : (ref var) literal 68/push 0/imm32/no-register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 0/imm32/type-literal 68/push "0x34"/imm32 89/<- %edx 4/r32/esp - # inouts/esi : (list var2) + # var inouts/esi : (ref list var2) 68/push 0/imm32/next 52/push-edx/var-var2 89/<- %esi 4/r32/esp - # outputs/edi : (list var1) + # var outputs/edi : (ref list var1) 68/push 0/imm32/next 51/push-ecx/var-var1 89/<- %edi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 57/push-edi/outputs 56/push-esi/inouts @@ -3835,29 +3842,29 @@ test-add-literal-to-mem: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-var1/ecx : var + # var var-var1/ecx : (ref var) 68/push 0/imm32/no-register 68/push 8/imm32/stack-offset 68/push 1/imm32/block-depth 68/push 1/imm32/type-int 68/push "var1"/imm32 89/<- %ecx 4/r32/esp - # var-var2/edx : var literal + # var var-var2/edx : (ref var) literal 68/push 0/imm32/no-register 68/push 0/imm32/no-stack-offset 68/push 1/imm32/block-depth 68/push 0/imm32/type-literal 68/push "0x34"/imm32 89/<- %edx 4/r32/esp - # inouts/esi : (list var2) + # var inouts/esi : (ref list var2) 68/push 0/imm32/next 52/push-edx/var-var2 89/<- %esi 4/r32/esp - # inouts = (list var1 inouts) + # var inouts = (ref list var1 inouts) 56/push-esi/next 51/push-ecx/var-var1 89/<- %esi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 56/push-esi/inouts @@ -3906,30 +3913,30 @@ test-emit-subx-statement-function-call: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : var + # var var-foo/ecx : (ref var) 68/push 0/imm32/no-register 68/push -8/imm32/stack-offset 68/push 0/imm32/block-depth 68/push 1/imm32/type-int 68/push "foo"/imm32 89/<- %ecx 4/r32/esp - # vars/edx = (stack 1) + # var vars/edx = (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # operands/esi : (list var) + # var operands/esi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %esi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 56/push-esi/inouts 68/push "f"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # functions/ebx : function + # var functions/ebx : (ref function) 68/push 0/imm32/next 68/push 0/imm32/body 68/push 0/imm32/outputs @@ -3965,30 +3972,30 @@ test-emit-subx-statement-function-call-with-literal-arg: # setup (clear-stream _test-output-stream) (clear-stream $_test-output-buffered-file->buffer) - # var-foo/ecx : literal + # var var-foo/ecx : (ref var) literal 68/push 0/imm32/no-register 68/push 0/imm32/no-stack-offset 68/push 0/imm32/block-depth 68/push 0/imm32/type-literal 68/push "34"/imm32 89/<- %ecx 4/r32/esp - # vars/edx = (stack 1) + # var vars/edx = (ref stack 1) 51/push-ecx/var-foo 68/push 1/imm32/data-length 68/push 1/imm32/top 89/<- %edx 4/r32/esp - # operands/esi : (list var) + # var operands/esi : (ref list var) 68/push 0/imm32/next 51/push-ecx/var-foo 89/<- %esi 4/r32/esp - # stmt/esi : statement + # var stmt/esi : (ref statement) 68/push 0/imm32/next 68/push 0/imm32/outputs 56/push-esi/inouts 68/push "f"/imm32/operation 68/push 1/imm32 89/<- %esi 4/r32/esp - # functions/ebx : function + # var functions/ebx : (ref function) 68/push 0/imm32/next 68/push 0/imm32/body 68/push 0/imm32/outputs diff --git a/apps/mulisp.subx b/apps/mulisp.subx index 71ad170c..1cfdeb03 100644 --- a/apps/mulisp.subx +++ b/apps/mulisp.subx @@ -81,12 +81,12 @@ repl: # in : (address buffered-file), out : (address buffered-file) # . save registers 50/push-eax { - (lisp-read Stdin) # => eax : (address cell) + (lisp-read Stdin) # => eax : (handle cell) # if (eax == 0) break 3d/compare-eax-and 0/imm32 74/jump-if-equal break/disp8 # - (lisp-eval %eax) # => eax : (address cell) + (lisp-eval %eax) # => eax : (handle cell) (lisp-print Stdout %eax) eb/jump loop/disp8 } @@ -104,13 +104,13 @@ $repl:end: # arrays start with '[' # symbols start with anything else but quote, backquote, unquote or splice # only one s-expression per line -lisp-read: # in : (address buffered-file) -> eax : (address cell) +lisp-read: # in : (address buffered-file) -> eax : (handle cell) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # . save registers 51/push-ecx - # var s/ecx : (stream byte 512) + # var s/ecx : (ref stream byte 512) 81 5/subop/subtract %esp 0x200/imm32 68/push 0x200/imm32/size 68/push 0/imm32/read @@ -142,14 +142,14 @@ $lisp-read:end: 5d/pop-to-ebp c3/return -# lisp-read: in : (address buffered-file) -> (address cell) +# lisp-read: in : (address buffered-file) -> (handle cell) # token tmp = next-mulisp-token(in) # if is-int(tmp) return cell(tmp) # if is-string(tmp) return cell(tmp) # if is-pair(tmp) ... # if is-array(tmp) ... -next-mulisp-token: # in : (address buffered-file), line : (address stream), result : (address slice) +next-mulisp-token: # in : (address buffered-file), line : (address stream byte), result : (address slice) # pseudocode: # if (line->read >= line->write) # read-line-buffered(in, line) @@ -194,11 +194,11 @@ $next-mulisp-token:end: 5d/pop-to-ebp c3/return -new-int-cell: # in : (address slice) -> eax : (address cell) +new-int-cell: # in : (address slice) -> eax : (handle cell) -new-string-cell: # in : (address slice) -> eax : (address cell) +new-string-cell: # in : (address slice) -> eax : (handle cell) -lisp-eval: # in : (address cell) -> eax : (address cell) +lisp-eval: # in : (address cell) -> eax : (handle cell) # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp diff --git a/apps/pack b/apps/pack index 74d4ed32ecf20856768dd4fd4fcb5b4bfb452cc7..005c42f82fa32ee2bc6df04bc0f2ffe97b3cb488 100755 GIT binary patch literal 55192 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 diff --git a/apps/pack.subx b/apps/pack.subx index 6079a896..df683f84 100644 --- a/apps/pack.subx +++ b/apps/pack.subx @@ -45,8 +45,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto interactive - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto interactive + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-pack-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -55,7 +55,7 @@ Entry: # run tests if necessary, convert stdin if not eb/jump $subx-pack-main:end/disp8 $subx-pack-main:interactive: # - otherwise convert stdin - # var ed/eax : exit-descriptor + # var ed/eax : (ref exit-descriptor) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # subtract from esp 89/copy 3/mod/direct 0/rm32/eax . . . 4/r32/esp . . # copy esp to eax # configure ed to really exit() @@ -99,7 +99,7 @@ $subx-pack-main:end: subx-pack: # in : (address buffered-file), out : (address buffered-file) # pseudocode: - # var line : (stream byte 512) + # var line : (ref stream byte 512) # var in-code? = false # while true # clear-stream(line) @@ -128,17 +128,17 @@ subx-pack: # in : (address buffered-file), out : (address buffered-file) 51/push-ecx 52/push-edx 53/push-ebx - # var line/ecx : (address stream byte) = stream(512) + # var line/ecx : (ref stream byte 512) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var word-slice/edx = {0, 0} + # var word-slice/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx - # var in-code?/ebx = false + # var in-code?/ebx : boolean = false 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx $subx-pack:loop: # clear-stream(line) @@ -203,8 +203,8 @@ $subx-pack:check1: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) write-stream-data(out, line) - 3d/compare-eax-and 0/imm32 + # . if (eax != false) write-stream-data(out, line) + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $subx-pack:pass-through/disp32 $subx-pack:check2: #? # dump word-slice {{{ @@ -256,8 +256,8 @@ $subx-pack:check2: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto check3 - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto check3 + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $subx-pack:check3/disp32 # word-slice = next-word(line) # . . push args @@ -328,8 +328,8 @@ $subx-pack:check3: e8/call rewind-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # if (in-code? != 0) convert-instruction(line, out) - 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx + # if (in-code? != false) convert-instruction(line, out) + 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx 74/jump-if-equal $subx-pack:data/disp8 $subx-pack:code: # . convert-instruction(line, out) @@ -911,7 +911,7 @@ test-subx-pack-code-and-data-segments: convert-data: # line : (address stream byte), out : (address buffered-file) # pseudocode: - # var word-slice = {0, 0} + # var word-slice : (ref slice) # while true # word-slice = next-word(line) # if slice-empty?(word-slice) # end of file (maybe including trailing whitespace) @@ -936,7 +936,7 @@ convert-data: # line : (address stream byte), out : (address buffered-file) 50/push-eax 51/push-ecx 52/push-edx - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -1024,17 +1024,17 @@ $convert-data:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $convert-data:break/disp32 $convert-data:check-for-comment: # if (slice-starts-with?(word-slice, "#")) - # . start/edx = word-slice->start + # . var start/edx : (address byte) = word-slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL - # . if (eax != '#') goto next check + # . if (c != '#') goto next check 3d/compare-eax-and 0x23/imm32/hash 75/jump-if-not-equal $convert-data:check-for-label/disp8 $convert-data:comment: @@ -1050,12 +1050,12 @@ $convert-data:comment: 0f 85/jump-if-not-equal $convert-data:end/disp32 $convert-data:check-for-label: # if (slice-ends-with?(word-slice, ":")) - # . end/edx = word-slice->end + # . var end/edx : (address byte) = word-slice->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx - # . c/eax = *(end-1) + # . var c/eax : byte = *(end-1) 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 1/mod/*+disp8 2/rm32/edx . . . 0/r32/AL -1/disp8 . # copy byte at *ecx to AL - # . if (eax != ':') goto next check + # . if (c != ':') goto next check 3d/compare-eax-and 0x3a/imm32/colon 75/jump-if-not-equal $convert-data:check-for-imm32/disp8 $convert-data:label: @@ -1079,8 +1079,8 @@ $convert-data:check-for-imm32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) process as a single byte - 3d/compare-eax-and 0/imm32 + # . if (eax == false) process as a single byte + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $convert-data:single-byte/disp8 $convert-data:imm32: # emit(out, word-slice, 4) @@ -1837,7 +1837,7 @@ convert-instruction: # line : (address stream byte), out : (address buffered-fi 50/push-eax 51/push-ecx 52/push-edx - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -1858,27 +1858,27 @@ $convert-instruction:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) pass through - 3d/compare-eax-and 0/imm32 + # . if (eax != false) pass through + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $convert-instruction:pass-through/disp8 $convert-instruction:check1: # if (slice-starts-with?(word-slice, "#")) write-stream-data(out, line) - # . start/edx = word-slice->start + # . var start/edx : (address byte) = word-slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL - # . if (eax == '#') pass through + # . if (c == '#') pass through 3d/compare-eax-and 0x23/imm32/hash 74/jump-if-equal $convert-instruction:pass-through/disp8 $convert-instruction:check2: # if (slice-ends-with?(word-slice, ":")) write-stream-data(out, line) - # . end/edx = word-slice->end + # . var end/edx : (address byte) = word-slice->end 8b/copy 1/mod/*+disp8 1/rm32/ecx . . . 2/r32/edx 4/disp8 . # copy *(ecx+4) to edx - # . c/eax = *(end-1) + # . var c/eax : byte = *(end-1) 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 1/mod/*+disp8 2/rm32/edx . . . 0/r32/AL -1/disp8 . # copy byte at *ecx to AL - # . if (eax == ':') pass through + # . if (c == ':') pass through 3d/compare-eax-and 0x3a/imm32/colon 75/jump-if-not-equal $convert-instruction:really-convert/disp8 $convert-instruction:pass-through: @@ -1994,11 +1994,11 @@ emit-opcodes: # line : (address stream byte), out : (address buffered-file) 51/push-ecx 52/push-edx 53/push-ebx - # var op1/ecx = {0, 0} + # var op1/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var op2/edx = {0, 0} + # var op2/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -2026,16 +2026,16 @@ $emit-opcodes:op1: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) return - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 # if (slice-starts-with?(op1, "#")) return - # . start/ebx = op1->start + # . var start/ebx : (address byte) = op1->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 3/r32/ebx . . # copy *ecx to ebx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL - # . if (eax == '#') return + # . if (c == '#') return 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-opcodes:end/disp32 # op1 = next-token-from-slice(op1->start, op1->end, '/') @@ -2073,8 +2073,8 @@ $emit-opcodes:op1: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) goto op2 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) goto op2 + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $emit-opcodes:op2/disp8 # if (slice-equal?(op1, "f2")) goto op2 # . eax = slice-equal?(op1, "f2") @@ -2085,8 +2085,8 @@ $emit-opcodes:op1: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) goto op2 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) goto op2 + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $emit-opcodes:op2/disp8 # if (slice-equal?(op1, "f3")) goto op2 # . eax = slice-equal?(op1, "f3") @@ -2097,8 +2097,8 @@ $emit-opcodes:op1: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) goto op2 - 3d/compare-eax-and 0/imm32 + # . if (eax != false) goto op2 + 3d/compare-eax-and 0/imm32/false 75/jump-if-not-equal $emit-opcodes:op2/disp8 # otherwise return e9/jump $emit-opcodes:end/disp32 @@ -2119,16 +2119,16 @@ $emit-opcodes:op2: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) return - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 # if (slice-starts-with?(op2, "#")) return - # . start/ebx = op2->start + # . var start/ebx : (address byte) = op2->start 8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL - # . if (eax == '#') return + # . if (c == '#') return 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-opcodes:end/disp32 # op2 = next-token-from-slice(op2->start, op2->end, '/') @@ -2166,8 +2166,8 @@ $emit-opcodes:op2: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) return - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 # if (!slice-equal?(op2, "0f")) return # . eax = slice-equal?(op2, "0f") @@ -2178,8 +2178,8 @@ $emit-opcodes:op2: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) return - 3d/compare-eax-and 0/imm32 + # . if (eax == false) return + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-opcodes:end/disp32 $emit-opcodes:op3: # next-word(line, op3) # reuse op2/edx @@ -2198,16 +2198,16 @@ $emit-opcodes:op3: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) return - 3d/compare-eax-and 0/imm32 + # . if (eax != false) return + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-opcodes:end/disp32 # if (slice-starts-with?(op3, "#")) return - # . start/ebx = op2->start + # . var start/ebx : (address byte) = op2->start 8b/copy 0/mod/indirect 2/rm32/edx . . . 3/r32/ebx . . # copy *edx to ebx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 3/rm32/ebx . . . 0/r32/AL . . # copy byte at *ebx to AL - # . if (eax == '#') return + # . if (c == '#') return 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-opcodes:end/disp32 # op3 = next-token-from-slice(op3->start, op3->end, '/') @@ -2253,7 +2253,7 @@ emit-modrm: # line : (address stream byte), out : (address buffered-file) # pseudocode: # rewind-stream(line) # var has-modrm? = false, mod = 0, rm32 = 0, r32 = 0 - # var word-slice = {0, 0} + # var word-slice : (ref slice) # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break @@ -2285,17 +2285,17 @@ emit-modrm: # line : (address stream byte), out : (address buffered-file) 53/push-ebx 56/push-esi 57/push-edi - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var has-modrm?/edx = false + # var has-modrm?/edx : boolean = false 31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx - # var mod/ebx = 0 + # var mod/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - # var rm32/esi = 0 + # var rm32/esi : byte = 0 31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi - # var r32/edi = 0 + # var r32/edi : byte = 0 31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi # rewind-stream(line) # . . push args @@ -2395,21 +2395,21 @@ $emit-modrm:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) pass through - 3d/compare-eax-and 0/imm32 + # . if (eax != false) pass through + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-modrm:break/disp32 $emit-modrm:check1: # if (slice-starts-with?(word-slice, "#")) break # . spill edx 52/push-edx - # . start/edx = word-slice->start + # . var start/edx : (address byte) = word-slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL # . restore edx 5a/pop-to-edx - # . if (eax == '#') pass through + # . if (c == '#') pass through 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-modrm:break/disp32 $emit-modrm:check-for-mod: @@ -2422,8 +2422,8 @@ $emit-modrm:check-for-mod: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-modrm:check-for-rm32/disp8 $emit-modrm:mod: # mod = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2450,8 +2450,8 @@ $emit-modrm:check-for-rm32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-modrm:check-for-r32/disp8 $emit-modrm:rm32: # rm32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2478,8 +2478,8 @@ $emit-modrm:check-for-r32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-modrm:check-for-subop/disp8 $emit-modrm:r32: # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2506,8 +2506,8 @@ $emit-modrm:check-for-subop: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) loop - 3d/compare-eax-and 0/imm32 + # . if (eax == false) loop + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-modrm:loop/disp32 $emit-modrm:subop: # r32 = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2526,10 +2526,10 @@ $emit-modrm:subop: e9/jump $emit-modrm:loop/disp32 $emit-modrm:break: # if (!has-modrm?) return - 81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32 # compare edx + 81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx 74/jump-if-equal $emit-modrm:end/disp8 $emit-modrm:calculate: - # modrm/ebx = mod & 0b11 + # var modrm/ebx : byte = mod & 0b11 81 4/subop/and 3/mod/direct 3/rm32/ebx . . . . . 3/imm32/0b11 # bitwise and of ebx # modrm <<= 3 c1/shift 4/subop/left 3/mod/direct 3/rm32/ebx . . . . . 3/imm8 # shift ebx left by 3 bits @@ -2569,7 +2569,7 @@ $emit-modrm:end: emit-sib: # line : (address stream byte), out : (address buffered-file) # pseudocode: # var has-sib? = false, base = 0, index = 0, scale = 0 - # var word-slice = {0, 0} + # var word-slice : (ref slice) # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break @@ -2601,17 +2601,17 @@ emit-sib: # line : (address stream byte), out : (address buffered-file) 53/push-ebx 56/push-esi 57/push-edi - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var has-sib?/edx = false + # var has-sib?/edx : boolean = false 31/xor 3/mod/direct 2/rm32/edx . . . 2/r32/edx . . # clear edx - # var scale/ebx = 0 + # var scale/ebx : byte = 0 31/xor 3/mod/direct 3/rm32/ebx . . . 3/r32/ebx . . # clear ebx - # var base/esi = 0 + # var base/esi : byte = 0 31/xor 3/mod/direct 6/rm32/esi . . . 6/r32/esi . . # clear esi - # var index/edi = 0 + # var index/edi : byte = 0 31/xor 3/mod/direct 7/rm32/edi . . . 7/r32/edi . . # clear edi # rewind-stream(line) # . . push args @@ -2704,21 +2704,21 @@ $emit-sib:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) pass through - 3d/compare-eax-and 0/imm32 + # . if (eax != false) pass through + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-sib:break/disp32 $emit-sib:check1: # if (slice-starts-with?(word-slice, "#")) break # . spill edx 52/push-edx - # . start/edx = word-slice->start + # . var start/edx : (address byte) = word-slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL # . restore edx 5a/pop-to-edx - # . if (eax == '#') pass through + # . if (c == '#') pass through 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-sib:break/disp32 $emit-sib:check-for-scale: @@ -2731,8 +2731,8 @@ $emit-sib:check-for-scale: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-sib:check-for-base/disp8 $emit-sib:scale: # scale = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2759,8 +2759,8 @@ $emit-sib:check-for-base: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-sib:check-for-index/disp8 $emit-sib:base: # base = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2787,8 +2787,8 @@ $emit-sib:check-for-index: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) loop - 3d/compare-eax-and 0/imm32 + # . if (eax == false) loop + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-sib:loop/disp32 $emit-sib:index: # index = parse-hex-int(next-token-from-slice(word-slice->start, word-slice->end, '/')) @@ -2807,10 +2807,10 @@ $emit-sib:index: e9/jump $emit-sib:loop/disp32 $emit-sib:break: # if (!has-sib?) return - 81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32 # compare edx + 81 7/subop/compare 3/mod/direct 2/rm32/edx . . . . . 0/imm32/false # compare edx 74/jump-if-equal $emit-sib:end/disp8 $emit-sib:calculate: - # sib/ebx = scale & 0b11 + # var sib/ebx : byte = scale & 0b11 81 4/subop/and 3/mod/direct 3/rm32/ebx . . . . . 3/imm32/0b11 # bitwise and of ebx # sib <<= 2 c1/shift 4/subop/left 3/mod/direct 3/rm32/ebx . . . . . 2/imm8 # shift ebx left by 2 bits @@ -2850,7 +2850,7 @@ $emit-sib:end: emit-disp: # line : (address stream byte), out : (address buffered-file) # pseudocode: # rewind-stream(line) - # var word-slice = {0, 0} + # var word-slice : (ref slice) # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break @@ -2872,7 +2872,7 @@ emit-disp: # line : (address stream byte), out : (address buffered-file) 50/push-eax 51/push-ecx 52/push-edx - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -2967,17 +2967,17 @@ $emit-disp:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) pass through - 3d/compare-eax-and 0/imm32 + # . if (eax != false) pass through + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-disp:break/disp32 $emit-disp:check1: # if (slice-starts-with?(word-slice, "#")) break - # . start/edx = word-slice->start + # . var start/edx : (address byte) = word-slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL - # . if (eax == '#') break + # . if (c == '#') break 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-disp:break/disp32 $emit-disp:check-for-disp32: @@ -2990,8 +2990,8 @@ $emit-disp:check-for-disp32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-disp:check-for-disp16/disp8 $emit-disp:disp32: # emit(out, word-slice, 4) @@ -3015,8 +3015,8 @@ $emit-disp:check-for-disp16: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-disp:check-for-disp8/disp8 $emit-disp:disp16: # emit(out, word-slice, 2) @@ -3040,8 +3040,8 @@ $emit-disp:check-for-disp8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) loop - 3d/compare-eax-and 0/imm32 + # . if (eax == false) loop + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-disp:loop/disp32 $emit-disp:disp8: # emit(out, word-slice, 1) @@ -3069,7 +3069,7 @@ $emit-disp:break: emit-imm: # line : (address stream byte), out : (address buffered-file) # pseudocode: # rewind-stream(line) - # var word-slice = {0, 0} + # var word-slice : (ref slice) # while true # word-slice = next-word(line) # if (slice-empty?(word-slice)) break @@ -3091,7 +3091,7 @@ emit-imm: # line : (address stream byte), out : (address buffered-file) 50/push-eax 51/push-ecx 52/push-edx - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -3186,17 +3186,17 @@ $emit-imm:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) pass through - 3d/compare-eax-and 0/imm32 + # . if (eax != false) pass through + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-imm:break/disp32 $emit-imm:check1: # if (slice-starts-with?(word-slice, "#")) break - # . start/edx = slice->start + # . var start/edx : (address byte) = slice->start 8b/copy 0/mod/indirect 1/rm32/ecx . . . 2/r32/edx . . # copy *ecx to edx - # . c/eax = *start + # . var c/eax : byte = *start 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax 8a/copy-byte 0/mod/indirect 2/rm32/edx . . . 0/r32/AL . . # copy byte at *edx to AL - # . if (eax == '#') break + # . if (c == '#') break 3d/compare-eax-and 0x23/imm32/hash 0f 84/jump-if-equal $emit-imm:break/disp32 $emit-imm:check-for-imm32: @@ -3209,8 +3209,8 @@ $emit-imm:check-for-imm32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-imm:check-for-imm16/disp8 $emit-imm:imm32: # emit(out, word-slice, 4) @@ -3234,8 +3234,8 @@ $emit-imm:check-for-imm16: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-imm:check-for-imm8/disp8 $emit-imm:imm16: # emit(out, word-slice, 2) @@ -3259,8 +3259,8 @@ $emit-imm:check-for-imm8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) loop - 3d/compare-eax-and 0/imm32 + # . if (eax == false) loop + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-imm:loop/disp32 $emit-imm:imm8: # emit(out, word-slice, 1) @@ -5837,7 +5837,7 @@ test-convert-instruction-handles-imm8-operand: c3/return # shortcut for parse-hex-int(next-token-from-slice(word->start, word->end, '/')) -parse-datum-of-word: # word : (address slice) -> value/eax +parse-datum-of-word: # word : (address slice) -> value/eax : int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp @@ -5846,7 +5846,7 @@ parse-datum-of-word: # word : (address slice) -> value/eax 56/push-esi # esi = word 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -5860,7 +5860,7 @@ parse-datum-of-word: # word : (address slice) -> value/eax e8/call next-token-from-slice/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 0x10/imm32 # add to esp - # value/eax = parse-hex-int(slice) + # return parse-hex-int(slice) # . . push args 51/push-ecx # . . call diff --git a/apps/sigils b/apps/sigils index a792c7e04911e040f72af1e5cc1fca04260b27d9..a1f33ada899ae5317fb0b6ab9d50b74c4555e35c 100755 GIT binary patch literal 55201 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 yJyU>$B&FRTK3W!Po literal 55211 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, word-slice->end} + # var local-slice/eax : (ref slice) = {word-slice->start, word-slice->end} 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 0/r32/eax 0xc/disp8 . # copy *(ebp+12) to eax ff 6/subop/push 1/mod/*+disp8 0/rm32/eax . . . . 4/disp8 . # push *(eax+4) ff 6/subop/push 0/mod/indirect 0/rm32/eax . . . . . . # push *eax @@ -1834,7 +1834,7 @@ test-next-word-or-expression: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -1907,7 +1907,7 @@ test-next-word-or-expression-returns-whole-comment: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -1980,7 +1980,7 @@ test-next-word-or-expression-returns-empty-slice-on-eof: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -2022,7 +2022,7 @@ test-next-word-or-expression-returns-string-literal: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -2085,7 +2085,7 @@ test-next-word-or-expression-returns-string-with-escapes: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -2148,7 +2148,7 @@ test-next-word-or-expression-returns-whole-expression: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var slice/ecx = {0, 0} + # var slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -2250,7 +2250,7 @@ parse-effective-address: # word-slice : (address slice) -> base/eax, index/ecx, # . save registers 56/push-esi 57/push-edi - # var local-slice/esi : (address slice) = {word-slice->start, word-slice->end} + # var local-slice/esi : (ref slice) = {word-slice->start, word-slice->end} 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4) ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi @@ -2679,7 +2679,7 @@ next-register: # in : (address slice) -> reg/eax : int 56/push-esi # esi = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # var reg-slice/ecx : (address slice) = {in->start, in->start + 3} + # var reg-slice/ecx : (ref slice) = {in->start, in->start + 3} 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax 05/add-to-eax 3/imm32 50/push-eax @@ -3865,7 +3865,7 @@ disp32-mode?: # in : (address slice) -> reg/eax : boolean # . save registers 56/push-esi 57/push-edi - # var local-slice/esi : (address slice) = {in->start, in->end} + # var local-slice/esi : (ref slice) = {in->start, in->end} 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4) ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi @@ -3923,7 +3923,7 @@ emit-indirect-disp32: # out : (address buffered-file), word-slice : (address sl 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # . save registers 56/push-esi - # var local-slice/esi : (address slice) = {in->start, in->end} + # var local-slice/esi : (ref slice) = {in->start, in->end} 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi ff 6/subop/push 1/mod/*+disp8 6/rm32/esi . . . . 4/disp8 . # push *(esi+4) ff 6/subop/push 0/mod/indirect 6/rm32/esi . . . . . . # push *esi @@ -4055,8 +4055,8 @@ $next-hex-int:loop: e8/call is-hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax == false) break + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $next-hex-int:break/disp8 # eax = from-hex-char(*curr) # . . copy arg to eax @@ -4071,7 +4071,8 @@ $next-hex-int:loop: # loop eb/jump $next-hex-int:loop/disp8 $next-hex-int:break: - 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx + # if (negate?) result = -result + 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx 74/jump-if-equal $next-hex-int:end/disp8 $next-hex-int:negate: f7 3/subop/negate 3/mod/direct 7/rm32/edi . . . . . . # negate edi @@ -4437,8 +4438,8 @@ $next-positive-hex-int:loop: e8/call is-hex-digit?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax == false) break + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $next-positive-hex-int:end/disp8 # eax = from-hex-char(*curr) # . . copy arg to eax diff --git a/apps/survey b/apps/survey index 23eb9e3bf7dfae5e286910f55ac76fb5792ad0d1..2ec38e5d8039734804539e9ba1a0d8bf56177df9 100755 GIT binary patch literal 52041 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

7SHiu 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 diff --git a/apps/survey.subx b/apps/survey.subx index 8563116f..e365ac1b 100644 --- a/apps/survey.subx +++ b/apps/survey.subx @@ -74,8 +74,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto interactive - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto interactive + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-survey-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -115,9 +115,9 @@ $subx-survey-main:end: subx-survey: # infile : (address buffered-file), out : (address buffered-file) # pseudocode - # var in : (address stream byte) = stream(4096) + # var in : (ref stream byte 4096) # slurp(infile, in) - # var segments : (stream segment-info 10) + # var segments : (stream segment-info) # var labels : (stream label-info Max-labels) # compute-offsets(in, segments, labels) # compute-addresses(segments, labels) @@ -131,13 +131,13 @@ subx-survey: # infile : (address buffered-file), out : (address buffered-file) 51/push-ecx 52/push-edx 56/push-esi - # var segments/ecx = stream(10 * 16) + # var segments/ecx : (ref stream {string, segment-info} 160) # 10 rows * 16 bytes/row 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var labels/edx = stream(Max-labels * 16) + # var labels/edx : (ref stream label-info Max-labels*16) # . data 2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Max-labels/disp32 # subtract *Max-labels from esp # . length @@ -147,7 +147,7 @@ subx-survey: # infile : (address buffered-file), out : (address buffered-file) # . write 68/push 0/imm32/write 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx - # var in/esi = stream(Input-size * 1) + # var in/esi : (ref stream byte Input-size) # . data 2b/subtract 0/mod/indirect 5/rm32/.disp32 . . 4/r32/esp Input-size/disp32 # subtract *Input-size from esp # . length @@ -618,7 +618,7 @@ compute-offsets:segment-tmp: # slice == code -compute-offsets: # in : (address stream), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) +compute-offsets: # in : (address stream byte), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) # skeleton: # for lines in 'in' # for words in line @@ -833,8 +833,8 @@ $compute-offsets:case-empty: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $compute-offsets:line-loop/disp32 $compute-offsets:case-comment: # if slice-starts-with?(word-slice, "#") continue @@ -843,8 +843,8 @@ $compute-offsets:case-comment: e8/call slice-starts-with?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $compute-offsets:line-loop/disp32 $compute-offsets:case-segment-header: # if (!slice-equal?(word-slice/edx, "==")) goto next case @@ -854,8 +854,8 @@ $compute-offsets:case-segment-header: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next case - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next case + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $compute-offsets:case-label/disp32 # if (curr-segment-name == 0) goto construct-next-segment 81 7/subop/compare 3/mod/direct 6/rm32/esi . . . . . 0/imm32 # compare esi @@ -973,8 +973,8 @@ $compute-offsets:update-curr-segment-name: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) abort - 3d/compare-eax-and 0/imm32 + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $compute-offsets:abort/disp32 # seg/ebx = get-or-insert(segments, curr-segment-name, row-size=16) # . . push args @@ -1022,8 +1022,8 @@ $compute-offsets:case-label: e8/call is-label?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) goto next case - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next case + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $compute-offsets:case-default/disp8 # strip trailing ':' from word-slice ff 1/subop/decrement 1/mod/*+disp8 2/rm32/edx . . . . 4/disp8 . # decrement *(edx+4) @@ -1219,13 +1219,13 @@ test-compute-offsets: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # var segments/ecx = stream(2 * 16) + # var segments/ecx : (ref stream byte 2*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp 68/push 0x20/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var labels/edx = stream(2 * 16) + # var labels/edx : (ref stream byte 2*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x20/imm32 # subtract from esp 68/push 0x20/imm32/length 68/push 0/imm32/read @@ -1381,7 +1381,7 @@ test-compute-offsets: compute-addresses: # segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) # pseudocode: # srow : (address segment-info) = segments->data - # max = segments->data + segments->write + # max = &segments->data[segments->write] # num-segments = segments->write / 16 # starting-offset = 0x34 + (num-segments * 0x20) # while true @@ -1392,7 +1392,7 @@ compute-addresses: # segments : (address stream {string, segment-info}), labels # trace-sssns("segment " s->key " starts at address " s->address) # srow += 16 # row-size # lrow : (address label-info) = labels->data - # max = labels->data + labels->write + # max = &labels->data[labels->write] # while true # if (lrow >= max) break # seg-name : (address string) = lrow->segment-name @@ -1422,7 +1422,7 @@ compute-addresses: # segments : (address stream {string, segment-info}), labels 81 0/subop/add 3/mod/direct 7/rm32/edi . . . . . 0x34/imm32 # add to edi # srow/eax = segments->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 0xc/disp8 . # copy esi+12 to eax - # max/ecx = segments->data + segments->write + # max/ecx = &segments->data[segments->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx $compute-addresses:segment-loop: @@ -1489,7 +1489,7 @@ $compute-addresses:segment-break: 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 0xc/disp8 . # copy *(ebp+12) to esi # lrow/eax = labels->data 8d/copy-address 1/mod/*+disp8 6/rm32/esi . . . 0/r32/eax 0xc/disp8 . # copy esi+12 to eax - # max/ecx = labels->data + labels->write + # max/ecx = &labels->data[labels->write] 8b/copy 0/mod/indirect 6/rm32/esi . . . 1/r32/ecx . . # copy *esi to ecx 01/add 3/mod/direct 1/rm32/ecx . . . 6/r32/esi . . # add esi to ecx $compute-addresses:label-loop: @@ -1621,13 +1621,13 @@ test-compute-addresses: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup - # . var segments/ecx = stream(10 * 16) + # . var segments/ecx : (ref stream byte 10*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . var labels/edx = stream(512 * 16) + # . var labels/edx : (ref stream byte 512*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 68/push 0x2000/imm32/length 68/push 0/imm32/read @@ -1790,13 +1790,13 @@ test-compute-addresses-large-segments: 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp # setup - # . var segments/ecx = stream(10 * 16) + # . var segments/ecx : (ref stream byte 10*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . var labels/edx = stream(512 * 16) + # . var labels/edx : (ref stream byte 512*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 68/push 0x2000/imm32/length 68/push 0/imm32/read @@ -1871,7 +1871,7 @@ test-compute-addresses-large-segments: 5d/pop-to-ebp c3/return -emit-output: # in : (address stream), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) +emit-output: # in : (address stream byte), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) # pseudocode: # emit-headers(out, segments, labels) # emit-segments(in, out, segments, labels) @@ -1922,7 +1922,7 @@ $emit-output:end: 5d/pop-to-ebp c3/return -emit-segments: # in : (address stream), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) +emit-segments: # in : (address stream byte), out : (address buffered-file), segments : (address stream {string, segment-info}), labels : (address stream {string, label-info}) # pseudocode: # var offset-of-next-instruction = 0 # var line : (stream byte 512) @@ -1993,11 +1993,11 @@ emit-segments: # in : (address stream), out : (address buffered-file), segments 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var word-slice/edx = {0, 0} + # var word-slice/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx - # var datum/edi = {0, 0} + # var datum/edi : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 7/rm32/edi . . . 4/r32/esp . . # copy esp to edi @@ -2139,8 +2139,8 @@ $emit-segments:check-for-label: e8/call is-label?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:line-loop/disp32 $emit-segments:check-for-segment-header: # if (slice-equal?(word-slice, "==")) break @@ -2152,8 +2152,8 @@ $emit-segments:check-for-segment-header: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:line-loop/disp32 $emit-segments:2-character: # if (length(word-slice) != 2) goto next check @@ -2275,8 +2275,8 @@ $emit-segments:check-global-variable: e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) goto code label checks - 3d/compare-eax-and 0/imm32 + # . if (eax != false) goto code label checks + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:check-code-label-for-imm8/disp32 $emit-segments:check-global-variable-for-disp8: # if has-metadata?(word-slice, "disp8") abort @@ -2288,8 +2288,8 @@ $emit-segments:check-global-variable-for-disp8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) abort - 3d/compare-eax-and 0/imm32 + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:global-variable-abort/disp32 $emit-segments:check-global-variable-for-imm8: # if has-metadata?(word-slice, "imm8") abort @@ -2301,8 +2301,8 @@ $emit-segments:check-global-variable-for-imm8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) abort - 3d/compare-eax-and 0/imm32 + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:global-variable-abort/disp32 $emit-segments:emit-global-variable: # emit-hex(out, info->address, 4) @@ -2326,8 +2326,8 @@ $emit-segments:check-code-label-for-imm8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) abort - 3d/compare-eax-and 0/imm32 + # . if (eax != false) abort + 3d/compare-eax-and 0/imm32/false 0f 85/jump-if-not-equal $emit-segments:imm8-abort/disp32 $emit-segments:check-code-label-for-imm32: # if (!has-metadata?(word-slice, "imm32")) goto next check @@ -2339,7 +2339,7 @@ $emit-segments:check-code-label-for-imm32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check + # . if (eax == false) goto next check 3d/compare-eax-and 0/imm32 74/jump-if-equal $emit-segments:check-code-label-for-disp8/disp8 #? # dump info->address {{{ @@ -2397,8 +2397,8 @@ $emit-segments:check-code-label-for-disp8: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-segments:check-code-label-for-disp32/disp8 $emit-segments:emit-code-label-disp8: # emit-hex(out, info->offset - offset-of-next-instruction, 1) @@ -2424,8 +2424,8 @@ $emit-segments:check-code-label-for-disp32: e8/call has-metadata?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) abort - 3d/compare-eax-and 0/imm32 + # . if (eax == false) abort + 3d/compare-eax-and 0/imm32/false 0f 84/jump-if-equal $emit-segments:abort/disp32 $emit-segments:emit-code-label-disp32: # emit-hex(out, info->offset - offset-of-next-instruction, 4) @@ -2577,13 +2577,13 @@ test-emit-segments-global-variable: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . var segments/ecx = stream(10 * 16) + # . var segments/ecx : (ref stream byte 10*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . var labels/edx = stream(512 * 16) + # . var labels/edx : (ref stream byte 512*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 68/push 0x2000/imm32/length 68/push 0/imm32/read @@ -2814,13 +2814,13 @@ test-emit-segments-code-label: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . var segments/ecx = stream(10 * 16) + # . var segments/ecx : (ref stream byte 10*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . var labels/edx = stream(512 * 16) + # . var labels/edx : (ref stream byte 512*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 68/push 0x2000/imm32/length 68/push 0/imm32/read @@ -3016,13 +3016,13 @@ test-emit-segments-code-label-absolute: e8/call clear-stream/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . var segments/ecx = stream(10 * 16) + # . var segments/ecx : (ref stream byte 10*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0xa0/imm32 # subtract from esp 68/push 0xa0/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # . var labels/edx = stream(512 * 16) + # . var labels/edx : (ref stream byte 512*16) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x2000/imm32 # subtract from esp 68/push 0x2000/imm32/length 68/push 0/imm32/read @@ -3177,7 +3177,7 @@ emit-headers: # out : (address buffered-file), segments : (address stream {stri # pseudocode: # emit-elf-header(out, segments, labels) # curr-segment = segments->data - # max = segments->data + segments->write + # max = &segments->data[segments->write] # while true # if (curr-segment >= max) break # emit-elf-program-header-entry(out, curr-segment) @@ -3213,7 +3213,7 @@ emit-headers: # out : (address buffered-file), segments : (address stream {stri 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx # curr-segment/eax = segments->data 8d/copy-address 1/mod/*+disp8 0/rm32/eax . . . 0/r32/eax 0xc/disp8 . # copy eax+12 to eax - # max/ecx = segments->data + segments->write + # max/ecx = &segments->data[segments->write] 01/add 3/mod/direct 1/rm32/ecx . . . 0/r32/eax . . # add eax to ecx $emit-headers:loop: # if (curr-segment >= max) break @@ -3431,8 +3431,8 @@ emit-elf-program-header-entry: # out : (address buffered-file), curr-segment : e8/call string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto next check - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto next check + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $emit-elf-program-header-entry:data/disp8 # *$Elf_p_flags = r-x c7 0/subop/copy 0/mod/indirect 5/rm32/.disp32 . . . $Elf_p_flags/disp32 5/imm32 # copy to *$Elf_p_flags @@ -3479,12 +3479,12 @@ stream-add4: # in : (address stream byte), key : address, val1 : address, val2 56/push-esi # esi = in 8b/copy 1/mod/*+disp8 5/rm32/ebp . . . 6/r32/esi 8/disp8 . # copy *(ebp+8) to esi - # curr/eax = in->data + in->write + # curr/eax = &in->data[in->write] # . eax = in->write 8b/copy 0/mod/indirect 6/rm32/esi . . . 0/r32/eax . . # copy *esi to eax # . eax = esi+eax+12 8d/copy-address 1/mod/*+disp8 4/rm32/sib 6/base/esi 0/index/eax . 0/r32/eax 0xc/disp8 . # copy esi+eax+12 to eax - # max/edx = in->data + in->length + # max/edx = &in->data[in->length] # . edx = in->length 8b/copy 1/mod/*+disp8 6/rm32/esi . . . 2/r32/edx 8/disp8 . # copy *(esi+8) to edx # . edx = esi+edx+12 @@ -3830,7 +3830,7 @@ test-trace-slsls: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var b/ebx : (address slice) = {eax, ecx} + # var b/ebx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx @@ -3839,7 +3839,7 @@ test-trace-slsls: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var d/edx : (address slice) = {eax, ecx} + # var d/edx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -3955,7 +3955,7 @@ test-trace-slsns: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var b/ebx : (address slice) = {eax, ecx} + # var b/ebx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx @@ -4071,7 +4071,7 @@ test-trace-slsss: 8b/copy 0/mod/indirect 0/rm32/eax . . . 1/r32/ecx . . # copy *eax to ecx 8d/copy-address 1/mod/*+disp8 4/rm32/sib 0/base/eax 1/index/ecx . 1/r32/ecx 4/disp8 . # copy eax+ecx+4 to ecx 05/add-to-eax 4/imm32 - # var b/ebx : (address slice) = {eax, ecx} + # var b/ebx : (ref slice) = {eax, ecx} 51/push-ecx 50/push-eax 89/copy 3/mod/direct 3/rm32/ebx . . . 4/r32/esp . . # copy esp to ebx @@ -4125,7 +4125,7 @@ test-trace-slsss: 5d/pop-to-ebp c3/return -num-bytes: # line : (address stream) -> eax : int +num-bytes: # line : (address stream byte) -> eax : int # pseudocode: # result = 0 # while true @@ -4150,7 +4150,7 @@ num-bytes: # line : (address stream) -> eax : int 53/push-ebx # var result/eax = 0 31/xor 3/mod/direct 0/rm32/eax . . . 0/r32/eax . . # clear eax - # var word-slice/ecx = {0, 0} + # var word-slice/ecx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx @@ -4247,8 +4247,8 @@ $num-bytes:check0: e8/call slice-empty?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false # . restore result now that ZF is set 58/pop-to-eax 75/jump-if-not-equal $num-bytes:end/disp8 @@ -4284,8 +4284,8 @@ $num-bytes:check-for-segment-header: e8/call slice-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax != 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax != false) break + 3d/compare-eax-and 0/imm32/false # . restore result now that ZF is set 58/pop-to-eax 75/jump-if-not-equal $num-bytes:end/disp8 diff --git a/apps/tests b/apps/tests index dd75aac173afe58d0faa283690489542d8caea6e..b292f93b1e89202b479377176c6758be4d99cfd0 100755 GIT binary patch literal 41598 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]E-Dsl>gf1`nTu^ERg9og zS%rX?XzdDwxRnz~f?MUV70wc(Q|u+-Xl)Jc*u{oB))0@_w=R~!>Tqo|g0w)(u<>D= zaRwnAH(;37Y6HrRA|FaHMPxWE>;|xHb+eG9Tu>jtNefb~YxUp+<};lWiNJcpq@@+q zcx;K$N>Clz0L-=oS;2%E6|kUeD{`#h42Vf;h{?Lyjx7W<72JH%fD=7Y%klCWuB27j zK!sSgtdNc=gcB!029}V|w%(=V$vO~;lX*JMfoz9e>G+fkYv_c;##r#L@{`n#NVMvT zEM@XyQ7eac0wFLC^Gg(lERDT9HB`67t_9c_Ha=|OXn~UH#DIf~h32$o2~F)>ty^9S zcU$@BK*Wsj`@QQb~yvAR#IcwvYNzgA#4GuZm3@#Fs#OW zMzllA3P>z%j&Y@@xcmM84s^J}R!Q@r4k9rs4ydShL}-L7hFJx5fubX=x(KVE9j>rX z6&xhlNz$nvo&WH51|FuLXYjW}zOFtd1pz2I&SqPSBvw$CMhHH#6O;qA3=2WB?fF58 zZlkWmcXhZ$C_Yz10bWxl{4RvDEwvqi+stY^Uvk4za!G!MeaCdh3Z{&Pq3wyQ9aES% z7K_`~O^cW|6G}W~`l8Or=%OM{UWbP(Du+|~SDhZGB460fd~Ml@B@{q7w-_GwR}9Zv zdsVuz1x%o3X%mV|q_SptxYki{*j7y! z@C>3-Y)eKiKmi;Y05abee{PVnOypCJD3+0eeA`m!hGm{206b7^Ghj#H0S7lM2!Vop zSO}$)?L>jA5el6uqjE~Gj>I5MIe60VAK?$%-Z)DFw6hWi^Q*P`+6Z30FQ?+xAZyDC zCqyA;wkea2U@h1A2)(`<87y3pSF?P1;W&uOf3d}k7N)W&5)1RoCT!NJdJ_?I$ zEa+s84|P}+aa?8`UV#Np@`{{Cl@@q2@GOUg!0=n;v2&0IZ3wo!{6gD|u!CARF?1NI z4*uvg)D|Zlpw-j$4xUPIAw;vKw)PPv4&9(DvBf&!)Q0JF?z|HC0a_4eH2}mln^Yhz*G<_x@ ztE>I=e-4cN{%Mr!;>#-{4S5AnvoN2*0^`~TgOJq`5X9dCxZ{PRGf61(@bH4 z)ta?e*(}Oh;@XCg2fic_zwt@`$b-`&3f9gBF-@3xevt$!tMcf{7J?2|0-cIicA7}a zSn;sV0M~CjS!E~CTO3%Z#J@B`S#4Qlt)D7lKi`fhVUa8At2m<|y+8##=g_B|!GxH{ zSr`y$BLxTmrfzOAJITXV4igW7t~j+bUVs1wczpwHH=>aS(kd3NsEzn*qJDaTSlXn0+p@XrB9gIyfX^$Zu^tNW% z+JMbKrYqeIJCcxObhL||m)}Xaf=?a6lzy z9?b=mp6$+WWHCy9Ui!eyu%%4H@xaf^w*Vsa+682vS!O+EV}}x$tPKXXRRa=;^D=`< zUOp0HG_n+>7+;nl;oFzRq-}oMGRN}p+KLFGJ1@VT{(^S;WxRndtkDi!p~=_$v{i4C zznR}U94+W@G)~7UQwt`TT?G^1ulzORP{vO3)8A!!z-87ry|Q0jQx(%n{3Zi{=EBy{1p6G9h`!-7chk_TZY*{T@_bqR#+ruk4X!B!%)gHkZTic>hQGdP8Ok*;XG zt>$ykFB)*)kTwVtf5`0g*%%rEfgkMrjj`jP9!-jZHWIyQ~Ajgtg2UOFIV zQ9X>JPw6xPgi24IiObEIS*qZcjqSu0n&8^9^L>f9fNMM9bOBYjU|Bg^l`6s2-Q%dO z;x+;3C7=~VJQ&wp5yu7oasEPE>Je|#nI*0fk@5KYs?D7)Fha@BLBUUcaP}Aa{Wh^( z39q5s7M7E0+YA@?$Az@4oKy;K#3s4K>PEHy55(t~o z60R@s*8uwc{>Y@fN-8`2yxryHnQp`Rc&M^4Pn^T?JJm>d4eG>5rTC~49~I&wx`M|l M#7DG-pQ>v94<3o-{Qv*} diff --git a/apps/tests.subx b/apps/tests.subx index f31f4d16..1d00cf30 100644 --- a/apps/tests.subx +++ b/apps/tests.subx @@ -43,8 +43,8 @@ Entry: # run tests if necessary, convert stdin if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) goto run-main - 3d/compare-eax-and 0/imm32 + # . if (eax == false) goto run-main + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-tests-main:interactive/disp8 # run-tests() e8/call run-tests/disp32 @@ -101,13 +101,13 @@ subx-gen-run-tests: # in : (address buffered-file), out : (address buffered-fil 52/push-edx 53/push-ebx 57/push-edi - # var line/ecx : (address stream byte) = stream(512) + # var line/ecx : (ref stream byte 512) 81 5/subop/subtract 3/mod/direct 4/rm32/esp . . . . . 0x200/imm32 # subtract from esp 68/push 0x200/imm32/length 68/push 0/imm32/read 68/push 0/imm32/write 89/copy 3/mod/direct 1/rm32/ecx . . . 4/r32/esp . . # copy esp to ecx - # var word-slice/edx = {0, 0} + # var word-slice/edx : (ref slice) 68/push 0/imm32/end 68/push 0/imm32/start 89/copy 3/mod/direct 2/rm32/edx . . . 4/r32/esp . . # copy esp to edx @@ -178,8 +178,8 @@ $subx-gen-run-tests:check-for-label: e8/call is-label?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 4/imm32 # add to esp - # . if (eax == 0) continue - 3d/compare-eax-and 0/imm32 + # . if (eax == false) continue + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-gen-run-tests:continue/disp8 $subx-gen-run-tests:check-label-prefix: # strip trailing ':' from word-slice @@ -192,8 +192,8 @@ $subx-gen-run-tests:check-label-prefix: e8/call slice-starts-with?/disp32 # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == 0) break - 3d/compare-eax-and 0/imm32 + # . if (eax == false) break + 3d/compare-eax-and 0/imm32/false 74/jump-if-equal $subx-gen-run-tests:continue/disp8 $subx-gen-run-tests:call-test-function: # tests-found? = true @@ -242,7 +242,7 @@ $subx-gen-run-tests:continue: e9/jump $subx-gen-run-tests:loop/disp32 $subx-gen-run-tests:break: # if (!tests-found?) goto end - 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32 # compare ebx + 81 7/subop/compare 3/mod/direct 3/rm32/ebx . . . . . 0/imm32/false # compare ebx 74/jump-if-equal $subx-gen-run-tests:end/disp8 # write(new-code-segment, " c3/return\n") # . . push args