https://github.com/akkartik/mu/blob/master/apps/mu.subx
    1 # The Mu computer's level-2 language, also called Mu.
    2 # http://akkartik.name/post/mu-2019-2
    3 #
    4 # To run:
    5 #   $ ./translate_subx init.linux [0-9]*.subx apps/mu.subx
    6 #   $ ./a.elf < prog.mu > prog.elf
    7 
    8 # == Goals
    9 # 1. Be memory safe. It should be impossible to corrupt the heap, or to create
   10 # a bad pointer. (Requires strong type safety.)
   11 # 2. Do as little as possible to achieve goal 1. The translator should be
   12 # implementable in machine code.
   13 #   - minimize impedance mismatch between source language and SubX target
   14 #     (e.g. programmer manages registers manually)
   15 #   - checks over syntax
   16 #     (e.g. programmer's register allocation is checked)
   17 #   - runtime checks to avoid complex static analysis
   18 #     (e.g. array indexing always checks bounds)
   19 
   20 # == Language description
   21 # A program is a sequence of function and type definitions.
   22 #
   23 # Function example:
   24 #   fn foo n: int -> result/eax: int {
   25 #     ...
   26 #   }
   27 #
   28 # Functions consist of a name, optional inputs, optional outputs and a block.
   29 #
   30 # Function inputs and outputs are variables. All variables have a type and
   31 # storage specifier. They can be placed either in memory (on the stack) or in
   32 # one of 6 named registers.
   33 #   eax ecx edx ebx esi edi
   34 # Variables in registers must be primitive 32-bit types.
   35 # Variables not explicitly placed in a register are on the stack.
   36 #
   37 # Function inputs are always passed in memory (on the stack), while outputs
   38 # are always returned in registers.
   39 #
   40 # Blocks mostly consist of statements.
   41 #
   42 # Statements mostly consist of a name, optional inputs and optional outputs.
   43 #
   44 # Statement inputs are variables or literals. Variables need to specify type
   45 # (and storage) the first time they're mentioned but not later.
   46 #
   47 # Statement outputs, like function outputs, must be variables in registers.
   48 #
   49 # Statement names must be either primitives or user-defined functions.
   50 #
   51 # Primitives can write to any register.
   52 # User-defined functions only write to hard-coded registers. Outputs of each
   53 # call must have the same registers as in the function definition.
   54 #
   55 # There are some other statement types:
   56 #   - blocks. Multiple statements surrounded by '{...}' and optionally
   57 #     prefixed with a label name and ':'
   58 #       - {
   59 #           ...
   60 #         }
   61 #       - foo: {
   62 #           ...
   63 #         }
   64 #
   65 #   - variable definitions on the stack. E.g.:
   66 #       - var foo: int
   67 #       - var bar: (array int 3)
   68 #     There's no initializer; variables are automatically initialized.
   69 #     The type of a local variable is either word-length (4 bytes) or starts with 'ref'.
   70 #
   71 #   - variables definitions in a register. E.g.:
   72 #       - var foo/eax: int <- add bar 1
   73 #     The initializer is mandatory and must be a valid instruction that writes
   74 #     a single output to the right register. In practice registers will
   75 #     usually be either initialized by primitives or copied from eax.
   76 #       - var eax: int <- foo bar quux
   77 #         var floo/ecx: int <- copy eax
   78 #
   79 # Still todo:
   80 #   global variables
   81 #   union types
   82 #
   83 # Formal types:
   84 #   A program is a linked list of functions
   85 #   A function contains:
   86 #     name: (handle array byte)
   87 #     inouts: linked list of vars  <-- 'inouts' is more precise than 'inputs'
   88 #       data: (handle var)
   89 #       next: (handle list)
   90 #     outputs: linked list of vars
   91 #       data: (handle var)
   92 #       next: (handle list)
   93 #     body: (handle block)
   94 #   A var-type contains:
   95 #     name: (handle array byte)
   96 #     type: (handle tree type-id)
   97 #
   98 #   A statement can be:
   99 #     tag 0: a block
  100 #     tag 1: a simple statement (stmt1)
  101 #     tag 2: a variable defined on the stack
  102 #     tag 3: a variable defined in a register
  103 #
  104 #   A block contains:
  105 #     tag: 0
  106 #     statements: (handle list stmt)
  107 #     name: (handle array byte) -- starting with '$'
  108 #
  109 #   A regular statement contains:
  110 #     tag: 1
  111 #     operation: (handle array byte)
  112 #     inouts: (handle list operand)
  113 #     outputs: (handle list var)
  114 #
  115 #   A variable defined on the stack contains:
  116 #     tag: 2
  117 #     name: (handle array byte)
  118 #     type: (handle tree type-id)
  119 #
  120 #   A variable defined in a register contains:
  121 #     tag: 3
  122 #     name: (handle array byte)
  123 #     type: (handle tree type-id)
  124 #     reg: (handle array byte)
  125 
  126 # == Translation: managing the stack
  127 # Now that we know what the language looks like in the large, let's think
  128 # about how translation happens from the bottom up. One crucial piece of the
  129 # puzzle is how Mu will clean up variables defined on the stack for you.
  130 #
  131 # Assume that we maintain a 'functions' list while parsing source code. And a
  132 # 'primitives' list is a global constant. Both these contain enough information
  133 # to perform type-checking on function calls or primitive statements, respectively.
  134 #
  135 # Defining variables pushes them on a stack with the current block depth and
  136 # enough information about their location (stack offset or register).
  137 # Starting a block increments the current block id.
  138 # Each statement now has enough information to emit code for it.
  139 # Ending a block is where the magic happens:
  140 #   pop all variables at the current block depth
  141 #   emit code to restore all register variables introduced at the current depth
  142 #   emit code to clean up all stack variables at the current depth (just increment esp)
  143 #   decrement the current block depth
  144 #
  145 # Formal types:
  146 #   live-vars: stack of vars
  147 #   var:
  148 #     name: (handle array byte)
  149 #     type: (handle tree type-id)
  150 #     block: int
  151 #     stack-offset: int  (added to ebp)
  152 #     register: (handle array byte)
  153 #       either usual register names
  154 #       or '*' to indicate any register
  155 #   At most one of stack-offset or register-index must be non-zero.
  156 #   A register of '*' designates a variable _template_. Only legal in formal
  157 #   parameters for primitives.
  158 
  159 # == Translating a single function call
  160 # This one's easy. Assuming we've already checked things, we just drop the
  161 # outputs (which use hard-coded registers) and emit inputs in a standard format.
  162 #
  163 # out1, out2, out3, ... <- name inout1, inout2, inout3, ...
  164 # =>
  165 # (name inout1 inout2 inout3)
  166 #
  167 # Formal types:
  168 #   functions: linked list of info
  169 #     name: (handle array byte)
  170 #     inouts: linked list of vars
  171 #     outputs: linked list of vars
  172 #     body: block (linked list of statements)
  173 
  174 # == Translating a single primitive instruction
  175 # A second crucial piece of the puzzle is how Mu converts fairly regular
  176 # primitives with their uniform syntax to SubX instructions with their gnarly
  177 # x86 details.
  178 #
  179 # Mu instructions have inputs and outputs. Primitives can have up to 2 of
  180 # them.
  181 # SubX instructions have rm32 and r32 operands.
  182 # The translation between them covers almost all the possibilities.
  183 #   Instructions with 1 inout may turn into ones with 1 rm32
  184 #     (e.g. incrementing a var on the stack)
  185 #   Instructions with 1 output may turn into ones with 1 rm32
  186 #     (e.g. incrementing a var in a register)
  187 #   1 inout and 1 output may turn into 1 rm32 and 1 r32
  188 #     (e.g. adding a var to a reg)
  189 #   2 inouts may turn into 1 rm32 and 1 r32
  190 #     (e.g. adding a reg to a var)
  191 #   1 inout and 1 literal may turn into 1 rm32 and 1 imm32
  192 #     (e.g. adding a constant to a var)
  193 #   1 output and 1 literal may turn into 1 rm32 and 1 imm32
  194 #     (e.g. adding a constant to a reg)
  195 #   2 outputs to hardcoded registers and 1 inout may turn into 1 rm32
  196 #     (special-case: divide edx:eax by a var or reg)
  197 # Observations:
  198 #   We always emit rm32. It may be the first inout or the first output.
  199 #   We may emit r32 or imm32 or neither.
  200 #   When we emit r32 it may come from first inout or second inout or first output.
  201 #
  202 # Accordingly, the formal data structure for a primitive looks like this:
  203 #   primitives: linked list of info
  204 #     name: (handle array byte)
  205 #     mu-inouts: linked list of vars to check
  206 #     mu-outputs: linked list of vars to check; at most a singleton
  207 #     subx-name: (handle array byte)
  208 #     subx-rm32: enum arg-location
  209 #     subx-r32: enum arg-location
  210 #     subx-imm32: enum arg-location
  211 #     subx-disp32: enum arg-location
  212 #     output-is-write-only: boolean
  213 #   arg-location: enum
  214 #     0 means none
  215 #     1 means first inout
  216 #     2 means second inout
  217 #     3 means first output
  218 
  219 # == Translating a block
  220 # Emit block name if necessary
  221 # Emit '{'
  222 # When you encounter a statement, emit it as above
  223 # When you encounter a variable declaration
  224 #   emit any code needed for it (bzeros)
  225 #   push it on the var stack
  226 #   update register dict if necessary
  227 # When you encounter '}'
  228 #   While popping variables off the var stack until block id changes
  229 #     Emit code needed to clean up the stack
  230 #       either increment esp
  231 #       or pop into appropriate register
  232 
  233 # The rest is straightforward.
  234 
  235 == data
  236 
  237 Program:
  238 _Program-functions:  # (handle function)
  239   0/imm32
  240 _Program-functions->payload:
  241   0/imm32
  242 _Program-types:  # (handle typeinfo)
  243   0/imm32
  244 _Program-types->payload:
  245   0/imm32
  246 
  247 # Some constants for simulating the data structures described above.
  248 # Many constants here come with a type in a comment.
  249 #
  250 # Sometimes the type is of the value at that offset for the given type. For
  251 # example, if you start at a function record and move forward Function-inouts
  252 # bytes, you'll find a (handle list var).
  253 #
  254 # At other times, the type is of the constant itself. For example, the type of
  255 # the constant Function-size is (addr int). To get the size of a function,
  256 # look in *Function-size.
  257 
  258 Function-name:  # (handle array byte)
  259   0/imm32
  260 Function-inouts:  # (handle list var)
  261   8/imm32
  262 Function-outputs:  # (handle list var)
  263   0x10/imm32
  264 Function-body:  # (handle block)
  265   0x18/imm32
  266 Function-next:  # (handle function)
  267   0x20/imm32
  268 Function-size:  # (addr int)
  269   0x28/imm32/40
  270 
  271 Primitive-name:  # (handle array byte)
  272   0/imm32
  273 Primitive-inouts:  # (handle list var)
  274   8/imm32
  275 Primitive-outputs:  # (handle list var)
  276   0x10/imm32
  277 Primitive-subx-name:  # (handle array byte)
  278   0x18/imm32
  279 Primitive-subx-rm32:  # enum arg-location
  280   0x20/imm32
  281 Primitive-subx-r32:  # enum arg-location
  282   0x24/imm32
  283 Primitive-subx-imm32:  # enum arg-location
  284   0x28/imm32
  285 Primitive-subx-disp32:  # enum arg-location  -- only for branches
  286   0x2c/imm32
  287 Primitive-output-is-write-only:  # boolean
  288   0x30/imm32
  289 Primitive-next:  # (handle function)
  290   0x34/imm32
  291 Primitive-size:  # (addr int)
  292   0x3c/imm32/60
  293 
  294 Stmt-tag:  # int
  295   0/imm32
  296 
  297 Block-stmts:  # (handle list stmt)
  298   4/imm32
  299 Block-var:  # (handle var)
  300   0xc/imm32
  301 
  302 Stmt1-operation:  # (handle array byte)
  303   4/imm32
  304 Stmt1-inouts:  # (handle stmt-var)
  305   0xc/imm32
  306 Stmt1-outputs:  # (handle stmt-var)
  307   0x14/imm32
  308 
  309 Vardef-var:  # (handle var)
  310   4/imm32
  311 
  312 Regvardef-operation:  # (handle array byte)
  313   4/imm32
  314 Regvardef-inouts:  # (handle stmt-var)
  315   0xc/imm32
  316 Regvardef-outputs:  # (handle stmt-var)  # will have exactly one element
  317   0x14/imm32
  318 
  319 Stmt-size:  # (addr int)
  320   0x1c/imm32
  321 
  322 Var-name:  # (handle array byte)
  323   0/imm32
  324 Var-type:  # (handle tree type-id)
  325   8/imm32
  326 Var-block-depth:  # int -- not available until code-generation time
  327   0x10/imm32
  328 Var-offset:  # int -- not available until code-generation time
  329   0x14/imm32
  330 Var-register:  # (handle array byte) -- name of a register
  331   0x18/imm32
  332 Var-size:  # (addr int)
  333   0x20/imm32
  334 
  335 List-value:  # (handle _)
  336   0/imm32
  337 List-next:  # (handle list _)
  338   8/imm32
  339 List-size:  # (addr int)
  340   0x10/imm32
  341 
  342 # A stmt-var is like a list of vars with call-site specific metadata
  343 Stmt-var-value:  # (handle var)
  344   0/imm32
  345 Stmt-var-next:  # (handle stmt-var)
  346   8/imm32
  347 Stmt-var-is-deref:  # boolean
  348   0x10/imm32
  349 Stmt-var-size:  # (addr int)
  350   0x14/imm32
  351 
  352 # A live-var is a var augmented with information needed for tracking live
  353 # variables.
  354 Live-var-value:  # (handle var)
  355   0/imm32
  356 Live-var-register-spilled:  # boolean; only used if value is in a register, and only during code-gen
  357   8/imm32
  358 Live-var-size:  # (addr int)
  359   0xc/imm32
  360 
  361 # Types are expressed as trees (s-expressions) of type-ids (ints).
  362 
  363 Tree-is-atom:  # boolean
  364   0/imm32
  365 # if left-is-atom?
  366 Tree-value:  # type-id
  367   4/imm32
  368 # unless left-is-atom?
  369 Tree-left:  # (addr tree type-id)
  370   4/imm32
  371 Tree-right:  # (addr tree type-id)
  372   0xc/imm32
  373 #
  374 Tree-size:  # (addr int)
  375   0x14/imm32
  376 
  377 # Types
  378 
  379 # TODO: Turn this data structure into valid Mu, with (fake) handles rather than addrs.
  380 Type-id:  # (stream (addr array byte))
  381   0/imm32/write  # initialized later from Primitive-type-ids
  382   0/imm32/read
  383   0x100/imm32/size
  384   # data
  385   "literal"/imm32  # 0: value is just the name
  386   "int"/imm32  # 1
  387   "addr"/imm32  # 2
  388   "array"/imm32  # 3
  389   "handle"/imm32  # 4
  390   "boolean"/imm32  # 5
  391   "constant"/imm32  # 6: like a literal, but value is an int in Var-offset
  392   "offset"/imm32  # 7: (offset T) is guaranteed to be a 32-bit multiple of size-of(T)
  393   # 0x20
  394   "byte"/imm32  # 8
  395           0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  396   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  397   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  398   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  399   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  400   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  401   0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32 0/imm32
  402 
  403 Primitive-type-ids:  # (addr int)
  404   0x24
  405 
  406 # == Type definitions
  407 # Program->types contains some typeinfo for each type definition.
  408 # Types contain vars with types, but can't specify registers.
  409 Typeinfo-id:  # type-id
  410   0/imm32
  411 Typeinfo-fields:  # (handle table (handle array byte) (handle typeinfo-entry))
  412   4/imm32
  413 # Total size must be >= 0
  414 # During parsing it may take on two additional values:
  415 #   -2: not yet initialized
  416 #   -1: in process of being computed
  417 # See populate-mu-type-sizes for details.
  418 Typeinfo-total-size-in-bytes:  # int
  419   0xc/imm32
  420 Typeinfo-next:  # (handle typeinfo)
  421   0x10/imm32
  422 Typeinfo-size:  # (addr int)
  423   0x18/imm32
  424 
  425 # Each entry in the typeinfo->fields table has a pointer to a string and a
  426 # pointer to a typeinfo-entry.
  427 Typeinfo-fields-row-size:  # (addr int)
  428   0x10/imm32
  429 
  430 # typeinfo-entry objects have information about a field in a single record type
  431 #
  432 # each field of a type is represented using two var's:
  433 #   1. the input var: expected type of the field; convenient for creating using parse-var-with-type
  434 #   2. the output var: a constant containing the byte offset; convenient for code-generation
  435 # computing the output happens after parsing; in the meantime we preserve the
  436 # order of fields in the 'index' field.
  437 Typeinfo-entry-input-var:  # (handle var)
  438   0/imm32
  439 Typeinfo-entry-index:  # int
  440   8/imm32
  441 Typeinfo-entry-output-var:  # (handle var)
  442   0xc/imm32
  443 Typeinfo-entry-size:  # (addr int)
  444   0x14/imm32
  445 
  446 == code
  447 
  448 Entry:
  449     # . prologue
  450     89/<- %ebp 4/r32/esp
  451     (new-segment *Heap-size Heap)
  452     # if (argv[1] == "test') run-tests()
  453     {
  454       # if (argc <= 1) break
  455       81 7/subop/compare *ebp 1/imm32
  456       7e/jump-if-<= break/disp8
  457       # if (argv[1] != "test") break
  458       (kernel-string-equal? *(ebp+8) "test")  # => eax
  459       3d/compare-eax-and 0/imm32/false
  460       74/jump-if-= break/disp8
  461       #
  462       (run-tests)
  463       # syscall(exit, *Num-test-failures)
  464       8b/-> *Num-test-failures 3/r32/ebx
  465       eb/jump $mu-main:end/disp8
  466     }
  467     # otherwise convert Stdin
  468     (convert-mu Stdin Stdout Stderr 0)
  469     (flush Stdout)
  470     # syscall(exit, 0)
  471     bb/copy-to-ebx 0/imm32
  472 $mu-main:end:
  473     e8/call syscall_exit/disp32
  474 
  475 convert-mu:  # in: (addr buffered-file), out: (addr buffered-file), err: (addr buffered-file), ed: (addr exit-descriptor)
  476     # . prologue
  477     55/push-ebp
  478     89/<- %ebp 4/r32/esp
  479     # . save registers
  480     50/push-eax
  481     # initialize global data structures
  482     c7 0/subop/copy *Next-block-index 1/imm32
  483     8b/-> *Primitive-type-ids 0/r32/eax
  484     89/<- *Type-id 0/r32/eax  # stream-write
  485     c7 0/subop/copy *_Program-functions 0/imm32
  486     c7 0/subop/copy *_Program-functions->payload 0/imm32
  487     c7 0/subop/copy *_Program-types 0/imm32
  488     c7 0/subop/copy *_Program-types->payload 0/imm32
  489     #
  490     (parse-mu *(ebp+8) *(ebp+0x10) *(ebp+0x14))
  491     (populate-mu-type-sizes *(ebp+0x10) *(ebp+0x14))
  492 #?     (dump-typeinfos "=== typeinfos\n")
  493     (check-mu-types *(ebp+0x10) *(ebp+0x14))
  494     (emit-subx *(ebp+0xc) *(ebp+0x10) *(ebp+0x14))
  495 $convert-mu:end:
  496     # . restore registers
  497     58/pop-to-eax
  498     # . epilogue
  499     89/<- %esp 5/r32/ebp
  500     5d/pop-to-ebp
  501     c3/return
  502 
  503 test-convert-empty-input:
  504     # empty input => empty output
  505     # . prologue
  506     55/push-ebp
  507     89/<- %ebp 4/r32/esp
  508     # setup
  509     (clear-stream _test-input-stream)
  510     (clear-stream $_test-input-buffered-file->buffer)
  511     (clear-stream _test-output-stream)
  512     (clear-stream $_test-output-buffered-file->buffer)
  513     #
  514     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  515     (flush _test-output-buffered-file)
  516     (check-stream-equal _test-output-stream "" "F - test-convert-empty-input")
  517     # . epilogue
  518     89/<- %esp 5/r32/ebp
  519     5d/pop-to-ebp
  520     c3/return
  521 
  522 test-convert-function-skeleton:
  523     # . prologue
  524     55/push-ebp
  525     89/<- %ebp 4/r32/esp
  526     # setup
  527     (clear-stream _test-input-stream)
  528     (clear-stream $_test-input-buffered-file->buffer)
  529     (clear-stream _test-output-stream)
  530     (clear-stream $_test-output-buffered-file->buffer)
  531     #
  532     (write _test-input-stream "fn foo {\n")
  533     (write _test-input-stream "}\n")
  534     # convert
  535     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  536     (flush _test-output-buffered-file)
  537 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  543     # check output
  544     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-skeleton/0")
  545     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-skeleton/1")
  546     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-skeleton/2")
  547     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-skeleton/3")
  548     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-skeleton/4")
  549     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-skeleton/5")
  550     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-skeleton/6")
  551     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-skeleton/7")
  552     # . epilogue
  553     89/<- %esp 5/r32/ebp
  554     5d/pop-to-ebp
  555     c3/return
  556 
  557 test-convert-multiple-function-skeletons:
  558     # . prologue
  559     55/push-ebp
  560     89/<- %ebp 4/r32/esp
  561     # setup
  562     (clear-stream _test-input-stream)
  563     (clear-stream $_test-input-buffered-file->buffer)
  564     (clear-stream _test-output-stream)
  565     (clear-stream $_test-output-buffered-file->buffer)
  566     #
  567     (write _test-input-stream "fn foo {\n")
  568     (write _test-input-stream "}\n")
  569     (write _test-input-stream "fn bar {\n")
  570     (write _test-input-stream "}\n")
  571     # convert
  572     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  573     (flush _test-output-buffered-file)
  574 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  580     # check first function
  581     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-multiple-function-skeletons/0")
  582     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-multiple-function-skeletons/1")
  583     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-multiple-function-skeletons/2")
  584     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-multiple-function-skeletons/3")
  585     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-multiple-function-skeletons/4")
  586     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-multiple-function-skeletons/5")
  587     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-multiple-function-skeletons/6")
  588     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-multiple-function-skeletons/7")
  589     # check second function
  590     (check-next-stream-line-equal _test-output-stream "bar:"                    "F - test-convert-multiple-function-skeletons/10")
  591     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-multiple-function-skeletons/11")
  592     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-multiple-function-skeletons/12")
  593     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-multiple-function-skeletons/13")
  594     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-multiple-function-skeletons/14")
  595     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-multiple-function-skeletons/15")
  596     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-multiple-function-skeletons/16")
  597     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-multiple-function-skeletons/17")
  598     # . epilogue
  599     89/<- %esp 5/r32/ebp
  600     5d/pop-to-ebp
  601     c3/return
  602 
  603 test-convert-function-with-arg:
  604     # . prologue
  605     55/push-ebp
  606     89/<- %ebp 4/r32/esp
  607     # setup
  608     (clear-stream _test-input-stream)
  609     (clear-stream $_test-input-buffered-file->buffer)
  610     (clear-stream _test-output-stream)
  611     (clear-stream $_test-output-buffered-file->buffer)
  612     #
  613     (write _test-input-stream "fn foo n: int {\n")
  614     (write _test-input-stream "}\n")
  615     # convert
  616     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  617     (flush _test-output-buffered-file)
  618 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  624     # check output
  625     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-arg/0")
  626     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-arg/1")
  627     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-arg/2")
  628     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-arg/3")
  629     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-arg/4")
  630     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-arg/5")
  631     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-arg/6")
  632     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-arg/7")
  633     # . epilogue
  634     89/<- %esp 5/r32/ebp
  635     5d/pop-to-ebp
  636     c3/return
  637 
  638 test-convert-function-with-arg-and-body:
  639     # . prologue
  640     55/push-ebp
  641     89/<- %ebp 4/r32/esp
  642     # setup
  643     (clear-stream _test-input-stream)
  644     (clear-stream $_test-input-buffered-file->buffer)
  645     (clear-stream _test-output-stream)
  646     (clear-stream $_test-output-buffered-file->buffer)
  647     #
  648     (write _test-input-stream "fn foo n: int {\n")
  649     (write _test-input-stream "  increment n\n")
  650     (write _test-input-stream "}\n")
  651     # convert
  652     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  653     (flush _test-output-buffered-file)
  654 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  660     # check output
  661     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-arg-and-body/0")
  662     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-arg-and-body/1")
  663     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-arg-and-body/2")
  664     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-arg-and-body/3")
  665     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-arg-and-body/4")
  666     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-arg-and-body/5")
  667     (check-next-stream-line-equal _test-output-stream "    ff 0/subop/increment *(ebp+0x00000008)"  "F - test-convert-function-with-arg-and-body/6")
  668     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-arg-and-body/7")
  669     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-arg-and-body/8")
  670     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-arg-and-body/9")
  671     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-arg-and-body/10")
  672     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-arg-and-body/11")
  673     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-arg-and-body/12")
  674     # . epilogue
  675     89/<- %esp 5/r32/ebp
  676     5d/pop-to-ebp
  677     c3/return
  678 
  679 test-convert-function-distinguishes-args:
  680     # . prologue
  681     55/push-ebp
  682     89/<- %ebp 4/r32/esp
  683     # setup
  684     (clear-stream _test-input-stream)
  685     (clear-stream $_test-input-buffered-file->buffer)
  686     (clear-stream _test-output-stream)
  687     (clear-stream $_test-output-buffered-file->buffer)
  688     #
  689     (write _test-input-stream "fn foo a: int, b: int {\n")
  690     (write _test-input-stream "  increment b\n")
  691     (write _test-input-stream "}\n")
  692     # convert
  693     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  694     (flush _test-output-buffered-file)
  695 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  701     # check output
  702     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-distinguishes-args/0")
  703     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-distinguishes-args/1")
  704     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-distinguishes-args/2")
  705     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-distinguishes-args/3")
  706     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-distinguishes-args/4")
  707     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-distinguishes-args/5")
  708     (check-next-stream-line-equal _test-output-stream "    ff 0/subop/increment *(ebp+0x0000000c)"  "F - test-convert-function-distinguishes-args/6")
  709     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-distinguishes-args/7")
  710     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-distinguishes-args/8")
  711     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-distinguishes-args/9")
  712     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-distinguishes-args/10")
  713     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-distinguishes-args/11")
  714     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-distinguishes-args/12")
  715     # . epilogue
  716     89/<- %esp 5/r32/ebp
  717     5d/pop-to-ebp
  718     c3/return
  719 
  720 test-convert-function-returns-result:
  721     # . prologue
  722     55/push-ebp
  723     89/<- %ebp 4/r32/esp
  724     # setup
  725     (clear-stream _test-input-stream)
  726     (clear-stream $_test-input-buffered-file->buffer)
  727     (clear-stream _test-output-stream)
  728     (clear-stream $_test-output-buffered-file->buffer)
  729     #
  730     (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n")
  731     (write _test-input-stream "  result <- copy a\n")
  732     (write _test-input-stream "  result <- increment\n")
  733     (write _test-input-stream "}\n")
  734     # convert
  735     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  736     (flush _test-output-buffered-file)
  737 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  743     # check output
  744     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-returns-result/0")
  745     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-returns-result/1")
  746     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-returns-result/2")
  747     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-returns-result/3")
  748     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-returns-result/4")
  749     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-returns-result/5")
  750     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-function-returns-result/6")
  751     (check-next-stream-line-equal _test-output-stream "    40/increment-eax"    "F - test-convert-function-returns-result/7")
  752     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-returns-result/8")
  753     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-returns-result/9")
  754     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-returns-result/10")
  755     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-returns-result/11")
  756     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-returns-result/12")
  757     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-returns-result/13")
  758     # . epilogue
  759     89/<- %esp 5/r32/ebp
  760     5d/pop-to-ebp
  761     c3/return
  762 
  763 test-convert-function-with-literal-arg:
  764     # . prologue
  765     55/push-ebp
  766     89/<- %ebp 4/r32/esp
  767     # setup
  768     (clear-stream _test-input-stream)
  769     (clear-stream $_test-input-buffered-file->buffer)
  770     (clear-stream _test-output-stream)
  771     (clear-stream $_test-output-buffered-file->buffer)
  772     #
  773     (write _test-input-stream "fn foo a: int, b: int -> result/eax: int {\n")
  774     (write _test-input-stream "  result <- copy a\n")
  775     (write _test-input-stream "  result <- add 1\n")
  776     (write _test-input-stream "}\n")
  777     # convert
  778     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  779     (flush _test-output-buffered-file)
  780 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  786     # check output
  787     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-literal-arg/0")
  788     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-literal-arg/1")
  789     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-literal-arg/2")
  790     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-literal-arg/3")
  791     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-literal-arg/4")
  792     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-literal-arg/5")
  793     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-function-with-literal-arg/6")
  794     (check-next-stream-line-equal _test-output-stream "    05/add-to-eax 1/imm32"  "F - test-convert-function-with-literal-arg/7")
  795     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-literal-arg/8")
  796     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-literal-arg/9")
  797     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-literal-arg/10")
  798     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-literal-arg/11")
  799     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-literal-arg/12")
  800     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-literal-arg/13")
  801     # . epilogue
  802     89/<- %esp 5/r32/ebp
  803     5d/pop-to-ebp
  804     c3/return
  805 
  806 test-convert-function-with-literal-arg-2:
  807     # . prologue
  808     55/push-ebp
  809     89/<- %ebp 4/r32/esp
  810     # setup
  811     (clear-stream _test-input-stream)
  812     (clear-stream $_test-input-buffered-file->buffer)
  813     (clear-stream _test-output-stream)
  814     (clear-stream $_test-output-buffered-file->buffer)
  815     #
  816     (write _test-input-stream "fn foo a: int, b: int -> result/ebx: int {\n")
  817     (write _test-input-stream "  result <- copy a\n")
  818     (write _test-input-stream "  result <- add 1\n")
  819     (write _test-input-stream "}\n")
  820     # convert
  821     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  822     (flush _test-output-buffered-file)
  823 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  829     # check output
  830     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-literal-arg-2/0")
  831     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-literal-arg-2/1")
  832     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-literal-arg-2/2")
  833     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-literal-arg-2/3")
  834     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-literal-arg-2/4")
  835     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-literal-arg-2/5")
  836     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000003/r32"  "F - test-convert-function-with-literal-arg-2/6")
  837     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %ebx 1/imm32"  "F - test-convert-function-with-literal-arg-2/7")
  838     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-literal-arg-2/8")
  839     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-literal-arg-2/9")
  840     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-literal-arg-2/10")
  841     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-literal-arg-2/11")
  842     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-literal-arg-2/12")
  843     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-literal-arg-2/13")
  844     # . epilogue
  845     89/<- %esp 5/r32/ebp
  846     5d/pop-to-ebp
  847     c3/return
  848 
  849 # HERE
  850 test-convert-function-call-with-literal-arg:
  851     # . prologue
  852     55/push-ebp
  853     89/<- %ebp 4/r32/esp
  854     # setup
  855     (clear-stream _test-input-stream)
  856     (clear-stream $_test-input-buffered-file->buffer)
  857     (clear-stream _test-output-stream)
  858     (clear-stream $_test-output-buffered-file->buffer)
  859     #
  860     (write _test-input-stream "fn main -> result/ebx: int {\n")
  861     (write _test-input-stream "  result <- do-add 3 4\n")
  862     (write _test-input-stream "}\n")
  863     (write _test-input-stream "fn do-add a: int, b: int -> result/ebx: int {\n")
  864     (write _test-input-stream "  result <- copy a\n")
  865     (write _test-input-stream "  result <- add b\n")
  866     (write _test-input-stream "}\n")
  867     # convert
  868     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  869     (flush _test-output-buffered-file)
  870 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  876     # check output
  877     (check-next-stream-line-equal _test-output-stream "main:"                   "F - test-convert-function-call-with-literal-arg/0")
  878     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-literal-arg/1")
  879     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-literal-arg/2")
  880     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-literal-arg/3")
  881     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-literal-arg/4")
  882     (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:"  "F - test-convert-function-call-with-literal-arg/5")
  883     (check-next-stream-line-equal _test-output-stream "    (do-add 3 4)"        "F - test-convert-function-call-with-literal-arg/6")
  884     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-literal-arg/7")
  885     (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call-with-literal-arg/8")
  886     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-literal-arg/9")
  887     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-literal-arg/10")
  888     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-literal-arg/11")
  889     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-literal-arg/12")
  890     (check-next-stream-line-equal _test-output-stream "do-add:"                 "F - test-convert-function-call-with-literal-arg/13")
  891     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-literal-arg/14")
  892     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-literal-arg/15")
  893     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-literal-arg/16")
  894     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-literal-arg/17")
  895     (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:loop:"  "F - test-convert-function-call-with-literal-arg/18")
  896     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000003/r32"  "F - test-convert-function-call-with-literal-arg/19")
  897     (check-next-stream-line-equal _test-output-stream "    03/add *(ebp+0x0000000c) 0x00000003/r32"  "F - test-convert-function-call-with-literal-arg/20")
  898     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-literal-arg/21")
  899     (check-next-stream-line-equal _test-output-stream "$do-add:0x00000002:break:"  "F - test-convert-function-call-with-literal-arg/22")
  900     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-literal-arg/23")
  901     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-literal-arg/24")
  902     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-literal-arg/25")
  903     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-literal-arg/26")
  904     # . epilogue
  905     89/<- %esp 5/r32/ebp
  906     5d/pop-to-ebp
  907     c3/return
  908 
  909 test-convert-function-with-local-var-in-mem:
  910     # . prologue
  911     55/push-ebp
  912     89/<- %ebp 4/r32/esp
  913     # setup
  914     (clear-stream _test-input-stream)
  915     (clear-stream $_test-input-buffered-file->buffer)
  916     (clear-stream _test-output-stream)
  917     (clear-stream $_test-output-buffered-file->buffer)
  918     #
  919     (write _test-input-stream "fn foo {\n")
  920     (write _test-input-stream "  var x: int\n")
  921     (write _test-input-stream "  increment x\n")
  922     (write _test-input-stream "}\n")
  923     # convert
  924     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
  925     (flush _test-output-buffered-file)
  926 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
  932     # check output
  933     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-in-mem/0")
  934     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-in-mem/1")
  935     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-in-mem/2")
  936     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-in-mem/3")
  937     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-in-mem/4")
  938     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-in-mem/5")
  939     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-with-local-var-in-mem/6")
  940     (check-next-stream-line-equal _test-output-stream "    ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-local-var-in-mem/7")
  941     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-local-var-in-mem/8")
  942     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-in-mem/9")
  943     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-in-mem/10")
  944     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-in-mem/11")
  945     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-in-mem/12")
  946     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-in-mem/13")
  947     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-in-mem/14")
  948     # . epilogue
  949     89/<- %esp 5/r32/ebp
  950     5d/pop-to-ebp
  951     c3/return
  952 
  953 test-local-var-in-mem-has-no-initializer:
  954     # . prologue
  955     55/push-ebp
  956     89/<- %ebp 4/r32/esp
  957     # setup
  958     (clear-stream _test-input-stream)
  959     (clear-stream $_test-input-buffered-file->buffer)
  960     (clear-stream _test-output-stream)
  961     (clear-stream $_test-output-buffered-file->buffer)
  962     (clear-stream _test-error-stream)
  963     (clear-stream $_test-error-buffered-file->buffer)
  964     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
  965     68/push 0/imm32
  966     68/push 0/imm32
  967     89/<- %edx 4/r32/esp
  968     (tailor-exit-descriptor %edx 0x10)
  969     #
  970     (write _test-input-stream "fn foo {\n")
  971     (write _test-input-stream "  var x: int <- copy 0\n")
  972     (write _test-input-stream "  increment x\n")
  973     (write _test-input-stream "}\n")
  974     # convert
  975     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
  976     # registers except esp clobbered at this point
  977     # restore ed
  978     89/<- %edx 4/r32/esp
  979     (flush _test-output-buffered-file)
  980     (flush _test-error-buffered-file)
  981 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
  987     # check output
  988     (check-stream-equal _test-output-stream  ""  "F - test-var-in-mem-has-no-initializer: output should be empty")
  989     (check-next-stream-line-equal _test-error-stream  "fn foo: var x: variables on the stack can't take an initializer"  "F - test-var-in-mem-has-no-initializer: error message")
  990     # check that stop(1) was called
  991     (check-ints-equal *(edx+4) 2 "F - test-var-in-mem-has-no-initializer: exit status")
  992     # don't restore from ebp
  993     81 0/subop/add %esp 8/imm32
  994     # . epilogue
  995     5d/pop-to-ebp
  996     c3/return
  997 
  998 test-convert-function-with-local-var-with-compound-type-in-mem:
  999     # . prologue
 1000     55/push-ebp
 1001     89/<- %ebp 4/r32/esp
 1002     # setup
 1003     (clear-stream _test-input-stream)
 1004     (clear-stream $_test-input-buffered-file->buffer)
 1005     (clear-stream _test-output-stream)
 1006     (clear-stream $_test-output-buffered-file->buffer)
 1007     #
 1008     (write _test-input-stream "fn foo {\n")
 1009     (write _test-input-stream "  var x: (addr int)\n")
 1010     (write _test-input-stream "  copy-to x, 0\n")
 1011     (write _test-input-stream "}\n")
 1012     # convert
 1013     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1014     (flush _test-output-buffered-file)
 1015 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1021     # check output
 1022     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-with-compound-type-in-mem/0")
 1023     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-with-compound-type-in-mem/1")
 1024     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-with-compound-type-in-mem/2")
 1025     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-with-compound-type-in-mem/3")
 1026     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-with-compound-type-in-mem/4")
 1027     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-with-compound-type-in-mem/5")
 1028     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-with-local-var-with-compound-type-in-mem/6")
 1029     (check-next-stream-line-equal _test-output-stream "    c7 0/subop/copy *(ebp+0xfffffffc) 0/imm32"  "F - test-convert-function-with-local-var-with-compound-type-in-mem/7")
 1030     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-local-var-with-compound-type-in-mem/8")
 1031     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-with-compound-type-in-mem/9")
 1032     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-with-compound-type-in-mem/10")
 1033     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-with-compound-type-in-mem/11")
 1034     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-with-compound-type-in-mem/12")
 1035     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-with-compound-type-in-mem/13")
 1036     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-with-compound-type-in-mem/14")
 1037     # . epilogue
 1038     89/<- %esp 5/r32/ebp
 1039     5d/pop-to-ebp
 1040     c3/return
 1041 
 1042 test-convert-function-with-local-var-in-reg:
 1043     # . prologue
 1044     55/push-ebp
 1045     89/<- %ebp 4/r32/esp
 1046     # setup
 1047     (clear-stream _test-input-stream)
 1048     (clear-stream $_test-input-buffered-file->buffer)
 1049     (clear-stream _test-output-stream)
 1050     (clear-stream $_test-output-buffered-file->buffer)
 1051     #
 1052     (write _test-input-stream "fn foo {\n")
 1053     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 1054     (write _test-input-stream "  x <- increment\n")
 1055     (write _test-input-stream "}\n")
 1056     # convert
 1057     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1058     (flush _test-output-buffered-file)
 1059 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1065     # check output
 1066     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-in-reg/0")
 1067     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-in-reg/1")
 1068     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-in-reg/2")
 1069     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-in-reg/3")
 1070     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-in-reg/4")
 1071     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-in-reg/5")
 1072     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-with-local-var-in-reg/6")
 1073     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-convert-function-with-local-var-in-reg/7")
 1074     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-convert-function-with-local-var-in-reg/8")
 1075     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-in-reg/9")
 1076     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-in-reg/10")
 1077     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-in-reg/11")
 1078     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-in-reg/12")
 1079     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-in-reg/13")
 1080     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-in-reg/14")
 1081     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-in-reg/15")
 1082     # . epilogue
 1083     89/<- %esp 5/r32/ebp
 1084     5d/pop-to-ebp
 1085     c3/return
 1086 
 1087 test-convert-function-with-second-local-var-in-same-reg:
 1088     # . prologue
 1089     55/push-ebp
 1090     89/<- %ebp 4/r32/esp
 1091     # setup
 1092     (clear-stream _test-input-stream)
 1093     (clear-stream $_test-input-buffered-file->buffer)
 1094     (clear-stream _test-output-stream)
 1095     (clear-stream $_test-output-buffered-file->buffer)
 1096     #
 1097     (write _test-input-stream "fn foo {\n")
 1098     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 1099     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 1100     (write _test-input-stream "  y <- increment\n")
 1101     (write _test-input-stream "}\n")
 1102     # convert
 1103     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1104     (flush _test-output-buffered-file)
 1105 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1111     # check output
 1112     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-second-local-var-in-same-reg/0")
 1113     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-second-local-var-in-same-reg/1")
 1114     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-second-local-var-in-same-reg/2")
 1115     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-second-local-var-in-same-reg/3")
 1116     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-second-local-var-in-same-reg/4")
 1117     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-second-local-var-in-same-reg/5")
 1118     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-with-second-local-var-in-same-reg/6")
 1119     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-convert-function-with-second-local-var-in-same-reg/7")
 1120     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 4/imm32"  "F - test-convert-function-with-second-local-var-in-same-reg/8")
 1121     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-convert-function-with-second-local-var-in-same-reg/9")
 1122     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-with-second-local-var-in-same-reg/10")
 1123     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-second-local-var-in-same-reg/11")
 1124     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-second-local-var-in-same-reg/12")
 1125     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-second-local-var-in-same-reg/13")
 1126     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-second-local-var-in-same-reg/14")
 1127     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-second-local-var-in-same-reg/15")
 1128     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-second-local-var-in-same-reg/16")
 1129     # . epilogue
 1130     89/<- %esp 5/r32/ebp
 1131     5d/pop-to-ebp
 1132     c3/return
 1133 
 1134 test-read-clobbered-reg-var:
 1135     # . prologue
 1136     55/push-ebp
 1137     89/<- %ebp 4/r32/esp
 1138     # setup
 1139     (clear-stream _test-input-stream)
 1140     (clear-stream $_test-input-buffered-file->buffer)
 1141     (clear-stream _test-output-stream)
 1142     (clear-stream $_test-output-buffered-file->buffer)
 1143     (clear-stream _test-error-stream)
 1144     (clear-stream $_test-error-buffered-file->buffer)
 1145     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)  # bytes of args in call to convert-mu
 1146     68/push 0/imm32
 1147     68/push 0/imm32
 1148     89/<- %edx 4/r32/esp
 1149     (tailor-exit-descriptor %edx 0x10)
 1150     #
 1151     (write _test-input-stream "fn foo {\n")
 1152     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 1153     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 1154     (write _test-input-stream "  x <- increment\n")
 1155     (write _test-input-stream "}\n")
 1156     # convert
 1157     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1158     # registers except esp clobbered at this point
 1159     # restore ed
 1160     89/<- %edx 4/r32/esp
 1161     (flush _test-output-buffered-file)
 1162     (flush _test-error-buffered-file)
 1163 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1169     # check output
 1170     (check-stream-equal _test-output-stream  ""  "F - test-read-clobbered-reg-var: output should be empty")
 1171     (check-next-stream-line-equal _test-error-stream  "fn foo: register ecx reads var 'x' after writing var 'y'"  "F - test-read-clobbered-reg-var: error message")
 1172     # check that stop(1) was called
 1173     (check-ints-equal *(edx+4) 2 "F - test-read-clobbered-reg-var: exit status")
 1174     # don't restore from ebp
 1175     81 0/subop/add %esp 8/imm32
 1176     # . epilogue
 1177     5d/pop-to-ebp
 1178     c3/return
 1179 
 1180 test-convert-function-call:
 1181     # . prologue
 1182     55/push-ebp
 1183     89/<- %ebp 4/r32/esp
 1184     # setup
 1185     (clear-stream _test-input-stream)
 1186     (clear-stream $_test-input-buffered-file->buffer)
 1187     (clear-stream _test-output-stream)
 1188     (clear-stream $_test-output-buffered-file->buffer)
 1189     #
 1190     (write _test-input-stream "fn main -> result/ebx: int {\n")
 1191     (write _test-input-stream "  result <- foo\n")
 1192     (write _test-input-stream "}\n")
 1193     (write _test-input-stream "fn foo -> result/ebx: int {\n")
 1194     (write _test-input-stream "  result <- copy 3\n")
 1195     (write _test-input-stream "}\n")
 1196     # convert
 1197     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1198     (flush _test-output-buffered-file)
 1199 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1205     # check output
 1206     (check-next-stream-line-equal _test-output-stream "main:"                   "F - test-convert-function-call/0")
 1207     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call/1")
 1208     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call/2")
 1209     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call/3")
 1210     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call/4")
 1211     (check-next-stream-line-equal _test-output-stream "$main:0x00000001:loop:"  "F - test-convert-function-call/5")
 1212     (check-next-stream-line-equal _test-output-stream "    (foo)"               "F - test-convert-function-call/6")
 1213     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call/7")
 1214     (check-next-stream-line-equal _test-output-stream "$main:0x00000001:break:" "F - test-convert-function-call/8")
 1215     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call/9")
 1216     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call/10")
 1217     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call/11")
 1218     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call/12")
 1219     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-call/13")
 1220     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call/14")
 1221     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call/15")
 1222     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call/16")
 1223     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call/17")
 1224     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"  "F - test-convert-function-call/18")
 1225     (check-next-stream-line-equal _test-output-stream "    bb/copy-to-ebx 3/imm32"  "F - test-convert-function-call/19")
 1226     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call/20")
 1227     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-call/21")
 1228     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call/22")
 1229     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call/23")
 1230     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call/24")
 1231     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call/25")
 1232     # . epilogue
 1233     89/<- %esp 5/r32/ebp
 1234     5d/pop-to-ebp
 1235     c3/return
 1236 
 1237 test-convert-function-call-with-incorrect-inout-type:
 1238     # . prologue
 1239     55/push-ebp
 1240     89/<- %ebp 4/r32/esp
 1241     # setup
 1242     (clear-stream _test-input-stream)
 1243     (clear-stream $_test-input-buffered-file->buffer)
 1244     (clear-stream _test-output-stream)
 1245     (clear-stream $_test-output-buffered-file->buffer)
 1246     (clear-stream _test-error-stream)
 1247     (clear-stream $_test-error-buffered-file->buffer)
 1248     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1249     68/push 0/imm32
 1250     68/push 0/imm32
 1251     89/<- %edx 4/r32/esp
 1252     (tailor-exit-descriptor %edx 0x10)
 1253     #
 1254     (write _test-input-stream "fn f {\n")
 1255     (write _test-input-stream "  var x: int\n")
 1256     (write _test-input-stream "  g x\n")
 1257     (write _test-input-stream "}\n")
 1258     (write _test-input-stream "fn g a: foo {\n")
 1259     (write _test-input-stream "}\n")
 1260     # convert
 1261     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1262     # registers except esp clobbered at this point
 1263     # restore ed
 1264     89/<- %edx 4/r32/esp
 1265     (flush _test-output-buffered-file)
 1266     (flush _test-error-buffered-file)
 1267 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1273     # check output
 1274     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-incorrect-inout-type: output should be empty")
 1275     (check-next-stream-line-equal _test-error-stream  "fn f: call g: type for inout 'x' is not right"  "F - test-convert-function-call-with-incorrect-inout-type: error message")
 1276     # check that stop(1) was called
 1277     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-inout-type: exit status")
 1278     # don't restore from ebp
 1279     81 0/subop/add %esp 8/imm32
 1280     5d/pop-to-ebp
 1281     c3/return
 1282 
 1283 test-convert-function-call-with-too-few-inouts:
 1284     # . prologue
 1285     55/push-ebp
 1286     89/<- %ebp 4/r32/esp
 1287     # setup
 1288     (clear-stream _test-input-stream)
 1289     (clear-stream $_test-input-buffered-file->buffer)
 1290     (clear-stream _test-output-stream)
 1291     (clear-stream $_test-output-buffered-file->buffer)
 1292     (clear-stream _test-error-stream)
 1293     (clear-stream $_test-error-buffered-file->buffer)
 1294     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1295     68/push 0/imm32
 1296     68/push 0/imm32
 1297     89/<- %edx 4/r32/esp
 1298     (tailor-exit-descriptor %edx 0x10)
 1299     #
 1300     (write _test-input-stream "fn f {\n")
 1301     (write _test-input-stream "  g\n")
 1302     (write _test-input-stream "}\n")
 1303     (write _test-input-stream "fn g a: int {\n")
 1304     (write _test-input-stream "}\n")
 1305     # convert
 1306     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1307     # registers except esp clobbered at this point
 1308     # restore ed
 1309     89/<- %edx 4/r32/esp
 1310     (flush _test-output-buffered-file)
 1311     (flush _test-error-buffered-file)
 1312 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1318     # check output
 1319     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-too-few-inouts: output should be empty")
 1320     (check-next-stream-line-equal _test-error-stream  "fn f: call g: too few inouts"  "F - test-convert-function-call-with-too-few-inouts: error message")
 1321     # check that stop(1) was called
 1322     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-inouts: exit status")
 1323     # don't restore from ebp
 1324     81 0/subop/add %esp 8/imm32
 1325     5d/pop-to-ebp
 1326     c3/return
 1327 
 1328 test-convert-function-call-with-too-many-inouts:
 1329     # . prologue
 1330     55/push-ebp
 1331     89/<- %ebp 4/r32/esp
 1332     # setup
 1333     (clear-stream _test-input-stream)
 1334     (clear-stream $_test-input-buffered-file->buffer)
 1335     (clear-stream _test-output-stream)
 1336     (clear-stream $_test-output-buffered-file->buffer)
 1337     (clear-stream _test-error-stream)
 1338     (clear-stream $_test-error-buffered-file->buffer)
 1339     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1340     68/push 0/imm32
 1341     68/push 0/imm32
 1342     89/<- %edx 4/r32/esp
 1343     (tailor-exit-descriptor %edx 0x10)
 1344     #
 1345     (write _test-input-stream "fn f {\n")
 1346     (write _test-input-stream "  var x: int\n")
 1347     (write _test-input-stream "  g x\n")
 1348     (write _test-input-stream "}\n")
 1349     (write _test-input-stream "fn g {\n")
 1350     (write _test-input-stream "}\n")
 1351     # convert
 1352     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1353     # registers except esp clobbered at this point
 1354     # restore ed
 1355     89/<- %edx 4/r32/esp
 1356     (flush _test-output-buffered-file)
 1357     (flush _test-error-buffered-file)
 1358 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1364     # check output
 1365     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-too-many-inouts: output should be empty")
 1366     (check-next-stream-line-equal _test-error-stream  "fn f: call g: too many inouts"  "F - test-convert-function-call-with-too-many-inouts: error message")
 1367     # check that stop(1) was called
 1368     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-inouts: exit status")
 1369     # don't restore from ebp
 1370     81 0/subop/add %esp 8/imm32
 1371     5d/pop-to-ebp
 1372     c3/return
 1373 
 1374 test-convert-function-call-with-incorrect-output-type:
 1375     # . prologue
 1376     55/push-ebp
 1377     89/<- %ebp 4/r32/esp
 1378     # setup
 1379     (clear-stream _test-input-stream)
 1380     (clear-stream $_test-input-buffered-file->buffer)
 1381     (clear-stream _test-output-stream)
 1382     (clear-stream $_test-output-buffered-file->buffer)
 1383     (clear-stream _test-error-stream)
 1384     (clear-stream $_test-error-buffered-file->buffer)
 1385     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1386     68/push 0/imm32
 1387     68/push 0/imm32
 1388     89/<- %edx 4/r32/esp
 1389     (tailor-exit-descriptor %edx 0x10)
 1390     #
 1391     (write _test-input-stream "fn f {\n")
 1392     (write _test-input-stream "  var x/eax: int <- g\n")
 1393     (write _test-input-stream "}\n")
 1394     (write _test-input-stream "fn g -> a/eax: foo {\n")
 1395     (write _test-input-stream "}\n")
 1396     # convert
 1397     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1398     # registers except esp clobbered at this point
 1399     # restore ed
 1400     89/<- %edx 4/r32/esp
 1401     (flush _test-output-buffered-file)
 1402     (flush _test-error-buffered-file)
 1403 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1409     # check output
 1410     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-incorrect-output-type: output should be empty")
 1411     (check-next-stream-line-equal _test-error-stream  "fn f: call g: type for output 'x' is not right"  "F - test-convert-function-call-with-incorrect-output-type: error message")
 1412     # check that stop(1) was called
 1413     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-type: exit status")
 1414     # don't restore from ebp
 1415     81 0/subop/add %esp 8/imm32
 1416     5d/pop-to-ebp
 1417     c3/return
 1418 
 1419 test-convert-function-call-with-too-few-outputs:
 1420     # . prologue
 1421     55/push-ebp
 1422     89/<- %ebp 4/r32/esp
 1423     # setup
 1424     (clear-stream _test-input-stream)
 1425     (clear-stream $_test-input-buffered-file->buffer)
 1426     (clear-stream _test-output-stream)
 1427     (clear-stream $_test-output-buffered-file->buffer)
 1428     (clear-stream _test-error-stream)
 1429     (clear-stream $_test-error-buffered-file->buffer)
 1430     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1431     68/push 0/imm32
 1432     68/push 0/imm32
 1433     89/<- %edx 4/r32/esp
 1434     (tailor-exit-descriptor %edx 0x10)
 1435     #
 1436     (write _test-input-stream "fn f {\n")
 1437     (write _test-input-stream "  g\n")
 1438     (write _test-input-stream "}\n")
 1439     (write _test-input-stream "fn g -> a/eax: int {\n")
 1440     (write _test-input-stream "}\n")
 1441     # convert
 1442     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1443     # registers except esp clobbered at this point
 1444     # restore ed
 1445     89/<- %edx 4/r32/esp
 1446     (flush _test-output-buffered-file)
 1447     (flush _test-error-buffered-file)
 1448 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1454     # check output
 1455     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-too-few-outputs: output should be empty")
 1456     (check-next-stream-line-equal _test-error-stream  "fn f: call g: too few outputs"  "F - test-convert-function-call-with-too-few-outputs: error message")
 1457     # check that stop(1) was called
 1458     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-few-outputs: exit status")
 1459     # don't restore from ebp
 1460     81 0/subop/add %esp 8/imm32
 1461     5d/pop-to-ebp
 1462     c3/return
 1463 
 1464 test-convert-function-call-with-too-many-outputs:
 1465     # . prologue
 1466     55/push-ebp
 1467     89/<- %ebp 4/r32/esp
 1468     # setup
 1469     (clear-stream _test-input-stream)
 1470     (clear-stream $_test-input-buffered-file->buffer)
 1471     (clear-stream _test-output-stream)
 1472     (clear-stream $_test-output-buffered-file->buffer)
 1473     (clear-stream _test-error-stream)
 1474     (clear-stream $_test-error-buffered-file->buffer)
 1475     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1476     68/push 0/imm32
 1477     68/push 0/imm32
 1478     89/<- %edx 4/r32/esp
 1479     (tailor-exit-descriptor %edx 0x10)
 1480     #
 1481     (write _test-input-stream "fn f {\n")
 1482     (write _test-input-stream "  var x/eax: int <- g\n")
 1483     (write _test-input-stream "}\n")
 1484     (write _test-input-stream "fn g {\n")
 1485     (write _test-input-stream "}\n")
 1486     # convert
 1487     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1488     # registers except esp clobbered at this point
 1489     # restore ed
 1490     89/<- %edx 4/r32/esp
 1491     (flush _test-output-buffered-file)
 1492     (flush _test-error-buffered-file)
 1493 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1499     # check output
 1500     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-too-many-outputs: output should be empty")
 1501     (check-next-stream-line-equal _test-error-stream  "fn f: call g: too many outputs"  "F - test-convert-function-call-with-too-many-outputs: error message")
 1502     # check that stop(1) was called
 1503     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-too-many-outputs: exit status")
 1504     # don't restore from ebp
 1505     81 0/subop/add %esp 8/imm32
 1506     5d/pop-to-ebp
 1507     c3/return
 1508 
 1509 test-convert-function-call-with-incorrect-output-register:
 1510     # . prologue
 1511     55/push-ebp
 1512     89/<- %ebp 4/r32/esp
 1513     # setup
 1514     (clear-stream _test-input-stream)
 1515     (clear-stream $_test-input-buffered-file->buffer)
 1516     (clear-stream _test-output-stream)
 1517     (clear-stream $_test-output-buffered-file->buffer)
 1518     (clear-stream _test-error-stream)
 1519     (clear-stream $_test-error-buffered-file->buffer)
 1520     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1521     68/push 0/imm32
 1522     68/push 0/imm32
 1523     89/<- %edx 4/r32/esp
 1524     (tailor-exit-descriptor %edx 0x10)
 1525     #
 1526     (write _test-input-stream "fn f {\n")
 1527     (write _test-input-stream "  var x/ecx: int <- g\n")
 1528     (write _test-input-stream "}\n")
 1529     (write _test-input-stream "fn g -> a/eax: int {\n")
 1530     (write _test-input-stream "}\n")
 1531     # convert
 1532     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1533     # registers except esp clobbered at this point
 1534     # restore ed
 1535     89/<- %edx 4/r32/esp
 1536     (flush _test-output-buffered-file)
 1537     (flush _test-error-buffered-file)
 1538 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1544     # check output
 1545     (check-stream-equal _test-output-stream  ""  "F - test-convert-function-call-with-incorrect-output-register: output should be empty")
 1546     (check-next-stream-line-equal _test-error-stream  "fn f: call g: register for output 'x' is not right"  "F - test-convert-function-call-with-incorrect-output-register: error message")
 1547     # check that stop(1) was called
 1548     (check-ints-equal *(edx+4) 2 "F - test-convert-function-call-with-incorrect-output-register: exit status")
 1549     # don't restore from ebp
 1550     81 0/subop/add %esp 8/imm32
 1551     5d/pop-to-ebp
 1552     c3/return
 1553 
 1554 test-convert-function-with-local-var-dereferenced:
 1555     # . prologue
 1556     55/push-ebp
 1557     89/<- %ebp 4/r32/esp
 1558     # setup
 1559     (clear-stream _test-input-stream)
 1560     (clear-stream $_test-input-buffered-file->buffer)
 1561     (clear-stream _test-output-stream)
 1562     (clear-stream $_test-output-buffered-file->buffer)
 1563     #
 1564     (write _test-input-stream "fn foo {\n")
 1565     (write _test-input-stream "  var x/ecx: (addr int) <- copy 0\n")
 1566     (write _test-input-stream "  increment *x\n")
 1567     (write _test-input-stream "}\n")
 1568     # convert
 1569     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1570     (flush _test-output-buffered-file)
 1571 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1577     # check output
 1578     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-dereferenced/0")
 1579     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-dereferenced/1")
 1580     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-dereferenced/2")
 1581     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-dereferenced/3")
 1582     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-dereferenced/4")
 1583     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-dereferenced/5")
 1584     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-with-local-var-dereferenced/6")
 1585     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 0/imm32"  "F - test-convert-function-with-local-var-dereferenced/7")
 1586     (check-next-stream-line-equal _test-output-stream "    ff 0/subop/increment *ecx"  "F - test-convert-function-with-local-var-dereferenced/8")
 1587     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-with-local-var-dereferenced/9")
 1588     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-dereferenced/10")
 1589     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-dereferenced/11")
 1590     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-dereferenced/12")
 1591     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-dereferenced/13")
 1592     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-dereferenced/14")
 1593     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-dereferenced/15")
 1594     # . epilogue
 1595     89/<- %esp 5/r32/ebp
 1596     5d/pop-to-ebp
 1597     c3/return
 1598 
 1599 # variables of type 'byte' are not allowed on the stack
 1600 test-convert-function-with-byte-operations:
 1601     # . prologue
 1602     55/push-ebp
 1603     89/<- %ebp 4/r32/esp
 1604     # setup
 1605     (clear-stream _test-input-stream)
 1606     (clear-stream $_test-input-buffered-file->buffer)
 1607     (clear-stream _test-output-stream)
 1608     (clear-stream $_test-output-buffered-file->buffer)
 1609     #
 1610     (write _test-input-stream "fn foo {\n")
 1611     (write _test-input-stream "  var x/eax: byte <- copy 0\n")
 1612     (write _test-input-stream "  var y/ecx: byte <- copy 0\n")
 1613     (write _test-input-stream "  y <- copy-byte x\n")
 1614     (write _test-input-stream "  var z/edx: (addr byte) <- copy 0\n")
 1615     (write _test-input-stream "  y <- copy-byte *z\n")
 1616     (write _test-input-stream "  copy-byte-to *z, x\n")
 1617     (write _test-input-stream "}\n")
 1618     # convert
 1619     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1620     (flush _test-output-buffered-file)
 1621 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1627     # check output
 1628     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-function-with-byte-operations/0")
 1629     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-function-with-byte-operations/1")
 1630     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-function-with-byte-operations/2")
 1631     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-function-with-byte-operations/3")
 1632     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-function-with-byte-operations/4")
 1633     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-function-with-byte-operations/5")
 1634     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-function-with-byte-operations/6")
 1635     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-function-with-byte-operations/7")
 1636     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-function-with-byte-operations/8")
 1637     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 0/imm32"                  "F - test-convert-function-with-byte-operations/9")
 1638     (check-next-stream-line-equal _test-output-stream "    8a/byte-> %eax 0x00000001/r32"           "F - test-convert-function-with-byte-operations/10")
 1639     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %edx"                    "F - test-convert-function-with-byte-operations/11")
 1640     (check-next-stream-line-equal _test-output-stream "    ba/copy-to-edx 0/imm32"                  "F - test-convert-function-with-byte-operations/12")
 1641     (check-next-stream-line-equal _test-output-stream "    8a/byte-> *edx 0x00000001/r32"           "F - test-convert-function-with-byte-operations/13")
 1642     (check-next-stream-line-equal _test-output-stream "    88/byte<- *edx 0x00000000/r32"           "F - test-convert-function-with-byte-operations/14")
 1643     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %edx"                     "F - test-convert-function-with-byte-operations/15")
 1644     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-function-with-byte-operations/16")
 1645     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-function-with-byte-operations/17")
 1646     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-function-with-byte-operations/18")
 1647     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-function-with-byte-operations/19")
 1648     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-function-with-byte-operations/20")
 1649     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-function-with-byte-operations/21")
 1650     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-function-with-byte-operations/22")
 1651     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-function-with-byte-operations/23")
 1652     # . epilogue
 1653     89/<- %esp 5/r32/ebp
 1654     5d/pop-to-ebp
 1655     c3/return
 1656 
 1657 # variables of type 'byte' _can_ be function args. They then occupy 4 bytes.
 1658 test-copy-byte-var-from-fn-arg:
 1659     # . prologue
 1660     55/push-ebp
 1661     89/<- %ebp 4/r32/esp
 1662     # setup
 1663     (clear-stream _test-input-stream)
 1664     (clear-stream $_test-input-buffered-file->buffer)
 1665     (clear-stream _test-output-stream)
 1666     (clear-stream $_test-output-buffered-file->buffer)
 1667     #
 1668     (write _test-input-stream "fn foo x: byte, y: int {\n")
 1669     (write _test-input-stream "  var a/eax: byte <- copy x\n")
 1670     (write _test-input-stream "  var b/eax: int <- copy y\n")
 1671     (write _test-input-stream "}\n")
 1672     # convert
 1673     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1674     (flush _test-output-buffered-file)
 1675 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1681     # check output
 1682     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-copy-byte-from-fn-arg/0")
 1683     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-copy-byte-from-fn-arg/1")
 1684     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-copy-byte-from-fn-arg/2")
 1685     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-copy-byte-from-fn-arg/3")
 1686     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-copy-byte-from-fn-arg/4")
 1687     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-copy-byte-from-fn-arg/5")
 1688     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-copy-byte-from-fn-arg/6")
 1689     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-copy-byte-from-fn-arg/7")
 1690     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x0000000c) 0x00000000/r32"  "F - test-copy-byte-from-fn-arg/8")
 1691     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"   "F - test-copy-byte-from-fn-arg/9")
 1692     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-copy-byte-from-fn-arg/10")
 1693     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-copy-byte-from-fn-arg/11")
 1694     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-copy-byte-from-fn-arg/12")
 1695     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-copy-byte-from-fn-arg/13")
 1696     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-copy-byte-from-fn-arg/14")
 1697     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-copy-byte-from-fn-arg/15")
 1698     # . epilogue
 1699     89/<- %esp 5/r32/ebp
 1700     5d/pop-to-ebp
 1701     c3/return
 1702 
 1703 test-convert-compare-register-with-literal:
 1704     # . prologue
 1705     55/push-ebp
 1706     89/<- %ebp 4/r32/esp
 1707     # setup
 1708     (clear-stream _test-input-stream)
 1709     (clear-stream $_test-input-buffered-file->buffer)
 1710     (clear-stream _test-output-stream)
 1711     (clear-stream $_test-output-buffered-file->buffer)
 1712     #
 1713     (write _test-input-stream "fn foo {\n")
 1714     (write _test-input-stream "  var x/ecx: int <- copy 0\n")
 1715     (write _test-input-stream "  compare x, 0\n")
 1716     (write _test-input-stream "}\n")
 1717     # convert
 1718     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1719     (flush _test-output-buffered-file)
 1720 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1726     # check output
 1727     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-compare-register-with-literal/0")
 1728     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-compare-register-with-literal/1")
 1729     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-compare-register-with-literal/2")
 1730     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-compare-register-with-literal/3")
 1731     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-compare-register-with-literal/4")
 1732     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-compare-register-with-literal/5")
 1733     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-compare-register-with-literal/6")
 1734     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 0/imm32"  "F - test-convert-compare-register-with-literal/7")
 1735     (check-next-stream-line-equal _test-output-stream "    81 7/subop/compare %ecx 0/imm32"  "F - test-convert-compare-register-with-literal/8")
 1736     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9")
 1737     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-compare-register-with-literal/10")
 1738     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-compare-register-with-literal/11")
 1739     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-compare-register-with-literal/12")
 1740     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-compare-register-with-literal/13")
 1741     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-compare-register-with-literal/14")
 1742     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-compare-register-with-literal/15")
 1743     # . epilogue
 1744     89/<- %esp 5/r32/ebp
 1745     5d/pop-to-ebp
 1746     c3/return
 1747 
 1748 test-unknown-variable:
 1749     # . prologue
 1750     55/push-ebp
 1751     89/<- %ebp 4/r32/esp
 1752     # setup
 1753     (clear-stream _test-input-stream)
 1754     (clear-stream $_test-input-buffered-file->buffer)
 1755     (clear-stream _test-output-stream)
 1756     (clear-stream $_test-output-buffered-file->buffer)
 1757     (clear-stream _test-error-stream)
 1758     (clear-stream $_test-error-buffered-file->buffer)
 1759     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1760     68/push 0/imm32
 1761     68/push 0/imm32
 1762     89/<- %edx 4/r32/esp
 1763     (tailor-exit-descriptor %edx 0x10)
 1764     #
 1765     (write _test-input-stream "fn foo {\n")
 1766     (write _test-input-stream "  compare x, 0\n")
 1767     (write _test-input-stream "}\n")
 1768     # convert
 1769     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1770     # registers except esp clobbered at this point
 1771     # restore ed
 1772     89/<- %edx 4/r32/esp
 1773     (flush _test-output-buffered-file)
 1774     (flush _test-error-buffered-file)
 1775 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1781     # check output
 1782     (check-stream-equal _test-output-stream  ""  "F - test-unknown-variable: output should be empty")
 1783     (check-next-stream-line-equal _test-error-stream  "fn foo: unknown variable 'x'"  "F - test-unknown-variable: error message")
 1784     # check that stop(1) was called
 1785     (check-ints-equal *(edx+4) 2 "F - test-unknown-variable: exit status")
 1786     # don't restore from ebp
 1787     81 0/subop/add %esp 8/imm32
 1788     # . epilogue
 1789     5d/pop-to-ebp
 1790     c3/return
 1791 
 1792 test-convert-function-with-local-var-in-block:
 1793     # . prologue
 1794     55/push-ebp
 1795     89/<- %ebp 4/r32/esp
 1796     # setup
 1797     (clear-stream _test-input-stream)
 1798     (clear-stream $_test-input-buffered-file->buffer)
 1799     (clear-stream _test-output-stream)
 1800     (clear-stream $_test-output-buffered-file->buffer)
 1801     #
 1802     (write _test-input-stream "fn foo {\n")
 1803     (write _test-input-stream "  {\n")
 1804     (write _test-input-stream "    var x: int\n")
 1805     (write _test-input-stream "    increment x\n")
 1806     (write _test-input-stream "  }\n")
 1807     (write _test-input-stream "}\n")
 1808     # convert
 1809     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1810     (flush _test-output-buffered-file)
 1811 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1817     # check output
 1818     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-in-block/0")
 1819     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-in-block/1")
 1820     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-in-block/2")
 1821     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-in-block/3")
 1822     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-in-block/4")
 1823     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-in-block/5")
 1824     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-local-var-in-block/6")
 1825     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-local-var-in-block/7")
 1826     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-local-var-in-block/8")
 1827     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-local-var-in-block/9")
 1828     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-local-var-in-block/10")
 1829     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-local-var-in-block/11")
 1830     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-local-var-in-block/12")
 1831     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-in-block/13")
 1832     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-in-block/14")
 1833     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-in-block/15")
 1834     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-in-block/16")
 1835     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-in-block/17")
 1836     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-in-block/18")
 1837     # . epilogue
 1838     89/<- %esp 5/r32/ebp
 1839     5d/pop-to-ebp
 1840     c3/return
 1841 
 1842 test-convert-function-with-local-var-in-named-block:
 1843     # . prologue
 1844     55/push-ebp
 1845     89/<- %ebp 4/r32/esp
 1846     # setup
 1847     (clear-stream _test-input-stream)
 1848     (clear-stream $_test-input-buffered-file->buffer)
 1849     (clear-stream _test-output-stream)
 1850     (clear-stream $_test-output-buffered-file->buffer)
 1851     #
 1852     (write _test-input-stream "fn foo {\n")
 1853     (write _test-input-stream "  $bar: {\n")
 1854     (write _test-input-stream "    var x: int\n")
 1855     (write _test-input-stream "    increment x\n")
 1856     (write _test-input-stream "  }\n")
 1857     (write _test-input-stream "}\n")
 1858     # convert
 1859     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1860     (flush _test-output-buffered-file)
 1861 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1867     # check output
 1868     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-in-named-block/0")
 1869     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-in-named-block/1")
 1870     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-in-named-block/2")
 1871     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-in-named-block/3")
 1872     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-in-named-block/4")
 1873     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-in-named-block/5")
 1874     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-local-var-in-named-block/6")
 1875     (check-next-stream-line-equal _test-output-stream "$bar:loop:"              "F - test-convert-function-with-local-var-in-named-block/7")
 1876     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-local-var-in-named-block/8")
 1877     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-local-var-in-named-block/9")
 1878     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-local-var-in-named-block/10")
 1879     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-local-var-in-named-block/11")
 1880     (check-next-stream-line-equal _test-output-stream "$bar:break:"             "F - test-convert-function-with-local-var-in-named-block/12")
 1881     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-in-named-block/13")
 1882     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-in-named-block/14")
 1883     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-in-named-block/15")
 1884     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-in-named-block/16")
 1885     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-in-named-block/17")
 1886     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-in-named-block/18")
 1887     # . epilogue
 1888     89/<- %esp 5/r32/ebp
 1889     5d/pop-to-ebp
 1890     c3/return
 1891 
 1892 test-unknown-variable-in-named-block:
 1893     # . prologue
 1894     55/push-ebp
 1895     89/<- %ebp 4/r32/esp
 1896     # setup
 1897     (clear-stream _test-input-stream)
 1898     (clear-stream $_test-input-buffered-file->buffer)
 1899     (clear-stream _test-output-stream)
 1900     (clear-stream $_test-output-buffered-file->buffer)
 1901     (clear-stream _test-error-stream)
 1902     (clear-stream $_test-error-buffered-file->buffer)
 1903     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 1904     68/push 0/imm32
 1905     68/push 0/imm32
 1906     89/<- %edx 4/r32/esp
 1907     (tailor-exit-descriptor %edx 0x10)
 1908     #
 1909     (write _test-input-stream "fn foo {\n")
 1910     (write _test-input-stream "  $a: {\n")
 1911     (write _test-input-stream "    compare x, 0\n")
 1912     (write _test-input-stream "  }\n")
 1913     (write _test-input-stream "}\n")
 1914     # convert
 1915     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 1916     # registers except esp clobbered at this point
 1917     # restore ed
 1918     89/<- %edx 4/r32/esp
 1919     (flush _test-output-buffered-file)
 1920     (flush _test-error-buffered-file)
 1921 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 1927     # check output
 1928     (check-stream-equal _test-output-stream  ""  "F - test-unknown-variable-in-named-block: output should be empty")
 1929     (check-next-stream-line-equal _test-error-stream  "fn foo: unknown variable 'x'"  "F - test-unknown-variable-in-named-block: error message")
 1930     # check that stop(1) was called
 1931     (check-ints-equal *(edx+4) 2 "F - test-unknown-variable-in-named-block: exit status")
 1932     # don't restore from ebp
 1933     81 0/subop/add %esp 8/imm32
 1934     # . epilogue
 1935     5d/pop-to-ebp
 1936     c3/return
 1937 
 1938 test-always-shadow-outermost-reg-vars-in-function:
 1939     # . prologue
 1940     55/push-ebp
 1941     89/<- %ebp 4/r32/esp
 1942     # setup
 1943     (clear-stream _test-input-stream)
 1944     (clear-stream $_test-input-buffered-file->buffer)
 1945     (clear-stream _test-output-stream)
 1946     (clear-stream $_test-output-buffered-file->buffer)
 1947     #
 1948     (write _test-input-stream "fn foo {\n")
 1949     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 1950     (write _test-input-stream "}\n")
 1951     # convert
 1952     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1953     (flush _test-output-buffered-file)
 1954 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 1960     # check output
 1961     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-always-shadow-outermost-reg-vars-in-function/0")
 1962     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-always-shadow-outermost-reg-vars-in-function/1")
 1963     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-always-shadow-outermost-reg-vars-in-function/2")
 1964     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-always-shadow-outermost-reg-vars-in-function/3")
 1965     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-always-shadow-outermost-reg-vars-in-function/4")
 1966     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-always-shadow-outermost-reg-vars-in-function/5")
 1967     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-compare-register-with-literal/6")
 1968     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-always-shadow-outermost-reg-vars-in-function/8")
 1969     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-compare-register-with-literal/9")
 1970     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-always-shadow-outermost-reg-vars-in-function/12")
 1971     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-always-shadow-outermost-reg-vars-in-function/13")
 1972     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-always-shadow-outermost-reg-vars-in-function/14")
 1973     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-always-shadow-outermost-reg-vars-in-function/15")
 1974     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-always-shadow-outermost-reg-vars-in-function/16")
 1975     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-always-shadow-outermost-reg-vars-in-function/17")
 1976     # . epilogue
 1977     89/<- %esp 5/r32/ebp
 1978     5d/pop-to-ebp
 1979     c3/return
 1980 
 1981 _pending-test-clobber-dead-local:
 1982     # . prologue
 1983     55/push-ebp
 1984     89/<- %ebp 4/r32/esp
 1985     # setup
 1986     (clear-stream _test-input-stream)
 1987     (clear-stream $_test-input-buffered-file->buffer)
 1988     (clear-stream _test-output-stream)
 1989     (clear-stream $_test-output-buffered-file->buffer)
 1990     #
 1991     (write _test-input-stream "fn foo {\n")
 1992     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 1993     (write _test-input-stream "  {\n")
 1994     (write _test-input-stream "    var y/ecx: int <- copy 4\n")
 1995     (write _test-input-stream "  }\n")
 1996     (write _test-input-stream "}\n")
 1997     # convert
 1998     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 1999     (flush _test-output-buffered-file)
 2000 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2006     # check output
 2007     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-clobber-dead-local/0")
 2008     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-clobber-dead-local/1")
 2009     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-clobber-dead-local/2")
 2010     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-clobber-dead-local/3")
 2011     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-clobber-dead-local/4")
 2012     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-clobber-dead-local/5")
 2013     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-clobber-dead-local/6")
 2014     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-clobber-dead-local/7")
 2015     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-clobber-dead-local/8")
 2016     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-clobber-dead-local/9")
 2017     (check-next-stream-line-equal _test-output-stream "      b9/copy-to-ecx 4/imm32"  "F - test-clobber-dead-local/10")  # no push/pop here
 2018     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-clobber-dead-local/11")
 2019     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-clobber-dead-local/12")
 2020     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-clobber-dead-local/13")
 2021     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-clobber-dead-local/14")
 2022     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-clobber-dead-local/15")
 2023     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-clobber-dead-local/16")
 2024     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-clobber-dead-local/17")
 2025     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-clobber-dead-local/18")
 2026     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-clobber-dead-local/19")
 2027     # . epilogue
 2028     89/<- %esp 5/r32/ebp
 2029     5d/pop-to-ebp
 2030     c3/return
 2031 
 2032 test-shadow-live-local:
 2033     # . prologue
 2034     55/push-ebp
 2035     89/<- %ebp 4/r32/esp
 2036     # setup
 2037     (clear-stream _test-input-stream)
 2038     (clear-stream $_test-input-buffered-file->buffer)
 2039     (clear-stream _test-output-stream)
 2040     (clear-stream $_test-output-buffered-file->buffer)
 2041     #
 2042     (write _test-input-stream "fn foo {\n")
 2043     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 2044     (write _test-input-stream "  {\n")
 2045     (write _test-input-stream "    var y/ecx: int <- copy 4\n")
 2046     (write _test-input-stream "  }\n")
 2047     (write _test-input-stream "  x <- increment\n")
 2048     (write _test-input-stream "}\n")
 2049     # convert
 2050     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2051     (flush _test-output-buffered-file)
 2052 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2058     # check output
 2059     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-shadow-live-local/0")
 2060     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-shadow-live-local/1")
 2061     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-shadow-live-local/2")
 2062     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-shadow-live-local/3")
 2063     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-shadow-live-local/4")
 2064     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-shadow-live-local/5")
 2065     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-shadow-live-local/6")
 2066     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-shadow-live-local/7")
 2067     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-shadow-live-local/8")
 2068     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-shadow-live-local/9")
 2069     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %ecx"  "F - test-shadow-live-local/10")
 2070     (check-next-stream-line-equal _test-output-stream "      b9/copy-to-ecx 4/imm32"  "F - test-shadow-live-local/11")
 2071     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %ecx" "F - test-shadow-live-local/12")
 2072     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-shadow-live-local/13")
 2073     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-shadow-live-local/14")
 2074     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-shadow-live-local/15")
 2075     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-shadow-live-local/16")
 2076     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-shadow-live-local/17")
 2077     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-shadow-live-local/18")
 2078     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-shadow-live-local/19")
 2079     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-shadow-live-local/20")
 2080     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-shadow-live-local/21")
 2081     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-shadow-live-local/22")
 2082     # . epilogue
 2083     89/<- %esp 5/r32/ebp
 2084     5d/pop-to-ebp
 2085     c3/return
 2086 
 2087 test-shadow-name:
 2088     # . prologue
 2089     55/push-ebp
 2090     89/<- %ebp 4/r32/esp
 2091     # setup
 2092     (clear-stream _test-input-stream)
 2093     (clear-stream $_test-input-buffered-file->buffer)
 2094     (clear-stream _test-output-stream)
 2095     (clear-stream $_test-output-buffered-file->buffer)
 2096     #
 2097     (write _test-input-stream "fn foo {\n")
 2098     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 2099     (write _test-input-stream "  {\n")
 2100     (write _test-input-stream "    var x/edx: int <- copy 4\n")
 2101     (write _test-input-stream "  }\n")
 2102     (write _test-input-stream "  x <- increment\n")
 2103     (write _test-input-stream "}\n")
 2104     # convert
 2105     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2106     (flush _test-output-buffered-file)
 2107 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2113     # check output
 2114     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-shadow-name/0")
 2115     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-shadow-name/1")
 2116     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-shadow-name/2")
 2117     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-shadow-name/3")
 2118     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-shadow-name/4")
 2119     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-shadow-name/5")
 2120     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-shadow-name/6")
 2121     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-shadow-name/7")
 2122     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-shadow-name/8")
 2123     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-shadow-name/9")
 2124     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %edx"  "F - test-shadow-name/10")
 2125     (check-next-stream-line-equal _test-output-stream "      ba/copy-to-edx 4/imm32"  "F - test-shadow-name/11")
 2126     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %edx" "F - test-shadow-name/12")
 2127     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-shadow-name/13")
 2128     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-shadow-name/14")
 2129     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-shadow-name/15")
 2130     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-shadow-name/16")
 2131     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-shadow-name/17")
 2132     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-shadow-name/18")
 2133     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-shadow-name/19")
 2134     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-shadow-name/20")
 2135     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-shadow-name/21")
 2136     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-shadow-name/22")
 2137     # . epilogue
 2138     89/<- %esp 5/r32/ebp
 2139     5d/pop-to-ebp
 2140     c3/return
 2141 
 2142 test-shadow-name-2:
 2143     # . prologue
 2144     55/push-ebp
 2145     89/<- %ebp 4/r32/esp
 2146     # setup
 2147     (clear-stream _test-input-stream)
 2148     (clear-stream $_test-input-buffered-file->buffer)
 2149     (clear-stream _test-output-stream)
 2150     (clear-stream $_test-output-buffered-file->buffer)
 2151     #
 2152     (write _test-input-stream "fn foo {\n")
 2153     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 2154     (write _test-input-stream "  {\n")
 2155     (write _test-input-stream "    var x/edx: int <- copy 4\n")
 2156     (write _test-input-stream "    var y/ecx: int <- copy 5\n")
 2157     (write _test-input-stream "  }\n")
 2158     (write _test-input-stream "  x <- increment\n")
 2159     (write _test-input-stream "}\n")
 2160     # convert
 2161     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2162     (flush _test-output-buffered-file)
 2163 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2169     # check output
 2170     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-shadow-name-2/0")
 2171     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-shadow-name-2/1")
 2172     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-shadow-name-2/2")
 2173     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-shadow-name-2/3")
 2174     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-shadow-name-2/4")
 2175     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-shadow-name-2/5")
 2176     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-shadow-name-2/6")
 2177     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-shadow-name-2/7")
 2178     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-shadow-name-2/8")
 2179     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-shadow-name-2/9")
 2180     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %edx"  "F - test-shadow-name-2/10")
 2181     (check-next-stream-line-equal _test-output-stream "      ba/copy-to-edx 4/imm32"  "F - test-shadow-name-2/11")
 2182     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %ecx"  "F - test-shadow-name-2/12")
 2183     (check-next-stream-line-equal _test-output-stream "      b9/copy-to-ecx 5/imm32"  "F - test-shadow-name-2/13")
 2184     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %ecx" "F - test-shadow-name-2/14")
 2185     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %edx" "F - test-shadow-name-2/15")
 2186     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-shadow-name-2/16")
 2187     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-shadow-name-2/17")
 2188     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-shadow-name-2/18")
 2189     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-shadow-name-2/19")
 2190     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-shadow-name-2/20")
 2191     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-shadow-name-2/21")
 2192     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-shadow-name-2/22")
 2193     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-shadow-name-2/23")
 2194     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-shadow-name-2/24")
 2195     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-shadow-name-2/25")
 2196     # . epilogue
 2197     89/<- %esp 5/r32/ebp
 2198     5d/pop-to-ebp
 2199     c3/return
 2200 
 2201 test-do-not-spill-same-register-in-block:
 2202     # . prologue
 2203     55/push-ebp
 2204     89/<- %ebp 4/r32/esp
 2205     # setup
 2206     (clear-stream _test-input-stream)
 2207     (clear-stream $_test-input-buffered-file->buffer)
 2208     (clear-stream _test-output-stream)
 2209     (clear-stream $_test-output-buffered-file->buffer)
 2210     #
 2211     (write _test-input-stream "fn foo {\n")
 2212     (write _test-input-stream "  var x/ecx: int <- copy 3\n")
 2213     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 2214     (write _test-input-stream "  y <- increment\n")
 2215     (write _test-input-stream "}\n")
 2216     # convert
 2217     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2218     (flush _test-output-buffered-file)
 2219 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2225     # check output
 2226     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-do-not-spill-same-register-in-block/0")
 2227     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-do-not-spill-same-register-in-block/1")
 2228     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-do-not-spill-same-register-in-block/2")
 2229     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-do-not-spill-same-register-in-block/3")
 2230     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-do-not-spill-same-register-in-block/4")
 2231     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-do-not-spill-same-register-in-block/5")
 2232     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-do-not-spill-same-register-in-block/6")
 2233     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-do-not-spill-same-register-in-block/7")
 2234     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 4/imm32"  "F - test-do-not-spill-same-register-in-block/8")
 2235     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-do-not-spill-same-register-in-block/9")
 2236     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-do-not-spill-same-register-in-block/10")
 2237     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-do-not-spill-same-register-in-block/11")
 2238     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-do-not-spill-same-register-in-block/12")
 2239     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-do-not-spill-same-register-in-block/13")
 2240     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-do-not-spill-same-register-in-block/14")
 2241     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-do-not-spill-same-register-in-block/15")
 2242     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-do-not-spill-same-register-in-block/16")
 2243     # . epilogue
 2244     89/<- %esp 5/r32/ebp
 2245     5d/pop-to-ebp
 2246     c3/return
 2247 
 2248 test-spill-different-register-in-block:
 2249     # . prologue
 2250     55/push-ebp
 2251     89/<- %ebp 4/r32/esp
 2252     # setup
 2253     (clear-stream _test-input-stream)
 2254     (clear-stream $_test-input-buffered-file->buffer)
 2255     (clear-stream _test-output-stream)
 2256     (clear-stream $_test-output-buffered-file->buffer)
 2257     #
 2258     (write _test-input-stream "fn foo {\n")
 2259     (write _test-input-stream "  var x/eax: int <- copy 3\n")
 2260     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 2261     (write _test-input-stream "  y <- increment\n")
 2262     (write _test-input-stream "}\n")
 2263     # convert
 2264     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2265     (flush _test-output-buffered-file)
 2266 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2272     # check output
 2273     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-spill-different-register-in-block/0")
 2274     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-spill-different-register-in-block/1")
 2275     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-spill-different-register-in-block/2")
 2276     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-spill-different-register-in-block/3")
 2277     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-spill-different-register-in-block/4")
 2278     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-spill-different-register-in-block/5")
 2279     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-spill-different-register-in-block/6")
 2280     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 3/imm32"  "F - test-spill-different-register-in-block/7")
 2281     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-spill-different-register-in-block/8")
 2282     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 4/imm32"  "F - test-spill-different-register-in-block/9")
 2283     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-spill-different-register-in-block/10")
 2284     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-spill-different-register-in-block/11")
 2285     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-spill-different-register-in-block/12")
 2286     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-spill-different-register-in-block/13")
 2287     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-spill-different-register-in-block/14")
 2288     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-spill-different-register-in-block/15")
 2289     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-spill-different-register-in-block/16")
 2290     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-spill-different-register-in-block/17")
 2291     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-spill-different-register-in-block/18")
 2292     # . epilogue
 2293     89/<- %esp 5/r32/ebp
 2294     5d/pop-to-ebp
 2295     c3/return
 2296 
 2297 test-shadow-live-output:
 2298     # . prologue
 2299     55/push-ebp
 2300     89/<- %ebp 4/r32/esp
 2301     # setup
 2302     (clear-stream _test-input-stream)
 2303     (clear-stream $_test-input-buffered-file->buffer)
 2304     (clear-stream _test-output-stream)
 2305     (clear-stream $_test-output-buffered-file->buffer)
 2306     #
 2307     (write _test-input-stream "fn foo -> x/ecx: int {\n")
 2308     (write _test-input-stream "  x <- copy 3\n")
 2309     (write _test-input-stream "  {\n")
 2310     (write _test-input-stream "    var y/ecx: int <- copy 4\n")
 2311     (write _test-input-stream "  }\n")
 2312     (write _test-input-stream "  x <- increment\n")
 2313     (write _test-input-stream "}\n")
 2314     # convert
 2315     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2316     (flush _test-output-buffered-file)
 2317 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2323     # check output
 2324     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-shadow-live-output/0")
 2325     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-shadow-live-output/1")
 2326     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-shadow-live-output/2")
 2327     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-shadow-live-output/3")
 2328     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-shadow-live-output/4")
 2329     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-shadow-live-output/5")
 2330     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"  "F - test-shadow-live-output/7")  # no push because it's an output reg
 2331     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-shadow-live-output/8")
 2332     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-shadow-live-output/9")
 2333     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %ecx"  "F - test-shadow-live-output/10")
 2334     (check-next-stream-line-equal _test-output-stream "      b9/copy-to-ecx 4/imm32"  "F - test-shadow-live-output/11")
 2335     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %ecx" "F - test-shadow-live-output/12")
 2336     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-shadow-live-output/13")
 2337     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-shadow-live-output/14")
 2338     (check-next-stream-line-equal _test-output-stream "    41/increment-ecx"    "F - test-shadow-live-output/15")
 2339     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-shadow-live-output/17")
 2340     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-shadow-live-output/18")
 2341     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-shadow-live-output/19")
 2342     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-shadow-live-output/20")
 2343     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-shadow-live-output/21")
 2344     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-shadow-live-output/21")
 2345     # . epilogue
 2346     89/<- %esp 5/r32/ebp
 2347     5d/pop-to-ebp
 2348     c3/return
 2349 
 2350 test-stmt-defines-output-in-same-register-as-inout:
 2351     # . prologue
 2352     55/push-ebp
 2353     89/<- %ebp 4/r32/esp
 2354     # setup
 2355     (clear-stream _test-input-stream)
 2356     (clear-stream $_test-input-buffered-file->buffer)
 2357     (clear-stream _test-output-stream)
 2358     (clear-stream $_test-output-buffered-file->buffer)
 2359     (clear-stream _test-error-stream)
 2360     (clear-stream $_test-error-buffered-file->buffer)
 2361     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 2362     68/push 0/imm32
 2363     68/push 0/imm32
 2364     89/<- %edx 4/r32/esp
 2365     (tailor-exit-descriptor %edx 0x10)
 2366     #
 2367     (write _test-input-stream "fn foo -> x/ecx: int {\n")
 2368     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 2369     (write _test-input-stream "  x <- copy y\n")  # writing to a fn output is currently the only way for a statement to define a new var
 2370     (write _test-input-stream "}\n")
 2371     # convert
 2372     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 2373     # registers except esp clobbered at this point
 2374     # restore ed
 2375     89/<- %edx 4/r32/esp
 2376     (flush _test-output-buffered-file)
 2377     (flush _test-error-buffered-file)
 2378 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2384     # no error; we looked up 'y' correctly before pushing the binding for 'x'
 2385     (check-stream-equal _test-error-stream  ""  "F - test-stmt-defines-output-in-same-register-as-inout: error stream should be empty")
 2386     # don't bother checking the generated code; that's in the test 'test-local-clobbered-by-fn-output' below
 2387     # don't restore from ebp
 2388     81 0/subop/add %esp 8/imm32
 2389     # . epilogue
 2390     5d/pop-to-ebp
 2391     c3/return
 2392 
 2393 test-local-clobbered-by-fn-output:
 2394     # . prologue
 2395     55/push-ebp
 2396     89/<- %ebp 4/r32/esp
 2397     # setup
 2398     (clear-stream _test-input-stream)
 2399     (clear-stream $_test-input-buffered-file->buffer)
 2400     (clear-stream _test-output-stream)
 2401     (clear-stream $_test-output-buffered-file->buffer)
 2402     #
 2403     (write _test-input-stream "fn foo -> x/ecx: int {\n")
 2404     (write _test-input-stream "  var y/ecx: int <- copy 4\n")
 2405     (write _test-input-stream "  x <- copy y\n")
 2406     (write _test-input-stream "}\n")
 2407     # convert
 2408     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2409     (flush _test-output-buffered-file)
 2410 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2416     # check output
 2417     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-local-clobbered-by-fn-output/0")
 2418     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-local-clobbered-by-fn-output/1")
 2419     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-local-clobbered-by-fn-output/2")
 2420     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-local-clobbered-by-fn-output/3")
 2421     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-local-clobbered-by-fn-output/4")
 2422     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-local-clobbered-by-fn-output/5")
 2423     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 4/imm32"  "F - test-local-clobbered-by-fn-output/6")  # no push because it's an output reg
 2424     (check-next-stream-line-equal _test-output-stream "    89/<- %ecx 0x00000001/r32"  "F - test-local-clobbered-by-fn-output/7")
 2425     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-local-clobbered-by-fn-output/8")
 2426     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-local-clobbered-by-fn-output/9")
 2427     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-local-clobbered-by-fn-output/10")
 2428     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-local-clobbered-by-fn-output/11")
 2429     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-local-clobbered-by-fn-output/12")
 2430     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-local-clobbered-by-fn-output/13")
 2431     # . epilogue
 2432     89/<- %esp 5/r32/ebp
 2433     5d/pop-to-ebp
 2434     c3/return
 2435 
 2436 test-read-output:
 2437     # . prologue
 2438     55/push-ebp
 2439     89/<- %ebp 4/r32/esp
 2440     # setup
 2441     (clear-stream _test-input-stream)
 2442     (clear-stream $_test-input-buffered-file->buffer)
 2443     (clear-stream _test-output-stream)
 2444     (clear-stream $_test-output-buffered-file->buffer)
 2445     #
 2446     (write _test-input-stream "fn foo -> x/ecx: int {\n")
 2447     (write _test-input-stream "  x <- copy 0x34\n")
 2448     (write _test-input-stream "  compare x, 0x35\n")
 2449     (write _test-input-stream "}\n")
 2450     # convert
 2451     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2452     (flush _test-output-buffered-file)
 2453 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2459     # check output
 2460     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-read-output/0")
 2461     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-read-output/1")
 2462     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-read-output/2")
 2463     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-read-output/3")
 2464     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-read-output/4")
 2465     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-read-output/5")
 2466     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 0x34/imm32"  "F - test-read-output/6")
 2467     (check-next-stream-line-equal _test-output-stream "    81 7/subop/compare %ecx 0x35/imm32"  "F - test-read-output/7")
 2468     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-read-output/8")
 2469     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-read-output/9")
 2470     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-read-output/10")
 2471     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-read-output/11")
 2472     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-read-output/12")
 2473     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-read-output/13")
 2474     # . epilogue
 2475     89/<- %esp 5/r32/ebp
 2476     5d/pop-to-ebp
 2477     c3/return
 2478 
 2479 test-fn-output-written-in-inner-block:
 2480     # . prologue
 2481     55/push-ebp
 2482     89/<- %ebp 4/r32/esp
 2483     # setup
 2484     (clear-stream _test-input-stream)
 2485     (clear-stream $_test-input-buffered-file->buffer)
 2486     (clear-stream _test-output-stream)
 2487     (clear-stream $_test-output-buffered-file->buffer)
 2488     #
 2489     (write _test-input-stream "fn foo -> out/edi: int {\n")
 2490     (write _test-input-stream "  var a/eax: int <- copy 3\n")  # define outer local
 2491     (write _test-input-stream "  {\n")
 2492     (write _test-input-stream "    var a/ecx: int <- copy 4\n")  # shadow outer local
 2493     (write _test-input-stream "    out <- copy a\n")  # write to fn output
 2494     (write _test-input-stream "  }\n")
 2495     (write _test-input-stream "  compare a, 0\n")  # use outer local
 2496     (write _test-input-stream "}\n")
 2497     # convert
 2498     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2499     (flush _test-output-buffered-file)
 2500 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2506     # no error; defining 'out' didn't interfere with the reclamation of 'b'
 2507     # check output
 2508     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-fn-output-written-in-inner-block/0")
 2509     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-fn-output-written-in-inner-block/1")
 2510     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-fn-output-written-in-inner-block/2")
 2511     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-fn-output-written-in-inner-block/3")
 2512     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-fn-output-written-in-inner-block/4")
 2513     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-fn-output-written-in-inner-block/5")
 2514     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-fn-output-written-in-inner-block/6")
 2515     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 3/imm32"  "F - test-fn-output-written-in-inner-block/7")
 2516     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-fn-output-written-in-inner-block/8")
 2517     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-fn-output-written-in-inner-block/9")
 2518     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %ecx"  "F - test-fn-output-written-in-inner-block/10")
 2519     (check-next-stream-line-equal _test-output-stream "      b9/copy-to-ecx 4/imm32"  "F - test-fn-output-written-in-inner-block/10")
 2520     (check-next-stream-line-equal _test-output-stream "      89/<- %edi 0x00000001/r32"  "F - test-fn-output-written-in-inner-block/11")
 2521     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %ecx"  "F - test-fn-output-written-in-inner-block/12")
 2522     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-fn-output-written-in-inner-block/13")
 2523     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-fn-output-written-in-inner-block/14")
 2524     (check-next-stream-line-equal _test-output-stream "    3d/compare-eax-with 0/imm32"  "F - test-fn-output-written-in-inner-block/15")
 2525     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-fn-output-written-in-inner-block/16")
 2526     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-fn-output-written-in-inner-block/17")
 2527     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-fn-output-written-in-inner-block/18")
 2528     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-fn-output-written-in-inner-block/19")
 2529     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-fn-output-written-in-inner-block/20")
 2530     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-fn-output-written-in-inner-block/21")
 2531     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-fn-output-written-in-inner-block/22")
 2532     # . epilogue
 2533     89/<- %esp 5/r32/ebp
 2534     5d/pop-to-ebp
 2535     c3/return
 2536 
 2537 test-convert-function-with-branches-in-block:
 2538     # . prologue
 2539     55/push-ebp
 2540     89/<- %ebp 4/r32/esp
 2541     # setup
 2542     (clear-stream _test-input-stream)
 2543     (clear-stream $_test-input-buffered-file->buffer)
 2544     (clear-stream _test-output-stream)
 2545     (clear-stream $_test-output-buffered-file->buffer)
 2546     #
 2547     (write _test-input-stream "fn foo x: int {\n")
 2548     (write _test-input-stream "  {\n")
 2549     (write _test-input-stream "    break-if->=\n")
 2550     (write _test-input-stream "    loop-if-addr<\n")
 2551     (write _test-input-stream "    increment x\n")
 2552     (write _test-input-stream "    loop\n")
 2553     (write _test-input-stream "  }\n")
 2554     (write _test-input-stream "}\n")
 2555     # convert
 2556     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2557     (flush _test-output-buffered-file)
 2558 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2564     # check output
 2565     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-branches-in-block/0")
 2566     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-branches-in-block/1")
 2567     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-branches-in-block/2")
 2568     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-branches-in-block/3")
 2569     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-branches-in-block/4")
 2570     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-branches-in-block/5")
 2571     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-branches-in-block/6")
 2572     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-branches-in-block/7")
 2573     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-in-block/8")
 2574     (check-next-stream-line-equal _test-output-stream "        0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-branches-in-block/9")
 2575     (check-next-stream-line-equal _test-output-stream "        e9/jump $foo:0x00000002:break/disp32"  "F - test-convert-function-with-branches-in-block/10")
 2576     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-in-block/11")
 2577     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-in-block/12")
 2578     (check-next-stream-line-equal _test-output-stream "        0f 83/jump-if-addr>= break/disp32"  "F - test-convert-function-with-branches-in-block/13")
 2579     (check-next-stream-line-equal _test-output-stream "        e9/jump $foo:0x00000002:loop/disp32"  "F - test-convert-function-with-branches-in-block/14")
 2580     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-in-block/15")
 2581     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0x00000008)"  "F - test-convert-function-with-branches-in-block/16")
 2582     (check-next-stream-line-equal _test-output-stream "      e9/jump loop/disp32"  "F - test-convert-function-with-branches-in-block/17")
 2583     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-branches-in-block/18")
 2584     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-branches-in-block/19")
 2585     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-branches-in-block/20")
 2586     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-branches-in-block/21")
 2587     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-branches-in-block/22")
 2588     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-branches-in-block/23")
 2589     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-branches-in-block/24")
 2590     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-branches-in-block/25")
 2591     # . epilogue
 2592     89/<- %esp 5/r32/ebp
 2593     5d/pop-to-ebp
 2594     c3/return
 2595 
 2596 test-convert-function-with-branches-in-named-block:
 2597     # . prologue
 2598     55/push-ebp
 2599     89/<- %ebp 4/r32/esp
 2600     # setup
 2601     (clear-stream _test-input-stream)
 2602     (clear-stream $_test-input-buffered-file->buffer)
 2603     (clear-stream _test-output-stream)
 2604     (clear-stream $_test-output-buffered-file->buffer)
 2605     #
 2606     (write _test-input-stream "fn foo x: int {\n")
 2607     (write _test-input-stream "  $bar: {\n")
 2608     (write _test-input-stream "    break-if->= $bar\n")
 2609     (write _test-input-stream "    loop-if-addr< $bar\n")
 2610     (write _test-input-stream "    increment x\n")
 2611     (write _test-input-stream "    loop\n")
 2612     (write _test-input-stream "  }\n")
 2613     (write _test-input-stream "}\n")
 2614     # convert
 2615     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2616     (flush _test-output-buffered-file)
 2617 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2623     # check output
 2624     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-branches-in-named-block/0")
 2625     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-branches-in-named-block/1")
 2626     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-branches-in-named-block/2")
 2627     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-branches-in-named-block/3")
 2628     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-branches-in-named-block/4")
 2629     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-branches-in-named-block/5")
 2630     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-branches-in-named-block/6")
 2631     (check-next-stream-line-equal _test-output-stream "$bar:loop:"              "F - test-convert-function-with-branches-in-named-block/7")
 2632     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-in-named-block/8")
 2633     (check-next-stream-line-equal _test-output-stream "        0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-branches-in-named-block/9")
 2634     (check-next-stream-line-equal _test-output-stream "        e9/jump $bar:break/disp32"  "F - test-convert-function-with-branches-in-named-block/10")
 2635     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-in-named-block/11")
 2636     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-in-named-block/12")
 2637     (check-next-stream-line-equal _test-output-stream "        0f 83/jump-if-addr>= break/disp32"  "F - test-convert-function-with-branches-in-named-block/13")
 2638     (check-next-stream-line-equal _test-output-stream "        e9/jump $bar:loop/disp32"  "F - test-convert-function-with-branches-in-named-block/14")
 2639     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-in-named-block/15")
 2640     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0x00000008)"  "F - test-convert-function-with-branches-in-named-block/16")
 2641     (check-next-stream-line-equal _test-output-stream "      e9/jump loop/disp32"   "F - test-convert-function-with-branches-in-named-block/17")
 2642     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-branches-in-named-block/18")
 2643     (check-next-stream-line-equal _test-output-stream "$bar:break:"             "F - test-convert-function-with-branches-in-named-block/19")
 2644     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-branches-in-named-block/20")
 2645     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-branches-in-named-block/21")
 2646     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-branches-in-named-block/22")
 2647     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-branches-in-named-block/23")
 2648     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-branches-in-named-block/24")
 2649     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-branches-in-named-block/25")
 2650     # . epilogue
 2651     89/<- %esp 5/r32/ebp
 2652     5d/pop-to-ebp
 2653     c3/return
 2654 
 2655 test-convert-function-with-var-in-nested-block:
 2656     # . prologue
 2657     55/push-ebp
 2658     89/<- %ebp 4/r32/esp
 2659     # setup
 2660     (clear-stream _test-input-stream)
 2661     (clear-stream $_test-input-buffered-file->buffer)
 2662     (clear-stream _test-output-stream)
 2663     (clear-stream $_test-output-buffered-file->buffer)
 2664     #
 2665     (write _test-input-stream "fn foo x: int {\n")
 2666     (write _test-input-stream "  {\n")
 2667     (write _test-input-stream "    {\n")
 2668     (write _test-input-stream "      var x: int\n")
 2669     (write _test-input-stream "      increment x\n")
 2670     (write _test-input-stream "    }\n")
 2671     (write _test-input-stream "  }\n")
 2672     (write _test-input-stream "}\n")
 2673     # convert
 2674     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2675     (flush _test-output-buffered-file)
 2676 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2682     # check output
 2683     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-var-in-nested-block/0")
 2684     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-var-in-nested-block/1")
 2685     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-var-in-nested-block/2")
 2686     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-var-in-nested-block/3")
 2687     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-var-in-nested-block/4")
 2688     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-var-in-nested-block/5")
 2689     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-var-in-nested-block/6")
 2690     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-var-in-nested-block/7")
 2691     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-var-in-nested-block/8")
 2692     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-var-in-nested-block/9")
 2693     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-var-in-nested-block/10")
 2694     (check-next-stream-line-equal _test-output-stream "        ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-var-in-nested-block/11")
 2695     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-var-in-nested-block/12")
 2696     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-var-in-nested-block/13")
 2697     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-var-in-nested-block/14")
 2698     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-var-in-nested-block/15")
 2699     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-var-in-nested-block/16")
 2700     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-var-in-nested-block/17")
 2701     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-var-in-nested-block/18")
 2702     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-var-in-nested-block/19")
 2703     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-var-in-nested-block/20")
 2704     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-var-in-nested-block/21")
 2705     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-var-in-nested-block/22")
 2706     # . epilogue
 2707     89/<- %esp 5/r32/ebp
 2708     5d/pop-to-ebp
 2709     c3/return
 2710 
 2711 test-convert-function-with-multiple-vars-in-nested-blocks:
 2712     # . prologue
 2713     55/push-ebp
 2714     89/<- %ebp 4/r32/esp
 2715     # setup
 2716     (clear-stream _test-input-stream)
 2717     (clear-stream $_test-input-buffered-file->buffer)
 2718     (clear-stream _test-output-stream)
 2719     (clear-stream $_test-output-buffered-file->buffer)
 2720     #
 2721     (write _test-input-stream "fn foo x: int {\n")
 2722     (write _test-input-stream "  {\n")
 2723     (write _test-input-stream "    var x/eax: int <- copy 0\n")
 2724     (write _test-input-stream "    {\n")
 2725     (write _test-input-stream "      var y: int\n")
 2726     (write _test-input-stream "      x <- add y\n")
 2727     (write _test-input-stream "    }\n")
 2728     (write _test-input-stream "  }\n")
 2729     (write _test-input-stream "}\n")
 2730     # convert
 2731     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2732     (flush _test-output-buffered-file)
 2733 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2739     # check output
 2740     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-multiple-vars-in-nested-blocks/0")
 2741     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-multiple-vars-in-nested-blocks/1")
 2742     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-multiple-vars-in-nested-blocks/2")
 2743     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/3")
 2744     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-multiple-vars-in-nested-blocks/4")
 2745     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-multiple-vars-in-nested-blocks/5")
 2746     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-multiple-vars-in-nested-blocks/6")
 2747     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-multiple-vars-in-nested-blocks/7")
 2748     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %eax"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/8")
 2749     (check-next-stream-line-equal _test-output-stream "      b8/copy-to-eax 0/imm32"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/9")
 2750     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-multiple-vars-in-nested-blocks/10")
 2751     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-multiple-vars-in-nested-blocks/11")
 2752     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-multiple-vars-in-nested-blocks/12")
 2753     (check-next-stream-line-equal _test-output-stream "        03/add *(ebp+0xfffffff8) 0x00000000/r32"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/13")
 2754     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/14")
 2755     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-multiple-vars-in-nested-blocks/15")
 2756     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/16")
 2757     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %eax"   "F - test-convert-function-with-multiple-vars-in-nested-blocks/17")
 2758     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-multiple-vars-in-nested-blocks/18")
 2759     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/19")
 2760     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-multiple-vars-in-nested-blocks/20")
 2761     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/21")
 2762     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-multiple-vars-in-nested-blocks/22")
 2763     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-multiple-vars-in-nested-blocks/23")
 2764     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-multiple-vars-in-nested-blocks/24")
 2765     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-multiple-vars-in-nested-blocks/25")
 2766     # . epilogue
 2767     89/<- %esp 5/r32/ebp
 2768     5d/pop-to-ebp
 2769     c3/return
 2770 
 2771 test-convert-function-with-branches-and-local-vars:
 2772     # A conditional 'break' after a 'var' in a block is converted into a
 2773     # nested block that performs all necessary cleanup before jumping. This
 2774     # results in some ugly code duplication.
 2775     # . prologue
 2776     55/push-ebp
 2777     89/<- %ebp 4/r32/esp
 2778     # setup
 2779     (clear-stream _test-input-stream)
 2780     (clear-stream $_test-input-buffered-file->buffer)
 2781     (clear-stream _test-output-stream)
 2782     (clear-stream $_test-output-buffered-file->buffer)
 2783     #
 2784     (write _test-input-stream "fn foo {\n")
 2785     (write _test-input-stream "  {\n")
 2786     (write _test-input-stream "    var x: int\n")
 2787     (write _test-input-stream "    break-if->=\n")
 2788     (write _test-input-stream "    increment x\n")
 2789     (write _test-input-stream "  }\n")
 2790     (write _test-input-stream "}\n")
 2791     # convert
 2792     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2793     (flush _test-output-buffered-file)
 2794 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2800     # check output
 2801     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-branches-and-local-vars/0")
 2802     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-branches-and-local-vars/1")
 2803     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-branches-and-local-vars/2")
 2804     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-branches-and-local-vars/3")
 2805     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-branches-and-local-vars/4")
 2806     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-branches-and-local-vars/5")
 2807     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-branches-and-local-vars/6")
 2808     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-branches-and-local-vars/7")
 2809     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-branches-and-local-vars/8")
 2810     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-and-local-vars/9")
 2811     (check-next-stream-line-equal _test-output-stream "        0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-branches-and-local-vars/10")
 2812     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-branches-and-local-vars/11")
 2813     (check-next-stream-line-equal _test-output-stream "        e9/jump $foo:0x00000002:break/disp32"  "F - test-convert-function-with-branches-and-local-vars/12")
 2814     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-and-local-vars/13")
 2815     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-branches-and-local-vars/14")
 2816     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-branches-and-local-vars/15")
 2817     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-branches-and-local-vars/16")
 2818     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-branches-and-local-vars/17")
 2819     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-branches-and-local-vars/18")
 2820     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-branches-and-local-vars/19")
 2821     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-branches-and-local-vars/20")
 2822     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-branches-and-local-vars/21")
 2823     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-branches-and-local-vars/22")
 2824     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-branches-and-local-vars/23")
 2825     # . epilogue
 2826     89/<- %esp 5/r32/ebp
 2827     5d/pop-to-ebp
 2828     c3/return
 2829 
 2830 test-convert-function-with-conditional-loops-and-local-vars:
 2831     # A conditional 'loop' after a 'var' in a block is converted into a nested
 2832     # block that performs all necessary cleanup before jumping. This results
 2833     # in some ugly code duplication.
 2834     # . prologue
 2835     55/push-ebp
 2836     89/<- %ebp 4/r32/esp
 2837     # setup
 2838     (clear-stream _test-input-stream)
 2839     (clear-stream $_test-input-buffered-file->buffer)
 2840     (clear-stream _test-output-stream)
 2841     (clear-stream $_test-output-buffered-file->buffer)
 2842     #
 2843     (write _test-input-stream "fn foo {\n")
 2844     (write _test-input-stream "  {\n")
 2845     (write _test-input-stream "    var x: int\n")
 2846     (write _test-input-stream "    loop-if->=\n")
 2847     (write _test-input-stream "    increment x\n")
 2848     (write _test-input-stream "  }\n")
 2849     (write _test-input-stream "}\n")
 2850     # convert
 2851     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2852     (flush _test-output-buffered-file)
 2853 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2859     # check output
 2860     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-conditional-loops-and-local-vars/0")
 2861     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-conditional-loops-and-local-vars/1")
 2862     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-conditional-loops-and-local-vars/2")
 2863     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-conditional-loops-and-local-vars/3")
 2864     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-conditional-loops-and-local-vars/4")
 2865     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-conditional-loops-and-local-vars/5")
 2866     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-conditional-loops-and-local-vars/6")
 2867     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-conditional-loops-and-local-vars/7")
 2868     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-conditional-loops-and-local-vars/8")
 2869     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-conditional-loops-and-local-vars/9")
 2870     (check-next-stream-line-equal _test-output-stream "        0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-conditional-loops-and-local-vars/10")
 2871     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-conditional-loops-and-local-vars/11")
 2872     (check-next-stream-line-equal _test-output-stream "        e9/jump $foo:0x00000002:loop/disp32"  "F - test-convert-function-with-conditional-loops-and-local-vars/12")
 2873     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-conditional-loops-and-local-vars/13")
 2874     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-conditional-loops-and-local-vars/14")
 2875     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-conditional-loops-and-local-vars/15")
 2876     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-conditional-loops-and-local-vars/16")
 2877     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-conditional-loops-and-local-vars/17")
 2878     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-conditional-loops-and-local-vars/18")
 2879     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-conditional-loops-and-local-vars/19")
 2880     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-conditional-loops-and-local-vars/20")
 2881     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-conditional-loops-and-local-vars/21")
 2882     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-conditional-loops-and-local-vars/22")
 2883     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-conditional-loops-and-local-vars/23")
 2884     # . epilogue
 2885     89/<- %esp 5/r32/ebp
 2886     5d/pop-to-ebp
 2887     c3/return
 2888 
 2889 test-convert-function-with-unconditional-loops-and-local-vars:
 2890     # An unconditional 'loop' after a 'var' in a block is emitted _after_ the
 2891     # regular block cleanup. Any instructions after 'loop' are dead and
 2892     # therefore skipped.
 2893     # . prologue
 2894     55/push-ebp
 2895     89/<- %ebp 4/r32/esp
 2896     # setup
 2897     (clear-stream _test-input-stream)
 2898     (clear-stream $_test-input-buffered-file->buffer)
 2899     (clear-stream _test-output-stream)
 2900     (clear-stream $_test-output-buffered-file->buffer)
 2901     #
 2902     (write _test-input-stream "fn foo {\n")
 2903     (write _test-input-stream "  {\n")
 2904     (write _test-input-stream "    var x: int\n")
 2905     (write _test-input-stream "    loop\n")
 2906     (write _test-input-stream "    increment x\n")
 2907     (write _test-input-stream "  }\n")
 2908     (write _test-input-stream "}\n")
 2909     # convert
 2910     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2911     (flush _test-output-buffered-file)
 2912 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2918     # check output
 2919     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-unconditional-loops-and-local-vars/0")
 2920     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-unconditional-loops-and-local-vars/1")
 2921     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-unconditional-loops-and-local-vars/2")
 2922     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-unconditional-loops-and-local-vars/3")
 2923     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-unconditional-loops-and-local-vars/4")
 2924     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-unconditional-loops-and-local-vars/5")
 2925     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-unconditional-loops-and-local-vars/6")
 2926     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-unconditional-loops-and-local-vars/7")
 2927     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-unconditional-loops-and-local-vars/8")
 2928     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-unconditional-loops-and-local-vars/9")
 2929     (check-next-stream-line-equal _test-output-stream "      e9/jump loop/disp32"  "F - test-convert-function-with-unconditional-loops-and-local-vars/10")
 2930     # not emitted:                                           ff 0/subop/increment *(ebp+0xfffffffc)
 2931     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-unconditional-loops-and-local-vars/11")
 2932     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-unconditional-loops-and-local-vars/12")
 2933     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-unconditional-loops-and-local-vars/13")
 2934     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-unconditional-loops-and-local-vars/14")
 2935     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-unconditional-loops-and-local-vars/15")
 2936     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-unconditional-loops-and-local-vars/16")
 2937     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-unconditional-loops-and-local-vars/17")
 2938     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-unconditional-loops-and-local-vars/18")
 2939     # . epilogue
 2940     89/<- %esp 5/r32/ebp
 2941     5d/pop-to-ebp
 2942     c3/return
 2943 
 2944 test-convert-function-with-branches-and-loops-and-local-vars:
 2945     # . prologue
 2946     55/push-ebp
 2947     89/<- %ebp 4/r32/esp
 2948     # setup
 2949     (clear-stream _test-input-stream)
 2950     (clear-stream $_test-input-buffered-file->buffer)
 2951     (clear-stream _test-output-stream)
 2952     (clear-stream $_test-output-buffered-file->buffer)
 2953     #
 2954     (write _test-input-stream "fn foo {\n")
 2955     (write _test-input-stream "  {\n")
 2956     (write _test-input-stream "    var x: int\n")
 2957     (write _test-input-stream "    break-if->=\n")
 2958     (write _test-input-stream "    increment x\n")
 2959     (write _test-input-stream "    loop\n")
 2960     (write _test-input-stream "  }\n")
 2961     (write _test-input-stream "}\n")
 2962     # convert
 2963     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 2964     (flush _test-output-buffered-file)
 2965 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 2971     # check output
 2972     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-branches-and-loops-and-local-vars/0")
 2973     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-branches-and-loops-and-local-vars/1")
 2974     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-branches-and-loops-and-local-vars/2")
 2975     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-branches-and-loops-and-local-vars/3")
 2976     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-branches-and-loops-and-local-vars/4")
 2977     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-branches-and-loops-and-local-vars/5")
 2978     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-branches-and-loops-and-local-vars/6")
 2979     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-branches-and-loops-and-local-vars/7")
 2980     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-branches-and-loops-and-local-vars/8")
 2981     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-branches-and-loops-and-local-vars/9")
 2982     (check-next-stream-line-equal _test-output-stream "        0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-branches-and-loops-and-local-vars/10")
 2983     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-branches-and-loops-and-local-vars/11")
 2984     (check-next-stream-line-equal _test-output-stream "        e9/jump $foo:0x00000002:break/disp32"  "F - test-convert-function-with-branches-and-loops-and-local-vars/12")
 2985     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-branches-and-loops-and-local-vars/13")
 2986     (check-next-stream-line-equal _test-output-stream "      ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-branches-and-loops-and-local-vars/14")
 2987     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-branches-and-loops-and-local-vars/15")
 2988     (check-next-stream-line-equal _test-output-stream "      e9/jump loop/disp32"  "F - test-convert-function-with-branches-and-loops-and-local-vars/16")
 2989     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-branches-and-loops-and-local-vars/17")
 2990     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-branches-and-loops-and-local-vars/18")
 2991     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-branches-and-loops-and-local-vars/19")
 2992     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-branches-and-loops-and-local-vars/20")
 2993     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-branches-and-loops-and-local-vars/21")
 2994     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-branches-and-loops-and-local-vars/22")
 2995     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-branches-and-loops-and-local-vars/23")
 2996     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-branches-and-loops-and-local-vars/24")
 2997     # . epilogue
 2998     89/<- %esp 5/r32/ebp
 2999     5d/pop-to-ebp
 3000     c3/return
 3001 
 3002 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars:
 3003     # . prologue
 3004     55/push-ebp
 3005     89/<- %ebp 4/r32/esp
 3006     # setup
 3007     (clear-stream _test-input-stream)
 3008     (clear-stream $_test-input-buffered-file->buffer)
 3009     (clear-stream _test-output-stream)
 3010     (clear-stream $_test-output-buffered-file->buffer)
 3011     #
 3012     (write _test-input-stream "fn foo {\n")
 3013     (write _test-input-stream "  a: {\n")
 3014     (write _test-input-stream "    var x: int\n")
 3015     (write _test-input-stream "    {\n")
 3016     (write _test-input-stream "      var y: int\n")
 3017     (write _test-input-stream "      break-if->= a\n")
 3018     (write _test-input-stream "      increment x\n")
 3019     (write _test-input-stream "      loop\n")
 3020     (write _test-input-stream "    }\n")
 3021     (write _test-input-stream "  }\n")
 3022     (write _test-input-stream "}\n")
 3023     # convert
 3024     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3025     (flush _test-output-buffered-file)
 3026 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3032     # check output
 3033     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/0")
 3034     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/1")
 3035     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/2")
 3036     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/3")
 3037     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/4")
 3038     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/5")
 3039     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/6")
 3040     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/7")
 3041     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/8")
 3042     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/9")
 3043     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/10")
 3044     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/11")
 3045     (check-next-stream-line-equal _test-output-stream "        {"               "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/12")
 3046     (check-next-stream-line-equal _test-output-stream "          0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/13")
 3047     (check-next-stream-line-equal _test-output-stream "          81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/14")
 3048     (check-next-stream-line-equal _test-output-stream "          81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/15")
 3049     (check-next-stream-line-equal _test-output-stream "          e9/jump a:break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/16")
 3050     (check-next-stream-line-equal _test-output-stream "        }"               "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/17")
 3051     (check-next-stream-line-equal _test-output-stream "        ff 0/subop/increment *(ebp+0xfffffffc)"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/18")
 3052     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/19")
 3053     (check-next-stream-line-equal _test-output-stream "        e9/jump loop/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/20")
 3054     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/21")
 3055     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/22")
 3056     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/23")
 3057     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/24")
 3058     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/25")
 3059     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/26")
 3060     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/27")
 3061     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/28")
 3062     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/29")
 3063     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/30")
 3064     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars/31")
 3065     # . epilogue
 3066     89/<- %esp 5/r32/ebp
 3067     5d/pop-to-ebp
 3068     c3/return
 3069 
 3070 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2:
 3071     # . prologue
 3072     55/push-ebp
 3073     89/<- %ebp 4/r32/esp
 3074     # setup
 3075     (clear-stream _test-input-stream)
 3076     (clear-stream $_test-input-buffered-file->buffer)
 3077     (clear-stream _test-output-stream)
 3078     (clear-stream $_test-output-buffered-file->buffer)
 3079     # non-local conditional branch from a block without a local variable,
 3080     # unwinding a local on the stack
 3081     (write _test-input-stream "fn foo {\n")
 3082     (write _test-input-stream "  a: {\n")
 3083     (write _test-input-stream "    var x: int\n")
 3084     (write _test-input-stream "    {\n")
 3085     (write _test-input-stream "      break-if->= a\n")
 3086     (write _test-input-stream "    }\n")
 3087     (write _test-input-stream "  }\n")
 3088     (write _test-input-stream "}\n")
 3089     # convert
 3090     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3091     (flush _test-output-buffered-file)
 3092 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3098     # check output
 3099     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/0")
 3100     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/1")
 3101     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/2")
 3102     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/3")
 3103     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/4")
 3104     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/5")
 3105     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/6")
 3106     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/7")
 3107     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/8")
 3108     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/9")
 3109     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/10")
 3110     (check-next-stream-line-equal _test-output-stream "        {"               "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/11")
 3111     (check-next-stream-line-equal _test-output-stream "          0f 8c/jump-if-< break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/12")
 3112     (check-next-stream-line-equal _test-output-stream "          81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/13")
 3113     (check-next-stream-line-equal _test-output-stream "          e9/jump a:break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/14")
 3114     (check-next-stream-line-equal _test-output-stream "        }"               "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/15")
 3115     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/16")
 3116     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/17")
 3117     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/18")
 3118     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/19")
 3119     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/20")
 3120     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/21")
 3121     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/22")
 3122     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/23")
 3123     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/24")
 3124     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/25")
 3125     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-2/26")
 3126     # . epilogue
 3127     89/<- %esp 5/r32/ebp
 3128     5d/pop-to-ebp
 3129     c3/return
 3130 
 3131 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3:
 3132     # . prologue
 3133     55/push-ebp
 3134     89/<- %ebp 4/r32/esp
 3135     # setup
 3136     (clear-stream _test-input-stream)
 3137     (clear-stream $_test-input-buffered-file->buffer)
 3138     (clear-stream _test-output-stream)
 3139     (clear-stream $_test-output-buffered-file->buffer)
 3140     # non-local unconditional branch from a block without a local variable,
 3141     # unwinding a local on the stack
 3142     (write _test-input-stream "fn foo {\n")
 3143     (write _test-input-stream "  a: {\n")
 3144     (write _test-input-stream "    var x: int\n")
 3145     (write _test-input-stream "    {\n")
 3146     (write _test-input-stream "      break a\n")
 3147     (write _test-input-stream "    }\n")
 3148     (write _test-input-stream "  }\n")
 3149     (write _test-input-stream "}\n")
 3150     # convert
 3151     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3152     (flush _test-output-buffered-file)
 3153 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3159     # check output
 3160     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/0")
 3161     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/1")
 3162     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/2")
 3163     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/3")
 3164     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/4")
 3165     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/5")
 3166     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/6")
 3167     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/7")
 3168     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/8")
 3169     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/9")
 3170     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/10")
 3171     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/11")
 3172     (check-next-stream-line-equal _test-output-stream "        e9/jump a:break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/12")
 3173     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/14")
 3174     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/15")
 3175     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/16")
 3176     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/17")
 3177     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/18")
 3178     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/19")
 3179     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/20")
 3180     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/21")
 3181     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/22")
 3182     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/23")
 3183     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-3/24")
 3184     # . epilogue
 3185     89/<- %esp 5/r32/ebp
 3186     5d/pop-to-ebp
 3187     c3/return
 3188 
 3189 test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4:
 3190     # . prologue
 3191     55/push-ebp
 3192     89/<- %ebp 4/r32/esp
 3193     # setup
 3194     (clear-stream _test-input-stream)
 3195     (clear-stream $_test-input-buffered-file->buffer)
 3196     (clear-stream _test-output-stream)
 3197     (clear-stream $_test-output-buffered-file->buffer)
 3198     #
 3199     (write _test-input-stream "fn foo {\n")
 3200     (write _test-input-stream "  a: {\n")
 3201     (write _test-input-stream "    var x/esi: int <- copy 0\n")
 3202     (write _test-input-stream "    {\n")
 3203     (write _test-input-stream "      break a\n")
 3204     (write _test-input-stream "    }\n")
 3205     (write _test-input-stream "  }\n")
 3206     (write _test-input-stream "}\n")
 3207     # convert
 3208     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3209     (flush _test-output-buffered-file)
 3210 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3216     # check output
 3217     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/0")
 3218     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/1")
 3219     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/2")
 3220     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/3")
 3221     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/4")
 3222     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/5")
 3223     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/6")
 3224     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/7")
 3225     (check-next-stream-line-equal _test-output-stream "      ff 6/subop/push %esi"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/8")
 3226     (check-next-stream-line-equal _test-output-stream "      be/copy-to-esi 0/imm32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/9")
 3227     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/10")
 3228     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/11")
 3229     (check-next-stream-line-equal _test-output-stream "        8f 0/subop/pop %esi"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/12")
 3230     (check-next-stream-line-equal _test-output-stream "        e9/jump a:break/disp32"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/13")
 3231     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/14")
 3232     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/15")
 3233     (check-next-stream-line-equal _test-output-stream "      8f 0/subop/pop %esi"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/16")
 3234     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/17")
 3235     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/18")
 3236     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/19")
 3237     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/20")
 3238     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/21")
 3239     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/22")
 3240     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/23")
 3241     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-branches-and-loops-and-local-vars-4/24")
 3242     # . epilogue
 3243     89/<- %esp 5/r32/ebp
 3244     5d/pop-to-ebp
 3245     c3/return
 3246 
 3247 test-convert-function-with-nonlocal-unconditional-break-and-local-vars:
 3248     # . prologue
 3249     55/push-ebp
 3250     89/<- %ebp 4/r32/esp
 3251     # setup
 3252     (clear-stream _test-input-stream)
 3253     (clear-stream $_test-input-buffered-file->buffer)
 3254     (clear-stream _test-output-stream)
 3255     (clear-stream $_test-output-buffered-file->buffer)
 3256     #
 3257     (write _test-input-stream "fn foo {\n")
 3258     (write _test-input-stream "  a: {\n")
 3259     (write _test-input-stream "    var x: int\n")
 3260     (write _test-input-stream "    {\n")
 3261     (write _test-input-stream "      var y: int\n")
 3262     (write _test-input-stream "      break a\n")
 3263     (write _test-input-stream "      increment x\n")
 3264     (write _test-input-stream "    }\n")
 3265     (write _test-input-stream "  }\n")
 3266     (write _test-input-stream "}\n")
 3267     # convert
 3268     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3269     (flush _test-output-buffered-file)
 3270 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3276     # check output
 3277     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/0")
 3278     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/1")
 3279     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/2")
 3280     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/3")
 3281     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/4")
 3282     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/5")
 3283     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/6")
 3284     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/7")
 3285     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/8")
 3286     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/9")
 3287     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/10")
 3288     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/11")
 3289     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/12")
 3290     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/13")
 3291     (check-next-stream-line-equal _test-output-stream "        e9/jump a:break/disp32"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/14")
 3292     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/15")
 3293     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/16")
 3294     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/17")
 3295     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/18")
 3296     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/19")
 3297     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/20")
 3298     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/21")
 3299     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/22")
 3300     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/23")
 3301     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/24")
 3302     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-unconditional-break-and-local-vars/25")
 3303     # . epilogue
 3304     89/<- %esp 5/r32/ebp
 3305     5d/pop-to-ebp
 3306     c3/return
 3307 
 3308 test-convert-function-with-unconditional-break-and-local-vars:
 3309     # . prologue
 3310     55/push-ebp
 3311     89/<- %ebp 4/r32/esp
 3312     # setup
 3313     (clear-stream _test-input-stream)
 3314     (clear-stream $_test-input-buffered-file->buffer)
 3315     (clear-stream _test-output-stream)
 3316     (clear-stream $_test-output-buffered-file->buffer)
 3317     #
 3318     (write _test-input-stream "fn foo {\n")
 3319     (write _test-input-stream "  {\n")
 3320     (write _test-input-stream "    var x: int\n")
 3321     (write _test-input-stream "    {\n")
 3322     (write _test-input-stream "      var y: int\n")
 3323     (write _test-input-stream "      break\n")
 3324     (write _test-input-stream "      increment x\n")
 3325     (write _test-input-stream "    }\n")
 3326     (write _test-input-stream "  }\n")
 3327     (write _test-input-stream "}\n")
 3328     # convert
 3329     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3330     (flush _test-output-buffered-file)
 3331 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3337     # check output
 3338     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-unconditional-break-and-local-vars/0")
 3339     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-unconditional-break-and-local-vars/1")
 3340     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-unconditional-break-and-local-vars/2")
 3341     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-unconditional-break-and-local-vars/3")
 3342     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-unconditional-break-and-local-vars/4")
 3343     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-unconditional-break-and-local-vars/5")
 3344     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-unconditional-break-and-local-vars/6")
 3345     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-with-unconditional-break-and-local-vars/7")
 3346     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-unconditional-break-and-local-vars/8")
 3347     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-unconditional-break-and-local-vars/9")
 3348     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-unconditional-break-and-local-vars/10")
 3349     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-unconditional-break-and-local-vars/11")
 3350     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-unconditional-break-and-local-vars/12")
 3351     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-unconditional-break-and-local-vars/13")
 3352     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-unconditional-break-and-local-vars/14")
 3353     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-unconditional-break-and-local-vars/15")
 3354     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-unconditional-break-and-local-vars/16")
 3355     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-with-unconditional-break-and-local-vars/17")
 3356     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-unconditional-break-and-local-vars/18")
 3357     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-unconditional-break-and-local-vars/19")
 3358     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-unconditional-break-and-local-vars/20")
 3359     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-unconditional-break-and-local-vars/21")
 3360     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-unconditional-break-and-local-vars/22")
 3361     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-unconditional-break-and-local-vars/23")
 3362     # . epilogue
 3363     89/<- %esp 5/r32/ebp
 3364     5d/pop-to-ebp
 3365     c3/return
 3366 
 3367 test-convert-function-with-nonlocal-unconditional-loop-and-local-vars:
 3368     # . prologue
 3369     55/push-ebp
 3370     89/<- %ebp 4/r32/esp
 3371     # setup
 3372     (clear-stream _test-input-stream)
 3373     (clear-stream $_test-input-buffered-file->buffer)
 3374     (clear-stream _test-output-stream)
 3375     (clear-stream $_test-output-buffered-file->buffer)
 3376     #
 3377     (write _test-input-stream "fn foo {\n")
 3378     (write _test-input-stream "  a: {\n")
 3379     (write _test-input-stream "    var x: int\n")
 3380     (write _test-input-stream "    {\n")
 3381     (write _test-input-stream "      var y: int\n")
 3382     (write _test-input-stream "      loop a\n")
 3383     (write _test-input-stream "      increment x\n")
 3384     (write _test-input-stream "    }\n")
 3385     (write _test-input-stream "  }\n")
 3386     (write _test-input-stream "}\n")
 3387     # convert
 3388     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3389     (flush _test-output-buffered-file)
 3390 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3396     # check output
 3397     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/0")
 3398     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/1")
 3399     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/2")
 3400     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/3")
 3401     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/4")
 3402     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/5")
 3403     (check-next-stream-line-equal _test-output-stream "    {"                   "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/6")
 3404     (check-next-stream-line-equal _test-output-stream "a:loop:"                 "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/7")
 3405     (check-next-stream-line-equal _test-output-stream "      68/push 0/imm32"   "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/8")
 3406     (check-next-stream-line-equal _test-output-stream "      {"                 "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/9")
 3407     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:loop:"   "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/10")
 3408     (check-next-stream-line-equal _test-output-stream "        68/push 0/imm32" "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/11")
 3409     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/12")
 3410     (check-next-stream-line-equal _test-output-stream "        81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/13")
 3411     (check-next-stream-line-equal _test-output-stream "        e9/jump a:loop/disp32"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/14")
 3412     (check-next-stream-line-equal _test-output-stream "      }"                 "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/15")
 3413     (check-next-stream-line-equal _test-output-stream "$foo:0x00000003:break:"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/16")
 3414     (check-next-stream-line-equal _test-output-stream "      81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/17")
 3415     (check-next-stream-line-equal _test-output-stream "    }"                   "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/18")
 3416     (check-next-stream-line-equal _test-output-stream "a:break:"                "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/19")
 3417     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/20")
 3418     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/21")
 3419     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/22")
 3420     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/23")
 3421     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/24")
 3422     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-nonlocal-unconditional-loop-and-local-vars/25")
 3423     # . epilogue
 3424     89/<- %esp 5/r32/ebp
 3425     5d/pop-to-ebp
 3426     c3/return
 3427 
 3428 test-convert-function-with-local-array-var-in-mem:
 3429     # . prologue
 3430     55/push-ebp
 3431     89/<- %ebp 4/r32/esp
 3432     # setup
 3433     (clear-stream _test-input-stream)
 3434     (clear-stream $_test-input-buffered-file->buffer)
 3435     (clear-stream _test-output-stream)
 3436     (clear-stream $_test-output-buffered-file->buffer)
 3437     #
 3438     (write _test-input-stream "fn foo {\n")
 3439     (write _test-input-stream "  var x: (array int 3)\n")
 3440     (write _test-input-stream "}\n")
 3441     # convert
 3442     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3443     (flush _test-output-buffered-file)
 3444 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3450     # check output
 3451     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-array-var-in-mem/0")
 3452     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-array-var-in-mem/1")
 3453     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-array-var-in-mem/2")
 3454     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-array-var-in-mem/3")
 3455     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-array-var-in-mem/4")
 3456     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-array-var-in-mem/5")
 3457     # define x
 3458     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x0000000c)"  "F - test-convert-function-with-local-array-var-in-mem/7")
 3459     (check-next-stream-line-equal _test-output-stream "    68/push 0x0000000c/imm32"  "F - test-convert-function-with-local-array-var-in-mem/8")
 3460     # reclaim x
 3461     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000010/imm32"  "F - test-convert-function-with-local-array-var-in-mem/9")
 3462     #
 3463     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-array-var-in-mem/10")
 3464     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-array-var-in-mem/11")
 3465     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-array-var-in-mem/12")
 3466     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-array-var-in-mem/13")
 3467     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-array-var-in-mem/14")
 3468     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-array-var-in-mem/15")
 3469     # . epilogue
 3470     89/<- %esp 5/r32/ebp
 3471     5d/pop-to-ebp
 3472     c3/return
 3473 
 3474 # special-case for size(byte) when allocating array
 3475 test-convert-function-with-local-array-of-bytes-in-mem:
 3476     # . prologue
 3477     55/push-ebp
 3478     89/<- %ebp 4/r32/esp
 3479     # setup
 3480     (clear-stream _test-input-stream)
 3481     (clear-stream $_test-input-buffered-file->buffer)
 3482     (clear-stream _test-output-stream)
 3483     (clear-stream $_test-output-buffered-file->buffer)
 3484     #
 3485     (write _test-input-stream "fn foo {\n")
 3486     (write _test-input-stream "  var x: (array byte 3)\n")
 3487     (write _test-input-stream "}\n")
 3488     # convert
 3489     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3490     (flush _test-output-buffered-file)
 3491 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3497     # check output
 3498     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-array-of-bytes-in-mem/0")
 3499     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-array-of-bytes-in-mem/1")
 3500     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-array-of-bytes-in-mem/2")
 3501     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-array-of-bytes-in-mem/3")
 3502     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-array-of-bytes-in-mem/4")
 3503     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-array-of-bytes-in-mem/5")
 3504     # define x
 3505     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x00000003)"  "F - test-convert-function-with-local-array-of-bytes-in-mem/7")
 3506     (check-next-stream-line-equal _test-output-stream "    68/push 0x00000003/imm32"  "F - test-convert-function-with-local-array-of-bytes-in-mem/8")
 3507     # reclaim x
 3508     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000007/imm32"  "F - test-convert-function-with-local-array-of-bytes-in-mem/9")
 3509     #
 3510     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-array-of-bytes-in-mem/10")
 3511     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-array-of-bytes-in-mem/11")
 3512     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-array-of-bytes-in-mem/12")
 3513     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-array-of-bytes-in-mem/13")
 3514     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-array-of-bytes-in-mem/14")
 3515     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-array-of-bytes-in-mem/15")
 3516     # . epilogue
 3517     89/<- %esp 5/r32/ebp
 3518     5d/pop-to-ebp
 3519     c3/return
 3520 
 3521 test-convert-address:
 3522     # . prologue
 3523     55/push-ebp
 3524     89/<- %ebp 4/r32/esp
 3525     # setup
 3526     (clear-stream _test-input-stream)
 3527     (clear-stream $_test-input-buffered-file->buffer)
 3528     (clear-stream _test-output-stream)
 3529     (clear-stream $_test-output-buffered-file->buffer)
 3530     #
 3531     (write _test-input-stream "fn foo {\n")
 3532     (write _test-input-stream "  var a: int\n")
 3533     (write _test-input-stream "  var b/eax: (addr int) <- address a\n")
 3534     (write _test-input-stream "}\n")
 3535     # convert
 3536     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3537     (flush _test-output-buffered-file)
 3538 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3544     # check output
 3545     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-address/0")
 3546     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-address/1")
 3547     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-address/2")
 3548     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-address/3")
 3549     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-address/4")
 3550     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-address/5")
 3551     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-address/6")
 3552     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-address/7")
 3553     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp+0xfffffffc) 0x00000000/r32"  "F - test-convert-address/8")
 3554     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"  "F - test-convert-address/9")
 3555     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"  "F - test-convert-address/10")
 3556     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-address/11")
 3557     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-address/12")
 3558     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-address/13")
 3559     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-address/14")
 3560     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-address/15")
 3561     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-address/16")
 3562     # . epilogue
 3563     89/<- %esp 5/r32/ebp
 3564     5d/pop-to-ebp
 3565     c3/return
 3566 
 3567 test-convert-length-of-array:
 3568     # . prologue
 3569     55/push-ebp
 3570     89/<- %ebp 4/r32/esp
 3571     # setup
 3572     (clear-stream _test-input-stream)
 3573     (clear-stream $_test-input-buffered-file->buffer)
 3574     (clear-stream _test-output-stream)
 3575     (clear-stream $_test-output-buffered-file->buffer)
 3576     #
 3577     (write _test-input-stream "fn foo a: (addr array int) {\n")
 3578     (write _test-input-stream "  var b/eax: (addr array int) <- copy a\n")
 3579     (write _test-input-stream "  var c/eax: int <- length b\n")
 3580     (write _test-input-stream "}\n")
 3581     # convert
 3582     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3583     (flush _test-output-buffered-file)
 3584 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3590     # check output
 3591     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-length-of-array/0")
 3592     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-length-of-array/1")
 3593     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-length-of-array/2")
 3594     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-length-of-array/3")
 3595     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-length-of-array/4")
 3596     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-length-of-array/5")
 3597     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-length-of-array/6")
 3598     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-length-of-array/7")
 3599     (check-next-stream-line-equal _test-output-stream "    8b/-> *eax 0x00000000/r32"  "F - test-convert-length-of-array/8")
 3600     (check-next-stream-line-equal _test-output-stream "    c1/shift 5/subop/>> %eax 0x00000002/imm8"  "F - test-convert-length-of-array/9")
 3601     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"  "F - test-convert-length-of-array/10")
 3602     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-length-of-array/11")
 3603     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-length-of-array/12")
 3604     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-length-of-array/13")
 3605     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-length-of-array/14")
 3606     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-length-of-array/15")
 3607     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-length-of-array/16")
 3608     # . epilogue
 3609     89/<- %esp 5/r32/ebp
 3610     5d/pop-to-ebp
 3611     c3/return
 3612 
 3613 # special-case for size(byte) when computing array length
 3614 test-convert-length-of-array-of-bytes:
 3615     # . prologue
 3616     55/push-ebp
 3617     89/<- %ebp 4/r32/esp
 3618     # setup
 3619     (clear-stream _test-input-stream)
 3620     (clear-stream $_test-input-buffered-file->buffer)
 3621     (clear-stream _test-output-stream)
 3622     (clear-stream $_test-output-buffered-file->buffer)
 3623     #
 3624     (write _test-input-stream "fn foo a: (addr array byte) {\n")
 3625     (write _test-input-stream "  var b/eax: (addr array byte) <- copy a\n")
 3626     (write _test-input-stream "  var c/eax: int <- length b\n")
 3627     (write _test-input-stream "}\n")
 3628     # convert
 3629     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3630     (flush _test-output-buffered-file)
 3631 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3637     # check output
 3638     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-length-of-array-of-bytes/0")
 3639     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-length-of-array-of-bytes/1")
 3640     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-length-of-array-of-bytes/2")
 3641     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-length-of-array-of-bytes/3")
 3642     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-length-of-array-of-bytes/4")
 3643     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-length-of-array-of-bytes/5")
 3644     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-length-of-array-of-bytes/6")
 3645     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-length-of-array-of-bytes/7")
 3646     (check-next-stream-line-equal _test-output-stream "    8b/-> *eax 0x00000000/r32"  "F - test-convert-length-of-array-of-bytes/8")
 3647     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"  "F - test-convert-length-of-array-of-bytes/9")
 3648     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-length-of-array-of-bytes/10")
 3649     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-length-of-array-of-bytes/11")
 3650     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-length-of-array-of-bytes/12")
 3651     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-length-of-array-of-bytes/13")
 3652     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-length-of-array-of-bytes/14")
 3653     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-length-of-array-of-bytes/15")
 3654     # . epilogue
 3655     89/<- %esp 5/r32/ebp
 3656     5d/pop-to-ebp
 3657     c3/return
 3658 
 3659 test-convert-length-of-array-on-stack:
 3660     # . prologue
 3661     55/push-ebp
 3662     89/<- %ebp 4/r32/esp
 3663     # setup
 3664     (clear-stream _test-input-stream)
 3665     (clear-stream $_test-input-buffered-file->buffer)
 3666     (clear-stream _test-output-stream)
 3667     (clear-stream $_test-output-buffered-file->buffer)
 3668     #
 3669     (write _test-input-stream "fn foo {\n")
 3670     (write _test-input-stream "  var a: (array int 3)\n")
 3671     (write _test-input-stream "  var b/eax: int <- length a\n")
 3672     (write _test-input-stream "}\n")
 3673     # convert
 3674     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3675     (flush _test-output-buffered-file)
 3676 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3682     # check output
 3683     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-length-of-array-on-stack/0")
 3684     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-length-of-array-on-stack/1")
 3685     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-length-of-array-on-stack/2")
 3686     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-length-of-array-on-stack/3")
 3687     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-length-of-array-on-stack/4")
 3688     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-length-of-array-on-stack/5")
 3689     # define x
 3690     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x0000000c)"  "F - test-convert-length-of-array-on-stack/6")
 3691     (check-next-stream-line-equal _test-output-stream "    68/push 0x0000000c/imm32"  "F - test-convert-length-of-array-on-stack/7")
 3692     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-length-of-array-on-stack/8")
 3693     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0xfffffff0) 0x00000000/r32"  "F - test-convert-length-of-array-on-stack/9")
 3694     (check-next-stream-line-equal _test-output-stream "    c1/shift 5/subop/>> %eax 0x00000002/imm8"  "F - test-convert-length-of-array-on-stack/10")
 3695     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"  "F - test-convert-length-of-array-on-stack/11")
 3696     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000010/imm32"  "F - test-convert-length-of-array-on-stack/12")
 3697     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-length-of-array-on-stack/13")
 3698     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-length-of-array-on-stack/14")
 3699     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-length-of-array-on-stack/15")
 3700     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-length-of-array-on-stack/16")
 3701     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-length-of-array-on-stack/17")
 3702     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-length-of-array-on-stack/18")
 3703     # . epilogue
 3704     89/<- %esp 5/r32/ebp
 3705     5d/pop-to-ebp
 3706     c3/return
 3707 
 3708 test-reg-var-def-with-read-of-same-register:
 3709     # . prologue
 3710     55/push-ebp
 3711     89/<- %ebp 4/r32/esp
 3712     # setup
 3713     (clear-stream _test-input-stream)
 3714     (clear-stream $_test-input-buffered-file->buffer)
 3715     (clear-stream _test-output-stream)
 3716     (clear-stream $_test-output-buffered-file->buffer)
 3717     (clear-stream _test-error-stream)
 3718     (clear-stream $_test-error-buffered-file->buffer)
 3719     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)  # bytes of args in call to convert-mu
 3720     68/push 0/imm32
 3721     68/push 0/imm32
 3722     89/<- %edx 4/r32/esp
 3723     (tailor-exit-descriptor %edx 0x10)
 3724     #
 3725     (write _test-input-stream "fn foo {\n")
 3726     (write _test-input-stream "  var arr/eax: (addr array int) <- copy 0\n")
 3727     (write _test-input-stream "  var idx/ecx: int <- copy 3\n")
 3728     (write _test-input-stream "  var x/eax: (addr int) <- index arr, idx\n")
 3729     (write _test-input-stream "}\n")
 3730     # convert
 3731     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 3732     # registers except esp could be clobbered at this point (though they shouldn't be)
 3733     # restore ed
 3734     89/<- %edx 4/r32/esp
 3735     (flush _test-output-buffered-file)
 3736     (flush _test-error-buffered-file)
 3737 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3743     (check-stream-equal _test-error-stream  ""  "F - test-reg-var-def-with-read-of-same-register: error stream should be empty")
 3744     # check output
 3745     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-reg-var-def-with-read-of-same-register/0")
 3746     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-reg-var-def-with-read-of-same-register/1")
 3747     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-reg-var-def-with-read-of-same-register/2")
 3748     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-reg-var-def-with-read-of-same-register/3")
 3749     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-reg-var-def-with-read-of-same-register/4")
 3750     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-reg-var-def-with-read-of-same-register/5")
 3751     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-reg-var-def-with-read-of-same-register/6")
 3752     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-reg-var-def-with-read-of-same-register/7")
 3753     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-reg-var-def-with-read-of-same-register/8")
 3754     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"                  "F - test-reg-var-def-with-read-of-same-register/9")
 3755     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32"  "F - test-reg-var-def-with-read-of-same-register/11")
 3756     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-reg-var-def-with-read-of-same-register/13")
 3757     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-reg-var-def-with-read-of-same-register/14")
 3758     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-reg-var-def-with-read-of-same-register/15")
 3759     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-reg-var-def-with-read-of-same-register/16")
 3760     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-reg-var-def-with-read-of-same-register/17")
 3761     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-reg-var-def-with-read-of-same-register/18")
 3762     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-reg-var-def-with-read-of-same-register/19")
 3763     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-reg-var-def-with-read-of-same-register/20")
 3764     # don't restore from ebp
 3765     81 0/subop/add %esp 8/imm32
 3766     # . epilogue
 3767     5d/pop-to-ebp
 3768     c3/return
 3769 
 3770 test-convert-index-into-array:
 3771     # . prologue
 3772     55/push-ebp
 3773     89/<- %ebp 4/r32/esp
 3774     # setup
 3775     (clear-stream _test-input-stream)
 3776     (clear-stream $_test-input-buffered-file->buffer)
 3777     (clear-stream _test-output-stream)
 3778     (clear-stream $_test-output-buffered-file->buffer)
 3779     #
 3780     (write _test-input-stream "fn foo {\n")
 3781     (write _test-input-stream "  var arr/eax: (addr array int) <- copy 0\n")
 3782     (write _test-input-stream "  var idx/ecx: int <- copy 3\n")
 3783     (write _test-input-stream "  var x/eax: (addr int) <- index arr, idx\n")
 3784     (write _test-input-stream "}\n")
 3785     # convert
 3786     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3787     (flush _test-output-buffered-file)
 3788 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3794     # check output
 3795     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array/0")
 3796     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array/1")
 3797     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array/2")
 3798     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array/3")
 3799     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array/4")
 3800     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array/5")
 3801     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array/6")
 3802     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array/7")
 3803     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array/8")
 3804     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"                  "F - test-convert-index-into-array/9")
 3805     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx<<0x00000002 + 4) 0x00000000/r32"  "F - test-convert-index-into-array/10")
 3806     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array/11")
 3807     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array/12")
 3808     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array/13")
 3809     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array/14")
 3810     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array/15")
 3811     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array/16")
 3812     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array/17")
 3813     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array/18")
 3814     # . epilogue
 3815     89/<- %esp 5/r32/ebp
 3816     5d/pop-to-ebp
 3817     c3/return
 3818 
 3819 test-convert-index-into-array-of-bytes:
 3820     # . prologue
 3821     55/push-ebp
 3822     89/<- %ebp 4/r32/esp
 3823     # setup
 3824     (clear-stream _test-input-stream)
 3825     (clear-stream $_test-input-buffered-file->buffer)
 3826     (clear-stream _test-output-stream)
 3827     (clear-stream $_test-output-buffered-file->buffer)
 3828     #
 3829     (write _test-input-stream "fn foo {\n")
 3830     (write _test-input-stream "  var arr/eax: (addr array byte) <- copy 0\n")
 3831     (write _test-input-stream "  var idx/ecx: int <- copy 3\n")
 3832     (write _test-input-stream "  var x/eax: (addr byte) <- index arr, idx\n")
 3833     (write _test-input-stream "}\n")
 3834     # convert
 3835     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3836     (flush _test-output-buffered-file)
 3837 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3843     # check output
 3844     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-of-bytes/0")
 3845     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-of-bytes/1")
 3846     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-of-bytes/2")
 3847     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-of-bytes/3")
 3848     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-of-bytes/4")
 3849     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-of-bytes/5")
 3850     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-of-bytes/6")
 3851     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-of-bytes/7")
 3852     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array-of-bytes/8")
 3853     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"                  "F - test-convert-index-into-array-of-bytes/9")
 3854     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx<<0x00000000 + 4) 0x00000000/r32"  "F - test-convert-index-into-array-of-bytes/11")
 3855     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array-of-bytes/13")
 3856     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-of-bytes/14")
 3857     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-of-bytes/15")
 3858     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-of-bytes/16")
 3859     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-of-bytes/17")
 3860     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-of-bytes/18")
 3861     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-of-bytes/19")
 3862     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-of-bytes/20")
 3863     # . epilogue
 3864     89/<- %esp 5/r32/ebp
 3865     5d/pop-to-ebp
 3866     c3/return
 3867 
 3868 test-convert-index-into-array-with-literal:
 3869     # . prologue
 3870     55/push-ebp
 3871     89/<- %ebp 4/r32/esp
 3872     # setup
 3873     (clear-stream _test-input-stream)
 3874     (clear-stream $_test-input-buffered-file->buffer)
 3875     (clear-stream _test-output-stream)
 3876     (clear-stream $_test-output-buffered-file->buffer)
 3877     #
 3878     (write _test-input-stream "fn foo {\n")
 3879     (write _test-input-stream "  var arr/eax: (addr array int) <- copy 0\n")
 3880     (write _test-input-stream "  var x/eax: (addr int) <- index arr, 2\n")
 3881     (write _test-input-stream "}\n")
 3882     # convert
 3883     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3884     (flush _test-output-buffered-file)
 3885 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3891     # check output
 3892     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-with-literal/0")
 3893     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-with-literal/1")
 3894     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-with-literal/2")
 3895     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-with-literal/3")
 3896     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-with-literal/4")
 3897     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-with-literal/5")
 3898     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-with-literal/6")
 3899     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-with-literal/7")
 3900                                                                                  # 2 * 4 bytes/elem + 4 bytes for size = offset 12
 3901     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x0000000c) 0x00000000/r32"  "F - test-convert-index-into-array-with-literal/8")
 3902     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-with-literal/9")
 3903     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-with-literal/10")
 3904     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-with-literal/11")
 3905     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-with-literal/12")
 3906     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-with-literal/13")
 3907     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-with-literal/14")
 3908     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-with-literal/15")
 3909     # . epilogue
 3910     89/<- %esp 5/r32/ebp
 3911     5d/pop-to-ebp
 3912     c3/return
 3913 
 3914 test-convert-index-into-array-of-bytes-with-literal:
 3915     # . prologue
 3916     55/push-ebp
 3917     89/<- %ebp 4/r32/esp
 3918     # setup
 3919     (clear-stream _test-input-stream)
 3920     (clear-stream $_test-input-buffered-file->buffer)
 3921     (clear-stream _test-output-stream)
 3922     (clear-stream $_test-output-buffered-file->buffer)
 3923     #
 3924     (write _test-input-stream "fn foo {\n")
 3925     (write _test-input-stream "  var arr/eax: (addr array byte) <- copy 0\n")
 3926     (write _test-input-stream "  var x/eax: (addr byte) <- index arr, 2\n")
 3927     (write _test-input-stream "}\n")
 3928     # convert
 3929     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3930     (flush _test-output-buffered-file)
 3931 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3937     # check output
 3938     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-of-bytes-with-literal/0")
 3939     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-of-bytes-with-literal/1")
 3940     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-of-bytes-with-literal/2")
 3941     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-of-bytes-with-literal/3")
 3942     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-of-bytes-with-literal/4")
 3943     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-of-bytes-with-literal/5")
 3944     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-of-bytes-with-literal/6")
 3945     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-of-bytes-with-literal/7")
 3946                                                                                  # 2 * 1 byte/elem + 4 bytes for size = offset 6
 3947     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000006) 0x00000000/r32"  "F - test-convert-index-into-array-of-bytes-with-literal/8")
 3948     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-of-bytes-with-literal/9")
 3949     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-of-bytes-with-literal/10")
 3950     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-of-bytes-with-literal/11")
 3951     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-of-bytes-with-literal/12")
 3952     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-of-bytes-with-literal/13")
 3953     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-of-bytes-with-literal/14")
 3954     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-of-bytes-with-literal/15")
 3955     # . epilogue
 3956     89/<- %esp 5/r32/ebp
 3957     5d/pop-to-ebp
 3958     c3/return
 3959 
 3960 test-convert-index-into-array-on-stack:
 3961     # . prologue
 3962     55/push-ebp
 3963     89/<- %ebp 4/r32/esp
 3964     # setup
 3965     (clear-stream _test-input-stream)
 3966     (clear-stream $_test-input-buffered-file->buffer)
 3967     (clear-stream _test-output-stream)
 3968     (clear-stream $_test-output-buffered-file->buffer)
 3969     #
 3970     (write _test-input-stream "fn foo {\n")
 3971     (write _test-input-stream "  var arr: (array int 3)\n")
 3972     (write _test-input-stream "  var idx/eax: int <- copy 2\n")
 3973     (write _test-input-stream "  var x/eax: (addr int) <- index arr, idx\n")
 3974     (write _test-input-stream "}\n")
 3975     # convert
 3976     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 3977     (flush _test-output-buffered-file)
 3978 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 3984     # check output
 3985     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-on-stack/0")
 3986     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-on-stack/1")
 3987     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-on-stack/2")
 3988     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-on-stack/3")
 3989     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-on-stack/4")
 3990     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-on-stack/5")
 3991     # var arr
 3992     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x0000000c)"          "F - test-convert-index-into-array-on-stack/6")
 3993     (check-next-stream-line-equal _test-output-stream "    68/push 0x0000000c/imm32"                "F - test-convert-index-into-array-on-stack/7")
 3994     # var idx
 3995     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-on-stack/8")
 3996     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 2/imm32"                  "F - test-convert-index-into-array-on-stack/9")
 3997     # var x is at (ebp-0x10) + idx<<2 + 4 = ebp + idx<<2 - 0xc
 3998     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp + eax<<0x00000002 + 0xfffffff4) 0x00000000/r32"  "F - test-convert-index-into-array-on-stack/10")
 3999     # reclaim idx
 4000     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-on-stack/11")
 4001     # reclaim arr
 4002     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000010/imm32"    "F - test-convert-index-into-array-on-stack/12")
 4003     #
 4004     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-on-stack/13")
 4005     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-on-stack/14")
 4006     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-on-stack/15")
 4007     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-on-stack/16")
 4008     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-on-stack/17")
 4009     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-on-stack/18")
 4010     # . epilogue
 4011     89/<- %esp 5/r32/ebp
 4012     5d/pop-to-ebp
 4013     c3/return
 4014 
 4015 test-convert-index-into-array-on-stack-with-literal:
 4016     # . prologue
 4017     55/push-ebp
 4018     89/<- %ebp 4/r32/esp
 4019     # setup
 4020     (clear-stream _test-input-stream)
 4021     (clear-stream $_test-input-buffered-file->buffer)
 4022     (clear-stream _test-output-stream)
 4023     (clear-stream $_test-output-buffered-file->buffer)
 4024     #
 4025     (write _test-input-stream "fn foo {\n")
 4026     (write _test-input-stream "  var arr: (array int 3)\n")
 4027     (write _test-input-stream "  var x/eax: (addr int) <- index arr, 2\n")
 4028     (write _test-input-stream "}\n")
 4029     # convert
 4030     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4031     (flush _test-output-buffered-file)
 4032 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4038     # check output
 4039     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-on-stack-with-literal/0")
 4040     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-on-stack-with-literal/1")
 4041     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-on-stack-with-literal/2")
 4042     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-on-stack-with-literal/3")
 4043     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-on-stack-with-literal/4")
 4044     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-on-stack-with-literal/5")
 4045     # var arr
 4046     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x0000000c)"          "F - test-convert-index-into-array-on-stack-with-literal/6")
 4047     (check-next-stream-line-equal _test-output-stream "    68/push 0x0000000c/imm32"                "F - test-convert-index-into-array-on-stack-with-literal/7")
 4048     # var x
 4049     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-on-stack-with-literal/8")
 4050     # x is at (ebp-0x10) + 4 + 2*4 = ebp-4
 4051     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp + 0xfffffffc) 0x00000000/r32"  "F - test-convert-index-into-array-on-stack-with-literal/9")
 4052     # reclaim x
 4053     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-on-stack-with-literal/10")
 4054     # reclaim arr
 4055     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000010/imm32"    "F - test-convert-index-into-array-on-stack-with-literal/11")
 4056     #
 4057     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-on-stack-with-literal/12")
 4058     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-on-stack-with-literal/13")
 4059     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-on-stack-with-literal/14")
 4060     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-on-stack-with-literal/15")
 4061     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-on-stack-with-literal/16")
 4062     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-on-stack-with-literal/17")
 4063     # . epilogue
 4064     89/<- %esp 5/r32/ebp
 4065     5d/pop-to-ebp
 4066     c3/return
 4067 
 4068 test-convert-index-into-array-of-bytes-on-stack-with-literal:
 4069     # . prologue
 4070     55/push-ebp
 4071     89/<- %ebp 4/r32/esp
 4072     # setup
 4073     (clear-stream _test-input-stream)
 4074     (clear-stream $_test-input-buffered-file->buffer)
 4075     (clear-stream _test-output-stream)
 4076     (clear-stream $_test-output-buffered-file->buffer)
 4077     #
 4078     (write _test-input-stream "fn foo {\n")
 4079     (write _test-input-stream "  var arr: (array byte 3)\n")
 4080     (write _test-input-stream "  var x/eax: (addr byte) <- index arr, 2\n")
 4081     (write _test-input-stream "}\n")
 4082     # convert
 4083     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4084     (flush _test-output-buffered-file)
 4085 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4091     # check output
 4092     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/0")
 4093     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/1")
 4094     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/2")
 4095     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/3")
 4096     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/4")
 4097     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/5")
 4098     # var arr
 4099     (check-next-stream-line-equal _test-output-stream "    (push-n-zero-bytes 0x00000003)"          "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/6")
 4100     (check-next-stream-line-equal _test-output-stream "    68/push 0x00000003/imm32"                "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/7")
 4101     # var x
 4102     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/8")
 4103     # x is at (ebp-7) + 4 + 2 = ebp-1
 4104     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp + 0xffffffff) 0x00000000/r32"  "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/9")
 4105     # reclaim x
 4106     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/10")
 4107     # reclaim arr
 4108     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000007/imm32"    "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/11")
 4109     #
 4110     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/12")
 4111     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/13")
 4112     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/14")
 4113     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/15")
 4114     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/16")
 4115     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-of-bytes-on-stack-with-literal/17")
 4116     # . epilogue
 4117     89/<- %esp 5/r32/ebp
 4118     5d/pop-to-ebp
 4119     c3/return
 4120 
 4121 test-convert-index-into-array-using-offset:
 4122     # . prologue
 4123     55/push-ebp
 4124     89/<- %ebp 4/r32/esp
 4125     # setup
 4126     (clear-stream _test-input-stream)
 4127     (clear-stream $_test-input-buffered-file->buffer)
 4128     (clear-stream _test-output-stream)
 4129     (clear-stream $_test-output-buffered-file->buffer)
 4130     #
 4131     (write _test-input-stream "fn foo {\n")
 4132     (write _test-input-stream "  var arr/eax: (addr array int) <- copy 0\n")
 4133     (write _test-input-stream "  var idx/ecx: int <- copy 3\n")
 4134     (write _test-input-stream "  var off/ecx: (offset int) <- compute-offset arr, idx\n")
 4135     (write _test-input-stream "  var x/eax: (addr int) <- index arr, off\n")
 4136     (write _test-input-stream "}\n")
 4137     # convert
 4138     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4139     (flush _test-output-buffered-file)
 4140 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4146     # check output
 4147     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-using-offset/0")
 4148     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-using-offset/1")
 4149     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-using-offset/2")
 4150     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-using-offset/3")
 4151     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-using-offset/4")
 4152     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-using-offset/5")
 4153     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-using-offset/6")
 4154     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-using-offset/7")
 4155     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array-using-offset/8")
 4156     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"                  "F - test-convert-index-into-array-using-offset/9")
 4157     (check-next-stream-line-equal _test-output-stream "    69/multiply %ecx 0x00000004/imm32 0x00000001/r32"  "F - test-convert-index-into-array-using-offset/10")
 4158     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx + 4) 0x00000000/r32"  "F - test-convert-index-into-array-using-offset/11")
 4159     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array-using-offset/12")
 4160     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-using-offset/13")
 4161     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-using-offset/14")
 4162     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-using-offset/15")
 4163     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-using-offset/16")
 4164     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-using-offset/17")
 4165     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-using-offset/18")
 4166     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-using-offset/19")
 4167     # . epilogue
 4168     89/<- %esp 5/r32/ebp
 4169     5d/pop-to-ebp
 4170     c3/return
 4171 
 4172 test-convert-index-into-array-of-bytes-using-offset:
 4173     # . prologue
 4174     55/push-ebp
 4175     89/<- %ebp 4/r32/esp
 4176     # setup
 4177     (clear-stream _test-input-stream)
 4178     (clear-stream $_test-input-buffered-file->buffer)
 4179     (clear-stream _test-output-stream)
 4180     (clear-stream $_test-output-buffered-file->buffer)
 4181     #
 4182     (write _test-input-stream "fn foo {\n")
 4183     (write _test-input-stream "  var arr/eax: (addr array byte) <- copy 0\n")
 4184     (write _test-input-stream "  var idx/ecx: int <- copy 3\n")
 4185     (write _test-input-stream "  var off/ecx: (offset byte) <- compute-offset arr, idx\n")
 4186     (write _test-input-stream "  var x/eax: (addr byte) <- index arr, off\n")
 4187     (write _test-input-stream "}\n")
 4188     # convert
 4189     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4190     (flush _test-output-buffered-file)
 4191 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4197     # check output
 4198     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-of-bytes-using-offset/0")
 4199     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-of-bytes-using-offset/1")
 4200     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-of-bytes-using-offset/2")
 4201     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-of-bytes-using-offset/3")
 4202     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-of-bytes-using-offset/4")
 4203     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-of-bytes-using-offset/5")
 4204     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-of-bytes-using-offset/6")
 4205     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-of-bytes-using-offset/7")
 4206     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array-of-bytes-using-offset/8")
 4207     (check-next-stream-line-equal _test-output-stream "    b9/copy-to-ecx 3/imm32"                  "F - test-convert-index-into-array-of-bytes-using-offset/9")
 4208     (check-next-stream-line-equal _test-output-stream "    69/multiply %ecx 0x00000001/imm32 0x00000001/r32"  "F - test-convert-index-into-array-of-bytes-using-offset/10")
 4209     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx + 4) 0x00000000/r32"  "F - test-convert-index-into-array-of-bytes-using-offset/11")
 4210     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array-of-bytes-using-offset/12")
 4211     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-of-bytes-using-offset/13")
 4212     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-of-bytes-using-offset/14")
 4213     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-of-bytes-using-offset/15")
 4214     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-of-bytes-using-offset/16")
 4215     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-of-bytes-using-offset/17")
 4216     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-of-bytes-using-offset/18")
 4217     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-of-bytes-using-offset/19")
 4218     # . epilogue
 4219     89/<- %esp 5/r32/ebp
 4220     5d/pop-to-ebp
 4221     c3/return
 4222 
 4223 test-convert-index-into-array-using-offset-on-stack:
 4224     # . prologue
 4225     55/push-ebp
 4226     89/<- %ebp 4/r32/esp
 4227     # setup
 4228     (clear-stream _test-input-stream)
 4229     (clear-stream $_test-input-buffered-file->buffer)
 4230     (clear-stream _test-output-stream)
 4231     (clear-stream $_test-output-buffered-file->buffer)
 4232     #
 4233     (write _test-input-stream "fn foo {\n")
 4234     (write _test-input-stream "  var arr/eax: (addr array int) <- copy 0\n")
 4235     (write _test-input-stream "  var idx: int\n")
 4236     (write _test-input-stream "  var off/ecx: (offset int) <- compute-offset arr, idx\n")
 4237     (write _test-input-stream "  var x/eax: (addr int) <- index arr, off\n")
 4238     (write _test-input-stream "}\n")
 4239     # convert
 4240     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4241     (flush _test-output-buffered-file)
 4242 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4248     # check output
 4249     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-using-offset-on-stack/0")
 4250     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-using-offset-on-stack/1")
 4251     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-using-offset-on-stack/2")
 4252     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-using-offset-on-stack/3")
 4253     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-using-offset-on-stack/4")
 4254     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-using-offset-on-stack/5")
 4255     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-using-offset-on-stack/6")
 4256     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-using-offset-on-stack/7")
 4257     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"                         "F - test-convert-index-into-array-using-offset-on-stack/8")
 4258     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array-using-offset-on-stack/9")
 4259     (check-next-stream-line-equal _test-output-stream "    69/multiply *(ebp+0xfffffff8) 0x00000004/imm32 0x00000001/r32"  "F - test-convert-index-into-array-using-offset-on-stack/10")
 4260     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx + 4) 0x00000000/r32"  "F - test-convert-index-into-array-using-offset-on-stack/11")
 4261     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array-using-offset-on-stack/12")
 4262     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"    "F - test-convert-index-into-array-using-offset-on-stack/13")
 4263     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-using-offset-on-stack/14")
 4264     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-using-offset-on-stack/15")
 4265     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-using-offset-on-stack/16")
 4266     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-using-offset-on-stack/17")
 4267     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-using-offset-on-stack/18")
 4268     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-using-offset-on-stack/19")
 4269     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-using-offset-on-stack/20")
 4270     # . epilogue
 4271     89/<- %esp 5/r32/ebp
 4272     5d/pop-to-ebp
 4273     c3/return
 4274 
 4275 test-convert-index-into-array-of-bytes-using-offset-on-stack:
 4276     # . prologue
 4277     55/push-ebp
 4278     89/<- %ebp 4/r32/esp
 4279     # setup
 4280     (clear-stream _test-input-stream)
 4281     (clear-stream $_test-input-buffered-file->buffer)
 4282     (clear-stream _test-output-stream)
 4283     (clear-stream $_test-output-buffered-file->buffer)
 4284     #
 4285     (write _test-input-stream "fn foo {\n")
 4286     (write _test-input-stream "  var arr/eax: (addr array byte) <- copy 0\n")
 4287     (write _test-input-stream "  var idx: int\n")
 4288     (write _test-input-stream "  var off/ecx: (offset byte) <- compute-offset arr, idx\n")
 4289     (write _test-input-stream "  var x/eax: (addr byte) <- index arr, off\n")
 4290     (write _test-input-stream "}\n")
 4291     # convert
 4292     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4293     (flush _test-output-buffered-file)
 4294 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4300     # check output
 4301     (check-next-stream-line-equal _test-output-stream "foo:"                                        "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/0")
 4302     (check-next-stream-line-equal _test-output-stream "  # . prologue"                              "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/1")
 4303     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"                               "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/2")
 4304     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"                      "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/3")
 4305     (check-next-stream-line-equal _test-output-stream "  {"                                         "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/4")
 4306     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"                       "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/5")
 4307     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"                    "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/6")
 4308     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"                  "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/7")
 4309     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"                         "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/8")
 4310     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"                    "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/9")
 4311     (check-next-stream-line-equal _test-output-stream "    69/multiply *(ebp+0xfffffff8) 0x00000001/imm32 0x00000001/r32"  "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/10")
 4312     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + ecx + 4) 0x00000000/r32"  "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/11")
 4313     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx"                     "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/12")
 4314     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000004/imm32"    "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/13")
 4315     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax"                     "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/14")
 4316     (check-next-stream-line-equal _test-output-stream "  }"                                         "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/15")
 4317     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"                      "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/16")
 4318     (check-next-stream-line-equal _test-output-stream "  # . epilogue"                              "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/17")
 4319     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"                      "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/18")
 4320     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"                             "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/19")
 4321     (check-next-stream-line-equal _test-output-stream "  c3/return"                                 "F - test-convert-index-into-array-of-bytes-using-offset-on-stack/20")
 4322     # . epilogue
 4323     89/<- %esp 5/r32/ebp
 4324     5d/pop-to-ebp
 4325     c3/return
 4326 
 4327 test-convert-function-and-type-definition:
 4328     # . prologue
 4329     55/push-ebp
 4330     89/<- %ebp 4/r32/esp
 4331     # setup
 4332     (clear-stream _test-input-stream)
 4333     (clear-stream $_test-input-buffered-file->buffer)
 4334     (clear-stream _test-output-stream)
 4335     (clear-stream $_test-output-buffered-file->buffer)
 4336     #
 4337     (write _test-input-stream "fn foo a: (addr t) {\n")
 4338     (write _test-input-stream "  var _a/eax: (addr t) <- copy a\n")
 4339     (write _test-input-stream "  var b/ecx: (addr int) <- get _a, x\n")
 4340     (write _test-input-stream "  var c/ecx: (addr int) <- get _a, y\n")
 4341     (write _test-input-stream "}\n")
 4342     (write _test-input-stream "type t {\n")
 4343     (write _test-input-stream "  x: int\n")
 4344     (write _test-input-stream "  y: int\n")
 4345     (write _test-input-stream "}\n")
 4346     # convert
 4347     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4348     (flush _test-output-buffered-file)
 4349 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4355     # check output
 4356     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-and-type-definition/0")
 4357     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-and-type-definition/1")
 4358     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-and-type-definition/2")
 4359     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-and-type-definition/3")
 4360     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-and-type-definition/4")
 4361     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-and-type-definition/5")
 4362     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-function-and-type-definition/6")
 4363     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000000/r32"  "F - test-convert-function-and-type-definition/7")
 4364     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-and-type-definition/8")
 4365     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000000) 0x00000001/r32"  "F - test-convert-function-and-type-definition/9")
 4366     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(eax + 0x00000004) 0x00000001/r32"  "F - test-convert-function-and-type-definition/11")
 4367     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-and-type-definition/13")
 4368     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-function-and-type-definition/14")
 4369     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-and-type-definition/15")
 4370     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-and-type-definition/16")
 4371     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-and-type-definition/17")
 4372     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-and-type-definition/18")
 4373     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-and-type-definition/19")
 4374     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-and-type-definition/20")
 4375     # . epilogue
 4376     89/<- %esp 5/r32/ebp
 4377     5d/pop-to-ebp
 4378     c3/return
 4379 
 4380 test-convert-function-with-local-var-with-user-defined-type:
 4381     # . prologue
 4382     55/push-ebp
 4383     89/<- %ebp 4/r32/esp
 4384     # setup
 4385     (clear-stream _test-input-stream)
 4386     (clear-stream $_test-input-buffered-file->buffer)
 4387     (clear-stream _test-output-stream)
 4388     (clear-stream $_test-output-buffered-file->buffer)
 4389     #
 4390     (write _test-input-stream "fn foo {\n")
 4391     (write _test-input-stream "  var a: t\n")
 4392     (write _test-input-stream "}\n")
 4393     (write _test-input-stream "type t {\n")
 4394     (write _test-input-stream "  x: int\n")
 4395     (write _test-input-stream "  y: int\n")
 4396     (write _test-input-stream "}\n")
 4397     # convert
 4398     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4399     (flush _test-output-buffered-file)
 4400 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4406     # check output
 4407     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-with-local-var-with-user-defined-type/0")
 4408     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-with-local-var-with-user-defined-type/1")
 4409     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-with-local-var-with-user-defined-type/2")
 4410     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-with-local-var-with-user-defined-type/3")
 4411     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-with-local-var-with-user-defined-type/4")
 4412     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-function-with-local-var-with-user-defined-type/5")
 4413     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-with-local-var-with-user-defined-type/6")
 4414     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-with-local-var-with-user-defined-type/7")
 4415     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000008/imm32"  "F - test-convert-function-with-local-var-with-user-defined-type/8")
 4416     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-with-local-var-with-user-defined-type/9")
 4417     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-function-with-local-var-with-user-defined-type/10")
 4418     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-with-local-var-with-user-defined-type/11")
 4419     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-with-local-var-with-user-defined-type/12")
 4420     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-with-local-var-with-user-defined-type/13")
 4421     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-with-local-var-with-user-defined-type/14")
 4422     # . epilogue
 4423     89/<- %esp 5/r32/ebp
 4424     5d/pop-to-ebp
 4425     c3/return
 4426 
 4427 test-convert-function-call-with-arg-of-user-defined-type:
 4428     # . prologue
 4429     55/push-ebp
 4430     89/<- %ebp 4/r32/esp
 4431     # setup
 4432     (clear-stream _test-input-stream)
 4433     (clear-stream $_test-input-buffered-file->buffer)
 4434     (clear-stream _test-output-stream)
 4435     (clear-stream $_test-output-buffered-file->buffer)
 4436     #
 4437     (write _test-input-stream "fn f {\n")
 4438     (write _test-input-stream "  var a: t\n")
 4439     (write _test-input-stream "  foo a\n")
 4440     (write _test-input-stream "}\n")
 4441     (write _test-input-stream "fn foo x: t {\n")
 4442     (write _test-input-stream "}\n")
 4443     (write _test-input-stream "type t {\n")
 4444     (write _test-input-stream "  x: int\n")
 4445     (write _test-input-stream "  y: int\n")
 4446     (write _test-input-stream "}\n")
 4447     # convert
 4448     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4449     (flush _test-output-buffered-file)
 4450 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4456     # check output
 4457     (check-next-stream-line-equal _test-output-stream "f:"                      "F - test-convert-function-call-with-arg-of-user-defined-type/0")
 4458     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type/1")
 4459     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type/2")
 4460     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type/3")
 4461     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-arg-of-user-defined-type/4")
 4462     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:"     "F - test-convert-function-call-with-arg-of-user-defined-type/5")
 4463     # var a: t
 4464     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-call-with-arg-of-user-defined-type/6")
 4465     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-call-with-arg-of-user-defined-type/7")
 4466     # foo a
 4467     (check-next-stream-line-equal _test-output-stream "    (foo *(ebp+0xfffffff8) *(ebp+0xfffffffc))"  "F - test-convert-function-call-with-arg-of-user-defined-type/8")
 4468     #
 4469     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000008/imm32"  "F - test-convert-function-call-with-arg-of-user-defined-type/9")
 4470     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-arg-of-user-defined-type/10")
 4471     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:"    "F - test-convert-function-call-with-arg-of-user-defined-type/11")
 4472     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type/12")
 4473     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type/13")
 4474     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type/14")
 4475     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type/15")
 4476     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-call-with-arg-of-user-defined-type/16")
 4477     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type/17")
 4478     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type/18")
 4479     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type/19")
 4480     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type/20")
 4481     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type/21")
 4482     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type/22")
 4483     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type/23")
 4484     # . epilogue
 4485     89/<- %esp 5/r32/ebp
 4486     5d/pop-to-ebp
 4487     c3/return
 4488 
 4489 test-convert-function-call-with-arg-of-user-defined-type-register-indirect:
 4490     # . prologue
 4491     55/push-ebp
 4492     89/<- %ebp 4/r32/esp
 4493     # setup
 4494     (clear-stream _test-input-stream)
 4495     (clear-stream $_test-input-buffered-file->buffer)
 4496     (clear-stream _test-output-stream)
 4497     (clear-stream $_test-output-buffered-file->buffer)
 4498     #
 4499     (write _test-input-stream "fn f {\n")
 4500     (write _test-input-stream "  var a/eax: (addr t) <- copy 0\n")
 4501     (write _test-input-stream "  foo *a\n")
 4502     (write _test-input-stream "}\n")
 4503     (write _test-input-stream "fn foo x: t {\n")
 4504     (write _test-input-stream "}\n")
 4505     (write _test-input-stream "type t {\n")
 4506     (write _test-input-stream "  x: int\n")
 4507     (write _test-input-stream "  y: int\n")
 4508     (write _test-input-stream "}\n")
 4509     # convert
 4510     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4511     (flush _test-output-buffered-file)
 4512 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4518     # check output
 4519     (check-next-stream-line-equal _test-output-stream "f:"                      "F - test-convert-function-call-with-arg-of-user-defined-type/0")
 4520     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type/1")
 4521     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type/2")
 4522     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type/3")
 4523     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-arg-of-user-defined-type/4")
 4524     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:"     "F - test-convert-function-call-with-arg-of-user-defined-type/5")
 4525     # var a
 4526     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-function-call-with-arg-of-user-defined-type/6")
 4527     (check-next-stream-line-equal _test-output-stream "    b8/copy-to-eax 0/imm32"  "F - test-convert-function-call-with-arg-of-user-defined-type/7")
 4528     # foo a
 4529     (check-next-stream-line-equal _test-output-stream "    (foo *(eax+0x00000000) *(eax+0x00000004))"  "F - test-convert-function-call-with-arg-of-user-defined-type/8")
 4530     #
 4531     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type/9")
 4532     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-arg-of-user-defined-type/10")
 4533     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:"    "F - test-convert-function-call-with-arg-of-user-defined-type/11")
 4534     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type/12")
 4535     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type/13")
 4536     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type/14")
 4537     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type/15")
 4538     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-call-with-arg-of-user-defined-type/16")
 4539     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type/17")
 4540     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type/18")
 4541     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type/19")
 4542     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type/20")
 4543     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type/21")
 4544     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type/22")
 4545     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type/23")
 4546     # . epilogue
 4547     89/<- %esp 5/r32/ebp
 4548     5d/pop-to-ebp
 4549     c3/return
 4550 
 4551 # we don't have special support for call-by-reference; just explicitly create
 4552 # a new variable with the address of the arg
 4553 test-convert-function-call-with-arg-of-user-defined-type-by-reference:
 4554     # . prologue
 4555     55/push-ebp
 4556     89/<- %ebp 4/r32/esp
 4557     # setup
 4558     (clear-stream _test-input-stream)
 4559     (clear-stream $_test-input-buffered-file->buffer)
 4560     (clear-stream _test-output-stream)
 4561     (clear-stream $_test-output-buffered-file->buffer)
 4562     #
 4563     (write _test-input-stream "fn f {\n")
 4564     (write _test-input-stream "  var a: t\n")
 4565     (write _test-input-stream "  var b/eax: (addr t) <- address a\n")
 4566     (write _test-input-stream "  foo b\n")
 4567     (write _test-input-stream "}\n")
 4568     (write _test-input-stream "fn foo x: (addr t) {\n")
 4569     (write _test-input-stream "  var x/ecx: (addr int) <- copy x\n")
 4570     (write _test-input-stream "  increment *x\n")
 4571     (write _test-input-stream "}\n")
 4572     (write _test-input-stream "type t {\n")
 4573     (write _test-input-stream "  x: int\n")
 4574     (write _test-input-stream "  y: int\n")
 4575     (write _test-input-stream "}\n")
 4576     # convert
 4577     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4578     (flush _test-output-buffered-file)
 4579 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4585     # check output
 4586     (check-next-stream-line-equal _test-output-stream "f:"                      "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/0")
 4587     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/1")
 4588     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/2")
 4589     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/3")
 4590     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/4")
 4591     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:loop:"     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/5")
 4592     # var a: t
 4593     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/6")
 4594     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/7")
 4595     # var b/eax: (addr t)
 4596     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %eax"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/8")
 4597     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp+0xfffffff8) 0x00000000/r32"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/9")
 4598     # foo a
 4599     (check-next-stream-line-equal _test-output-stream "    (foo %eax)"          "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/10")
 4600     #
 4601     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %eax" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/11")
 4602     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000008/imm32"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/12")
 4603     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/13")
 4604     (check-next-stream-line-equal _test-output-stream "$f:0x00000001:break:"    "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/14")
 4605     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/15")
 4606     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/16")
 4607     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/17")
 4608     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/18")
 4609     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/19")
 4610     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/20")
 4611     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/21")
 4612     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/22")
 4613     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/23")
 4614     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:loop:"   "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/24")
 4615     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/25")
 4616     (check-next-stream-line-equal _test-output-stream "    8b/-> *(ebp+0x00000008) 0x00000001/r32"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/26")
 4617     (check-next-stream-line-equal _test-output-stream "    ff 0/subop/increment *ecx"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/27")
 4618     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/28")
 4619     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/29")
 4620     (check-next-stream-line-equal _test-output-stream "$foo:0x00000002:break:"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/30")
 4621     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/31")
 4622     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/32")
 4623     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/33")
 4624     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-function-call-with-arg-of-user-defined-type-by-reference/34")
 4625     # . epilogue
 4626     89/<- %esp 5/r32/ebp
 4627     5d/pop-to-ebp
 4628     c3/return
 4629 
 4630 test-convert-get-on-local-variable:
 4631     # . prologue
 4632     55/push-ebp
 4633     89/<- %ebp 4/r32/esp
 4634     # setup
 4635     (clear-stream _test-input-stream)
 4636     (clear-stream $_test-input-buffered-file->buffer)
 4637     (clear-stream _test-output-stream)
 4638     (clear-stream $_test-output-buffered-file->buffer)
 4639     #
 4640     (write _test-input-stream "fn foo {\n")
 4641     (write _test-input-stream "  var a: t\n")
 4642     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 4643     (write _test-input-stream "}\n")
 4644     (write _test-input-stream "type t {\n")
 4645     (write _test-input-stream "  x: int\n")
 4646     (write _test-input-stream "  y: int\n")
 4647     (write _test-input-stream "}\n")
 4648     # convert
 4649     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4650     (flush _test-output-buffered-file)
 4651 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4657     # check output
 4658     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-get-on-local-variable/0")
 4659     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-get-on-local-variable/1")
 4660     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-get-on-local-variable/2")
 4661     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-get-on-local-variable/3")
 4662     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-get-on-local-variable/4")
 4663     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-get-on-local-variable/5")
 4664     # var a
 4665     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-get-on-local-variable/6")
 4666     (check-next-stream-line-equal _test-output-stream "    68/push 0/imm32"     "F - test-convert-get-on-local-variable/7")
 4667     # var c
 4668     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-get-on-local-variable/8")
 4669     # get
 4670     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp+0xfffffffc) 0x00000001/r32"  "F - test-convert-get-on-local-variable/9")
 4671     # reclaim c
 4672     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-get-on-local-variable/10")
 4673     # reclaim a
 4674     (check-next-stream-line-equal _test-output-stream "    81 0/subop/add %esp 0x00000008/imm32"  "F - test-convert-get-on-local-variable/11")
 4675     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-get-on-local-variable/12")
 4676     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-get-on-local-variable/13")
 4677     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-get-on-local-variable/14")
 4678     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-get-on-local-variable/15")
 4679     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-get-on-local-variable/16")
 4680     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-get-on-local-variable/17")
 4681     # . epilogue
 4682     89/<- %esp 5/r32/ebp
 4683     5d/pop-to-ebp
 4684     c3/return
 4685 
 4686 test-convert-get-on-function-argument:
 4687     # . prologue
 4688     55/push-ebp
 4689     89/<- %ebp 4/r32/esp
 4690     # setup
 4691     (clear-stream _test-input-stream)
 4692     (clear-stream $_test-input-buffered-file->buffer)
 4693     (clear-stream _test-output-stream)
 4694     (clear-stream $_test-output-buffered-file->buffer)
 4695     #
 4696     (write _test-input-stream "fn foo a: t {\n")
 4697     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 4698     (write _test-input-stream "}\n")
 4699     (write _test-input-stream "type t {\n")
 4700     (write _test-input-stream "  x: int\n")
 4701     (write _test-input-stream "  y: int\n")
 4702     (write _test-input-stream "}\n")
 4703     # convert
 4704     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4705     (flush _test-output-buffered-file)
 4706 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4712     # check output
 4713     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-get-on-function-argument/0")
 4714     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-get-on-function-argument/1")
 4715     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-get-on-function-argument/2")
 4716     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-get-on-function-argument/3")
 4717     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-get-on-function-argument/4")
 4718     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-get-on-function-argument/5")
 4719     # var c
 4720     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-get-on-function-argument/6")
 4721     # get
 4722     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp+0x0000000c) 0x00000001/r32"  "F - test-convert-get-on-function-argument/7")
 4723     # reclaim c
 4724     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument/8")
 4725     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-get-on-function-argument/9")
 4726     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-get-on-function-argument/10")
 4727     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-get-on-function-argument/11")
 4728     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-get-on-function-argument/12")
 4729     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-get-on-function-argument/13")
 4730     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-get-on-function-argument/14")
 4731     # . epilogue
 4732     89/<- %esp 5/r32/ebp
 4733     5d/pop-to-ebp
 4734     c3/return
 4735 
 4736 test-convert-get-on-function-argument-with-known-type:
 4737     # . prologue
 4738     55/push-ebp
 4739     89/<- %ebp 4/r32/esp
 4740     # setup
 4741     (clear-stream _test-input-stream)
 4742     (clear-stream $_test-input-buffered-file->buffer)
 4743     (clear-stream _test-output-stream)
 4744     (clear-stream $_test-output-buffered-file->buffer)
 4745     #
 4746     (write _test-input-stream "type t {\n")
 4747     (write _test-input-stream "  x: int\n")
 4748     (write _test-input-stream "  y: int\n")
 4749     (write _test-input-stream "}\n")
 4750     (write _test-input-stream "fn foo a: t {\n")
 4751     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 4752     (write _test-input-stream "}\n")
 4753     # convert
 4754     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4755     (flush _test-output-buffered-file)
 4756 +--  6 lines: #?     # dump _test-output-stream -----------------------------------------------------------------------------------------------------------------------------------------
 4762     # check output
 4763     (check-next-stream-line-equal _test-output-stream "foo:"                    "F - test-convert-get-on-function-argument-with-known-type/0")
 4764     (check-next-stream-line-equal _test-output-stream "  # . prologue"          "F - test-convert-get-on-function-argument-with-known-type/1")
 4765     (check-next-stream-line-equal _test-output-stream "  55/push-ebp"           "F - test-convert-get-on-function-argument-with-known-type/2")
 4766     (check-next-stream-line-equal _test-output-stream "  89/<- %ebp 4/r32/esp"  "F - test-convert-get-on-function-argument-with-known-type/3")
 4767     (check-next-stream-line-equal _test-output-stream "  {"                     "F - test-convert-get-on-function-argument-with-known-type/4")
 4768     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:loop:"   "F - test-convert-get-on-function-argument-with-known-type/5")
 4769     # var c
 4770     (check-next-stream-line-equal _test-output-stream "    ff 6/subop/push %ecx"  "F - test-convert-get-on-function-argument-with-known-type/6")
 4771     # get
 4772     (check-next-stream-line-equal _test-output-stream "    8d/copy-address *(ebp+0x0000000c) 0x00000001/r32"  "F - test-convert-get-on-function-argument-with-known-type/7")
 4773     # reclaim c
 4774     (check-next-stream-line-equal _test-output-stream "    8f 0/subop/pop %ecx" "F - test-convert-get-on-function-argument-with-known-type/8")
 4775     (check-next-stream-line-equal _test-output-stream "  }"                     "F - test-convert-get-on-function-argument-with-known-type/9")
 4776     (check-next-stream-line-equal _test-output-stream "$foo:0x00000001:break:"  "F - test-convert-get-on-function-argument-with-known-type/10")
 4777     (check-next-stream-line-equal _test-output-stream "  # . epilogue"          "F - test-convert-get-on-function-argument-with-known-type/11")
 4778     (check-next-stream-line-equal _test-output-stream "  89/<- %esp 5/r32/ebp"  "F - test-convert-get-on-function-argument-with-known-type/12")
 4779     (check-next-stream-line-equal _test-output-stream "  5d/pop-to-ebp"         "F - test-convert-get-on-function-argument-with-known-type/13")
 4780     (check-next-stream-line-equal _test-output-stream "  c3/return"             "F - test-convert-get-on-function-argument-with-known-type/14")
 4781     # . epilogue
 4782     89/<- %esp 5/r32/ebp
 4783     5d/pop-to-ebp
 4784     c3/return
 4785 
 4786 test-add-with-too-many-inouts:
 4787     # . prologue
 4788     55/push-ebp
 4789     89/<- %ebp 4/r32/esp
 4790     # setup
 4791     (clear-stream _test-input-stream)
 4792     (clear-stream $_test-input-buffered-file->buffer)
 4793     (clear-stream _test-output-stream)
 4794     (clear-stream $_test-output-buffered-file->buffer)
 4795     (clear-stream _test-error-stream)
 4796     (clear-stream $_test-error-buffered-file->buffer)
 4797     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 4798     68/push 0/imm32
 4799     68/push 0/imm32
 4800     89/<- %edx 4/r32/esp
 4801     (tailor-exit-descriptor %edx 0x10)
 4802     #
 4803     (write _test-input-stream "fn foo {\n")
 4804     (write _test-input-stream "  var a: int\n")
 4805     (write _test-input-stream "  var b/ecx: int <- add a, 0\n")
 4806     (write _test-input-stream "}\n")
 4807     # convert
 4808     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 4809     # registers except esp clobbered at this point
 4810     # restore ed
 4811     89/<- %edx 4/r32/esp
 4812     (flush _test-output-buffered-file)
 4813     (flush _test-error-buffered-file)
 4814 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 4820     # check output
 4821     (check-stream-equal _test-output-stream  ""  "F - test-add-with-too-many-inouts: output should be empty")
 4822     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt add: too many inouts; most primitives support at most two arguments, across inouts and outputs"  "F - test-add-with-too-many-inouts: error message")
 4823     # check that stop(1) was called
 4824     (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts: exit status")
 4825     # don't restore from ebp
 4826     81 0/subop/add %esp 8/imm32
 4827     # . epilogue
 4828     5d/pop-to-ebp
 4829     c3/return
 4830 
 4831 test-add-with-too-many-inouts-2:
 4832     # . prologue
 4833     55/push-ebp
 4834     89/<- %ebp 4/r32/esp
 4835     # setup
 4836     (clear-stream _test-input-stream)
 4837     (clear-stream $_test-input-buffered-file->buffer)
 4838     (clear-stream _test-output-stream)
 4839     (clear-stream $_test-output-buffered-file->buffer)
 4840     (clear-stream _test-error-stream)
 4841     (clear-stream $_test-error-buffered-file->buffer)
 4842     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 4843     68/push 0/imm32
 4844     68/push 0/imm32
 4845     89/<- %edx 4/r32/esp
 4846     (tailor-exit-descriptor %edx 0x10)
 4847     #
 4848     (write _test-input-stream "fn foo {\n")
 4849     (write _test-input-stream "  var a: int\n")
 4850     (write _test-input-stream "  add-to a, 0, 1\n")
 4851     (write _test-input-stream "}\n")
 4852     # convert
 4853     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 4854     # registers except esp clobbered at this point
 4855     # restore ed
 4856     89/<- %edx 4/r32/esp
 4857     (flush _test-output-buffered-file)
 4858     (flush _test-error-buffered-file)
 4859 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 4865     # check output
 4866     (check-stream-equal _test-output-stream  ""  "F - test-add-with-too-many-inouts-2: output should be empty")
 4867     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt add-to: too many inouts; most primitives support at most two arguments, across inouts and outputs"  "F - test-add-with-too-many-inouts-2: error message")
 4868     # check that stop(1) was called
 4869     (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-inouts-2: exit status")
 4870     # don't restore from ebp
 4871     81 0/subop/add %esp 8/imm32
 4872     # . epilogue
 4873     5d/pop-to-ebp
 4874     c3/return
 4875 
 4876 test-add-with-too-many-outputs:
 4877     # . prologue
 4878     55/push-ebp
 4879     89/<- %ebp 4/r32/esp
 4880     # setup
 4881     (clear-stream _test-input-stream)
 4882     (clear-stream $_test-input-buffered-file->buffer)
 4883     (clear-stream _test-output-stream)
 4884     (clear-stream $_test-output-buffered-file->buffer)
 4885     (clear-stream _test-error-stream)
 4886     (clear-stream $_test-error-buffered-file->buffer)
 4887     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 4888     68/push 0/imm32
 4889     68/push 0/imm32
 4890     89/<- %edx 4/r32/esp
 4891     (tailor-exit-descriptor %edx 0x10)
 4892     #
 4893     (write _test-input-stream "fn foo {\n")
 4894     (write _test-input-stream "  var a/eax: int <- copy 0\n")
 4895     (write _test-input-stream "  var b/ebx: int <- copy 0\n")
 4896     (write _test-input-stream "  var c/ecx: int <- copy 0\n")
 4897     (write _test-input-stream "  c, b <- add a\n")
 4898     (write _test-input-stream "}\n")
 4899     # convert
 4900     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 4901     # registers except esp clobbered at this point
 4902     # restore ed
 4903     89/<- %edx 4/r32/esp
 4904     (flush _test-output-buffered-file)
 4905     (flush _test-error-buffered-file)
 4906 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 4912     # check output
 4913     (check-stream-equal _test-output-stream  ""  "F - test-add-with-too-many-outputs: output should be empty")
 4914     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt add: too many outputs; most primitives support at most one output"  "F - test-add-with-too-many-outputs: error message")
 4915     # check that stop(1) was called
 4916     (check-ints-equal *(edx+4) 2 "F - test-add-with-too-many-outputs: exit status")
 4917     # don't restore from ebp
 4918     81 0/subop/add %esp 8/imm32
 4919     # . epilogue
 4920     5d/pop-to-ebp
 4921     c3/return
 4922 
 4923 test-add-with-non-number:
 4924     # . prologue
 4925     55/push-ebp
 4926     89/<- %ebp 4/r32/esp
 4927     # setup
 4928     (clear-stream _test-input-stream)
 4929     (clear-stream $_test-input-buffered-file->buffer)
 4930     (clear-stream _test-output-stream)
 4931     (clear-stream $_test-output-buffered-file->buffer)
 4932     (clear-stream _test-error-stream)
 4933     (clear-stream $_test-error-buffered-file->buffer)
 4934     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 4935     68/push 0/imm32
 4936     68/push 0/imm32
 4937     89/<- %edx 4/r32/esp
 4938     (tailor-exit-descriptor %edx 0x10)
 4939     #
 4940     (write _test-input-stream "fn foo {\n")
 4941     (write _test-input-stream "  var a: int\n")
 4942     (write _test-input-stream "  var b/ecx: (addr int) <- add a\n")
 4943     (write _test-input-stream "}\n")
 4944     # convert
 4945     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 4946     # registers except esp clobbered at this point
 4947     # restore ed
 4948     89/<- %edx 4/r32/esp
 4949     (flush _test-output-buffered-file)
 4950     (flush _test-error-buffered-file)
 4951 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 4957     # check output
 4958     (check-stream-equal _test-output-stream  ""  "F - test-add-with-non-number: output should be empty")
 4959     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt add: only non-addr scalar args permitted"  "F - test-add-with-non-number: error message")
 4960     # check that stop(1) was called
 4961     (check-ints-equal *(edx+4) 2 "F - test-add-with-non-number: exit status")
 4962     # don't restore from ebp
 4963     81 0/subop/add %esp 8/imm32
 4964     # . epilogue
 4965     5d/pop-to-ebp
 4966     c3/return
 4967 
 4968 test-add-with-addr-dereferenced:
 4969     # . prologue
 4970     55/push-ebp
 4971     89/<- %ebp 4/r32/esp
 4972     # setup
 4973     (clear-stream _test-input-stream)
 4974     (clear-stream $_test-input-buffered-file->buffer)
 4975     (clear-stream _test-output-stream)
 4976     (clear-stream $_test-output-buffered-file->buffer)
 4977     #
 4978     (write _test-input-stream "fn foo {\n")
 4979     (write _test-input-stream "  var a/eax: (addr int) <- copy 0\n")
 4980     (write _test-input-stream "  add-to *a, 1\n")
 4981     (write _test-input-stream "}\n")
 4982     # convert
 4983     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 4984     (flush _test-output-buffered-file)
 4985     # no error
 4986     # . epilogue
 4987     89/<- %esp 5/r32/ebp
 4988     5d/pop-to-ebp
 4989     c3/return
 4990 
 4991 test-get-with-wrong-field:
 4992     # . prologue
 4993     55/push-ebp
 4994     89/<- %ebp 4/r32/esp
 4995     # setup
 4996     (clear-stream _test-input-stream)
 4997     (clear-stream $_test-input-buffered-file->buffer)
 4998     (clear-stream _test-output-stream)
 4999     (clear-stream $_test-output-buffered-file->buffer)
 5000     (clear-stream _test-error-stream)
 5001     (clear-stream $_test-error-buffered-file->buffer)
 5002     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5003     68/push 0/imm32
 5004     68/push 0/imm32
 5005     89/<- %edx 4/r32/esp
 5006     (tailor-exit-descriptor %edx 0x10)
 5007     #
 5008     (write _test-input-stream "fn foo {\n")
 5009     (write _test-input-stream "  var a: t\n")
 5010     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 5011     (write _test-input-stream "}\n")
 5012     (write _test-input-stream "type t {\n")
 5013     (write _test-input-stream "  x: int\n")
 5014     (write _test-input-stream "}\n")
 5015     # convert
 5016     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5017     # registers except esp clobbered at this point
 5018     # restore ed
 5019     89/<- %edx 4/r32/esp
 5020     (flush _test-output-buffered-file)
 5021     (flush _test-error-buffered-file)
 5022 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5028     # check output
 5029     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-field: output should be empty")
 5030     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: type 't' has no member called 'y'"  "F - test-get-with-wrong-field: error message")
 5031     # check that stop(1) was called
 5032     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-field: exit status")
 5033     # don't restore from ebp
 5034     81 0/subop/add %esp 8/imm32
 5035     # . epilogue
 5036     5d/pop-to-ebp
 5037     c3/return
 5038 
 5039 test-get-with-wrong-base-type:
 5040     # . prologue
 5041     55/push-ebp
 5042     89/<- %ebp 4/r32/esp
 5043     # setup
 5044     (clear-stream _test-input-stream)
 5045     (clear-stream $_test-input-buffered-file->buffer)
 5046     (clear-stream _test-output-stream)
 5047     (clear-stream $_test-output-buffered-file->buffer)
 5048     (clear-stream _test-error-stream)
 5049     (clear-stream $_test-error-buffered-file->buffer)
 5050     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5051     68/push 0/imm32
 5052     68/push 0/imm32
 5053     89/<- %edx 4/r32/esp
 5054     (tailor-exit-descriptor %edx 0x10)
 5055     #
 5056     (write _test-input-stream "fn foo {\n")
 5057     (write _test-input-stream "  var a: int\n")
 5058     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 5059     (write _test-input-stream "}\n")
 5060     # convert
 5061     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5062     # registers except esp clobbered at this point
 5063     # restore ed
 5064     89/<- %edx 4/r32/esp
 5065     (flush _test-output-buffered-file)
 5066     (flush _test-error-buffered-file)
 5067 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5073     # check output
 5074     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-base-type: output should be empty")
 5075     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: var 'a' must have a 'type' definition"  "F - test-get-with-wrong-base-type: error message")
 5076     # check that stop(1) was called
 5077     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type: exit status")
 5078     # don't restore from ebp
 5079     81 0/subop/add %esp 8/imm32
 5080     # . epilogue
 5081     5d/pop-to-ebp
 5082     c3/return
 5083 
 5084 test-get-with-wrong-base-type-2:
 5085     # . prologue
 5086     55/push-ebp
 5087     89/<- %ebp 4/r32/esp
 5088     # setup
 5089     (clear-stream _test-input-stream)
 5090     (clear-stream $_test-input-buffered-file->buffer)
 5091     (clear-stream _test-output-stream)
 5092     (clear-stream $_test-output-buffered-file->buffer)
 5093     (clear-stream _test-error-stream)
 5094     (clear-stream $_test-error-buffered-file->buffer)
 5095     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5096     68/push 0/imm32
 5097     68/push 0/imm32
 5098     89/<- %edx 4/r32/esp
 5099     (tailor-exit-descriptor %edx 0x10)
 5100     #
 5101     (write _test-input-stream "fn foo {\n")
 5102     (write _test-input-stream "  var a: (addr t)\n")
 5103     (write _test-input-stream "  var c/ecx: (addr int) <- get a, y\n")
 5104     (write _test-input-stream "}\n")
 5105     (write _test-input-stream "type t {\n")
 5106     (write _test-input-stream "  x: int\n")
 5107     (write _test-input-stream "}\n")
 5108     # convert
 5109     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5110     # registers except esp clobbered at this point
 5111     # restore ed
 5112     89/<- %edx 4/r32/esp
 5113     (flush _test-output-buffered-file)
 5114     (flush _test-error-buffered-file)
 5115 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5121     # check output
 5122     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-base-type-2: output should be empty")
 5123     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: var 'a' is an 'addr' type, and so must live in a register"  "F - test-get-with-wrong-base-type-2: error message")
 5124     # check that stop(1) was called
 5125     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-base-type-2: exit status")
 5126     # don't restore from ebp
 5127     81 0/subop/add %esp 8/imm32
 5128     # . epilogue
 5129     5d/pop-to-ebp
 5130     c3/return
 5131 
 5132 test-get-with-wrong-offset-type:
 5133     # . prologue
 5134     55/push-ebp
 5135     89/<- %ebp 4/r32/esp
 5136     # setup
 5137     (clear-stream _test-input-stream)
 5138     (clear-stream $_test-input-buffered-file->buffer)
 5139     (clear-stream _test-output-stream)
 5140     (clear-stream $_test-output-buffered-file->buffer)
 5141     (clear-stream _test-error-stream)
 5142     (clear-stream $_test-error-buffered-file->buffer)
 5143     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5144     68/push 0/imm32
 5145     68/push 0/imm32
 5146     89/<- %edx 4/r32/esp
 5147     (tailor-exit-descriptor %edx 0x10)
 5148     #
 5149     (write _test-input-stream "fn foo {\n")
 5150     (write _test-input-stream "  var a: t\n")
 5151     (write _test-input-stream "  var b: int\n")
 5152     (write _test-input-stream "  var c/ecx: (addr int) <- get a, b\n")
 5153     (write _test-input-stream "}\n")
 5154     (write _test-input-stream "type t {\n")
 5155     (write _test-input-stream "  x: int\n")
 5156     (write _test-input-stream "}\n")
 5157     # convert
 5158     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5159     # registers except esp clobbered at this point
 5160     # restore ed
 5161     89/<- %edx 4/r32/esp
 5162     (flush _test-output-buffered-file)
 5163     (flush _test-error-buffered-file)
 5164 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5170     # check output
 5171     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-offset-type: output should be empty")
 5172     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: type 't' has no member called 'b'"  "F - test-get-with-wrong-offset-type: error message")
 5173     # check that stop(1) was called
 5174     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-offset-type: exit status")
 5175     # don't restore from ebp
 5176     81 0/subop/add %esp 8/imm32
 5177     # . epilogue
 5178     5d/pop-to-ebp
 5179     c3/return
 5180 
 5181 test-get-with-wrong-output-type:
 5182     # . prologue
 5183     55/push-ebp
 5184     89/<- %ebp 4/r32/esp
 5185     # setup
 5186     (clear-stream _test-input-stream)
 5187     (clear-stream $_test-input-buffered-file->buffer)
 5188     (clear-stream _test-output-stream)
 5189     (clear-stream $_test-output-buffered-file->buffer)
 5190     (clear-stream _test-error-stream)
 5191     (clear-stream $_test-error-buffered-file->buffer)
 5192     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5193     68/push 0/imm32
 5194     68/push 0/imm32
 5195     89/<- %edx 4/r32/esp
 5196     (tailor-exit-descriptor %edx 0x10)
 5197     #
 5198     (write _test-input-stream "fn foo {\n")
 5199     (write _test-input-stream "  var a: t\n")
 5200     (write _test-input-stream "  var c: (addr int)\n")
 5201     (write _test-input-stream "  c <- get a, x\n")
 5202     (write _test-input-stream "}\n")
 5203     (write _test-input-stream "type t {\n")
 5204     (write _test-input-stream "  x: int\n")
 5205     (write _test-input-stream "}\n")
 5206     # convert
 5207     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5208     # registers except esp clobbered at this point
 5209     # restore ed
 5210     89/<- %edx 4/r32/esp
 5211     (flush _test-output-buffered-file)
 5212     (flush _test-error-buffered-file)
 5213 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5219     # check output
 5220     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-output-type: output should be empty")
 5221     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: output 'c' is not in a register"  "F - test-get-with-wrong-output-type: error message")
 5222     # check that stop(1) was called
 5223     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type: exit status")
 5224     # don't restore from ebp
 5225     81 0/subop/add %esp 8/imm32
 5226     # . epilogue
 5227     5d/pop-to-ebp
 5228     c3/return
 5229 
 5230 test-get-with-wrong-output-type-2:
 5231     # . prologue
 5232     55/push-ebp
 5233     89/<- %ebp 4/r32/esp
 5234     # setup
 5235     (clear-stream _test-input-stream)
 5236     (clear-stream $_test-input-buffered-file->buffer)
 5237     (clear-stream _test-output-stream)
 5238     (clear-stream $_test-output-buffered-file->buffer)
 5239     (clear-stream _test-error-stream)
 5240     (clear-stream $_test-error-buffered-file->buffer)
 5241     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5242     68/push 0/imm32
 5243     68/push 0/imm32
 5244     89/<- %edx 4/r32/esp
 5245     (tailor-exit-descriptor %edx 0x10)
 5246     #
 5247     (write _test-input-stream "fn foo {\n")
 5248     (write _test-input-stream "  var a: t\n")
 5249     (write _test-input-stream "  var c/ecx: int <- get a, x\n")
 5250     (write _test-input-stream "}\n")
 5251     (write _test-input-stream "type t {\n")
 5252     (write _test-input-stream "  x: int\n")
 5253     (write _test-input-stream "}\n")
 5254     # convert
 5255     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5256     # registers except esp clobbered at this point
 5257     # restore ed
 5258     89/<- %edx 4/r32/esp
 5259     (flush _test-output-buffered-file)
 5260     (flush _test-error-buffered-file)
 5261 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5267     # check output
 5268     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-output-type-2: output should be empty")
 5269     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: output must be an address"  "F - test-get-with-wrong-output-type-2: error message")
 5270     # check that stop(1) was called
 5271     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-2: exit status")
 5272     # don't restore from ebp
 5273     81 0/subop/add %esp 8/imm32
 5274     # . epilogue
 5275     5d/pop-to-ebp
 5276     c3/return
 5277 
 5278 test-get-with-wrong-output-type-3:
 5279     # . prologue
 5280     55/push-ebp
 5281     89/<- %ebp 4/r32/esp
 5282     # setup
 5283     (clear-stream _test-input-stream)
 5284     (clear-stream $_test-input-buffered-file->buffer)
 5285     (clear-stream _test-output-stream)
 5286     (clear-stream $_test-output-buffered-file->buffer)
 5287     (clear-stream _test-error-stream)
 5288     (clear-stream $_test-error-buffered-file->buffer)
 5289     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5290     68/push 0/imm32
 5291     68/push 0/imm32
 5292     89/<- %edx 4/r32/esp
 5293     (tailor-exit-descriptor %edx 0x10)
 5294     #
 5295     (write _test-input-stream "fn foo {\n")
 5296     (write _test-input-stream "  var a: t\n")
 5297     (write _test-input-stream "  var c/ecx: (array int) <- get a, x\n")
 5298     (write _test-input-stream "}\n")
 5299     (write _test-input-stream "type t {\n")
 5300     (write _test-input-stream "  x: int\n")
 5301     (write _test-input-stream "}\n")
 5302     # convert
 5303     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5304     # registers except esp clobbered at this point
 5305     # restore ed
 5306     89/<- %edx 4/r32/esp
 5307     (flush _test-output-buffered-file)
 5308     (flush _test-error-buffered-file)
 5309 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5315     # check output
 5316     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-output-type-3: output should be empty")
 5317     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: output must be an address"  "F - test-get-with-wrong-output-type-3: error message")
 5318     # check that stop(1) was called
 5319     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-3: exit status")
 5320     # don't restore from ebp
 5321     81 0/subop/add %esp 8/imm32
 5322     # . epilogue
 5323     5d/pop-to-ebp
 5324     c3/return
 5325 
 5326 test-get-with-wrong-output-type-4:
 5327     # . prologue
 5328     55/push-ebp
 5329     89/<- %ebp 4/r32/esp
 5330     # setup
 5331     (clear-stream _test-input-stream)
 5332     (clear-stream $_test-input-buffered-file->buffer)
 5333     (clear-stream _test-output-stream)
 5334     (clear-stream $_test-output-buffered-file->buffer)
 5335     (clear-stream _test-error-stream)
 5336     (clear-stream $_test-error-buffered-file->buffer)
 5337     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5338     68/push 0/imm32
 5339     68/push 0/imm32
 5340     89/<- %edx 4/r32/esp
 5341     (tailor-exit-descriptor %edx 0x10)
 5342     #
 5343     (write _test-input-stream "fn foo {\n")
 5344     (write _test-input-stream "  var a: t\n")
 5345     (write _test-input-stream "  var c/ecx: (addr boolean) <- get a, x\n")
 5346     (write _test-input-stream "}\n")
 5347     (write _test-input-stream "type t {\n")
 5348     (write _test-input-stream "  x: int\n")
 5349     (write _test-input-stream "}\n")
 5350     # convert
 5351     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5352     # registers except esp clobbered at this point
 5353     # restore ed
 5354     89/<- %edx 4/r32/esp
 5355     (flush _test-output-buffered-file)
 5356     (flush _test-error-buffered-file)
 5357 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5363     # check output
 5364     (check-stream-equal _test-output-stream  ""  "F - test-get-with-wrong-output-type-4: output should be empty")
 5365     (check-next-stream-line-equal _test-error-stream  "fn foo: stmt get: wrong output type for member 'x' of type 't'"  "F - test-get-with-wrong-output-type-4: error message")
 5366     # check that stop(1) was called
 5367     (check-ints-equal *(edx+4) 2 "F - test-get-with-wrong-output-type-4: exit status")
 5368     # don't restore from ebp
 5369     81 0/subop/add %esp 8/imm32
 5370     # . epilogue
 5371     5d/pop-to-ebp
 5372     c3/return
 5373 
 5374 test-get-with-wrong-output-type-5:
 5375     # . prologue
 5376     55/push-ebp
 5377     89/<- %ebp 4/r32/esp
 5378     # setup
 5379     (clear-stream _test-input-stream)
 5380     (clear-stream $_test-input-buffered-file->buffer)
 5381     (clear-stream _test-output-stream)
 5382     (clear-stream $_test-output-buffered-file->buffer)
 5383     #
 5384     (write _test-input-stream "fn foo {\n")
 5385     (write _test-input-stream "  var a: t\n")
 5386     (write _test-input-stream "  var c/ecx: (addr handle int) <- get a, x\n")
 5387     (write _test-input-stream "}\n")
 5388     (write _test-input-stream "type t {\n")
 5389     (write _test-input-stream "  x: (handle int)\n")
 5390     (write _test-input-stream "}\n")
 5391     # convert
 5392     (convert-mu _test-input-buffered-file _test-output-buffered-file Stderr 0)
 5393     (flush _test-output-buffered-file)
 5394     # no errors
 5395     # . epilogue
 5396     89/<- %esp 5/r32/ebp
 5397     5d/pop-to-ebp
 5398     c3/return
 5399 
 5400 test-get-with-too-few-inouts:
 5401     # . prologue
 5402     55/push-ebp
 5403     89/<- %ebp 4/r32/esp
 5404     # setup
 5405     (clear-stream _test-input-stream)
 5406     (clear-stream $_test-input-buffered-file->buffer)
 5407     (clear-stream _test-output-stream)
 5408     (clear-stream $_test-output-buffered-file->buffer)
 5409     (clear-stream _test-error-stream)
 5410     (clear-stream $_test-error-buffered-file->buffer)
 5411     # var ed/edx: exit-descriptor = tailor-exit-descriptor(16)
 5412     68/push 0/imm32
 5413     68/push 0/imm32
 5414     89/<- %edx 4/r32/esp
 5415     (tailor-exit-descriptor %edx 0x10)
 5416     #
 5417     (write _test-input-stream "fn foo {\n")
 5418     (write _test-input-stream "  var a: t\n")
 5419     (write _test-input-stream "  var c/ecx: (addr int) <- get a\n")
 5420     (write _test-input-stream "}\n")
 5421     (write _test-input-stream "type t {\n")
 5422     (write _test-input-stream "  x: int\n")
 5423     (write _test-input-stream "}\n")
 5424     # convert
 5425     (convert-mu _test-input-buffered-file _test-output-buffered-file _test-error-buffered-file %edx)
 5426     # registers except esp clobbered at this point
 5427     # restore ed
 5428     89/<- %edx 4/r32/esp
 5429     (flush _test-output-buffered-file)
 5430     (flush _test-error-buffered-file)
 5431 +--  6 lines: #?     # dump _test-error-stream ------------------------------------------------------------------------------------------------------------------------------------------
 5437     # check output
 5438     (check-stream-equal _test-output-stream  ""  "F -