diff options
author | Kartik Agaram <vc@akkartik.com> | 2020-11-01 22:02:13 -0800 |
---|---|---|
committer | Kartik Agaram <vc@akkartik.com> | 2020-11-01 22:02:13 -0800 |
commit | 17623a628aee2429a5a8d8b65bd84235f6be0e3f (patch) | |
tree | 373ac0b29678e96d24faf1cb8d8c853ca6b06279 | |
parent | cc7dcdc3b8bb6c133ecdbc97d1c134d30f1500f5 (diff) | |
download | mu-17623a628aee2429a5a8d8b65bd84235f6be0e3f.tar.gz |
7154
-rw-r--r-- | apps/ex1.mu | 4 | ||||
-rw-r--r-- | apps/ex2.mu | 10 | ||||
-rw-r--r-- | apps/ex3.2.mu | 5 | ||||
-rw-r--r-- | apps/ex3.mu | 5 | ||||
-rwxr-xr-x | apps/factorial | bin | 44985 -> 44992 bytes | |||
-rw-r--r-- | apps/factorial.mu | 56 | ||||
-rw-r--r-- | apps/factorial.subx | 64 | ||||
-rw-r--r-- | apps/factorial2.subx | 59 | ||||
-rw-r--r-- | apps/factorial3.subx | 39 | ||||
-rw-r--r-- | apps/factorial4.subx | 31 | ||||
-rw-r--r-- | apps/hello.mu | 4 | ||||
-rw-r--r-- | apps/mulisp.subx | 233 |
12 files changed, 141 insertions, 369 deletions
diff --git a/apps/ex1.mu b/apps/ex1.mu index f6d67001..41609fac 100644 --- a/apps/ex1.mu +++ b/apps/ex1.mu @@ -8,6 +8,6 @@ # $ echo $? # 42 -fn main -> result/ebx: int { - result <- copy 0x2a # Mu requires hexadecimal +fn main -> _/ebx: int { + return 0x2a # Mu requires hexadecimal } diff --git a/apps/ex2.mu b/apps/ex2.mu index c3a73874..4ecfde9f 100644 --- a/apps/ex2.mu +++ b/apps/ex2.mu @@ -7,11 +7,13 @@ # $ echo $? # 7 -fn main -> result/ebx: int { - result <- do-add 3 4 +fn main -> _/ebx: int { + var result/eax: int <- do-add 3 4 + return result } -fn do-add a: int, b: int -> result/ebx: int { - result <- copy a +fn do-add a: int, b: int -> _/eax: int { + var result/ebx: int <- copy a result <- add b + return result } diff --git a/apps/ex3.2.mu b/apps/ex3.2.mu index dc97bf7a..d06928fe 100644 --- a/apps/ex3.2.mu +++ b/apps/ex3.2.mu @@ -6,7 +6,7 @@ # $ echo $? # 55 -fn main -> result/ebx: int { +fn main -> _/ebx: int { # populate a var a: (array int 0xb) # 11; we waste index 0 var i/ecx: int <- copy 1 @@ -19,7 +19,7 @@ fn main -> result/ebx: int { loop } # sum - result <- copy 0 + var result/edx: int <- copy 0 i <- copy 1 { compare i, 0xb @@ -29,4 +29,5 @@ fn main -> result/ebx: int { i <- increment loop } + return result } diff --git a/apps/ex3.mu b/apps/ex3.mu index efe6a317..d7e73140 100644 --- a/apps/ex3.mu +++ b/apps/ex3.mu @@ -7,8 +7,8 @@ # $ echo $? # 55 -fn main -> result/ebx: int { - result <- copy 0 +fn main -> _/ebx: int { + var result/ebx: int <- copy 0 var i/eax: int <- copy 1 { compare i, 0xa @@ -17,4 +17,5 @@ fn main -> result/ebx: int { i <- increment loop } + return result } diff --git a/apps/factorial b/apps/factorial index 5a567172..5eaecd80 100755 --- a/apps/factorial +++ b/apps/factorial Binary files differdiff --git a/apps/factorial.mu b/apps/factorial.mu index 362b68c6..bb335b0a 100644 --- a/apps/factorial.mu +++ b/apps/factorial.mu @@ -16,21 +16,19 @@ # # Compare apps/factorial4.subx -fn factorial n: int -> result/eax: int { +fn factorial n: int -> _/eax: int { compare n, 1 + # if (n <= 1) return 1 { break-if-> - # n <= 1; return 1 - result <- copy 1 - } - { - break-if-<= - # n > 1; return n * factorial(n-1) - var tmp/ecx: int <- copy n - tmp <- decrement - result <- factorial tmp - result <- multiply n + return 1 } + # n > 1; return n * factorial(n-1) + var tmp/ecx: int <- copy n + tmp <- decrement + var result/eax: int <- factorial tmp + result <- multiply n + return result } fn test-factorial { @@ -38,27 +36,25 @@ fn test-factorial { check-ints-equal result, 0x78, "F - test-factorial" } -fn main args-on-stack: (addr array (addr array byte)) -> exit-status/ebx: int { +fn main args-on-stack: (addr array (addr array byte)) -> _/ebx: int { var args/eax: (addr array addr array byte) <- copy args-on-stack # len = length(args) var len/ecx: int <- length args - $main-body: { - # if (len <= 1) return factorial(5) - compare len, 1 - { - break-if-> - var tmp/eax: int <- factorial 5 - exit-status <- copy tmp - break $main-body - } - # if (args[1] == "test") run-tests() - var tmp2/ecx: (addr addr array byte) <- index args, 1 - var tmp3/eax: boolean <- string-equal? *tmp2, "test" - compare tmp3, 0 - { - break-if-= - run-tests - exit-status <- copy 0 # TODO: get at Num-test-failures somehow - } + # if (len <= 1) return factorial(5) + compare len, 1 + { + break-if-> + var exit-status/eax: int <- factorial 5 + return exit-status + } + # if (args[1] == "test") run-tests() + var tmp2/ecx: (addr addr array byte) <- index args, 1 + var tmp3/eax: boolean <- string-equal? *tmp2, "test" + compare tmp3, 0 + { + break-if-= + run-tests + # TODO: get at Num-test-failures somehow } + return 0 } diff --git a/apps/factorial.subx b/apps/factorial.subx index b027696e..586592f5 100644 --- a/apps/factorial.subx +++ b/apps/factorial.subx @@ -18,21 +18,21 @@ # . op subop mod rm32 base index scale r32 # . 1-3 bytes 3 bits 2 bits 3 bits 3 bits 3 bits 2 bits 2 bits 0/1/2/4 bytes 0/1/2/4 bytes -factorial: # n: int -> int/eax +factorial: # n: int -> _/eax: int # . prologue 55/push-ebp 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - 53/push-ebx + 51/push-ecx # if (n <= 1) return 1 b8/copy-to-eax 1/imm32 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 1/imm32 # compare *(ebp+8) 7e/jump-if-<= $factorial:end/disp8 - # var ebx: int = n-1 - 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 3/r32/ebx 8/disp8 . # copy *(ebp+8) to ebx - 4b/decrement-ebx + # var ecx: int = n-1 + 8b/copy 1/mod/*+disp8 5/rm32/ebp . . 1/r32/ecx 8/disp8 . # copy *(ebp+8) to ecx + 49/decrement-ecx # var eax: int = factorial(n-1) # . . push args - 53/push-ebx + 51/push-ecx # . . call e8/call factorial/disp32 # . . discard args @@ -41,8 +41,9 @@ factorial: # n: int -> int/eax f7 4/subop/multiply 1/mod/*+disp8 5/rm32/ebp . . 8/disp8 . # multiply *(ebp+8) into eax # TODO: check for overflow $factorial:end: + # restore registers + 59/pop-to-ecx # . epilogue - 5b/pop-to-ebx 89/copy 3/mod/direct 4/rm32/esp . . . 5/r32/ebp . . # copy ebp to esp 5d/pop-to-ebp c3/return @@ -71,7 +72,7 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # . prologue 89/copy 3/mod/direct 5/rm32/ebp . . . 4/r32/esp . . # copy esp to ebp - # initialize heap + # initialize heap (needed by tests elsewhere) # . Heap = new-segment(Heap-size) # . . push args 68/push Heap/imm32 @@ -81,29 +82,10 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # . . discard args 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main - 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp - 7e/jump-if-<= $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main - # . eax = kernel-string-equal?(argv[1], "test") - # . . push args - 68/push "test"/imm32 - ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) - # . . call - e8/call kernel-string-equal?/disp32 - # . . discard args - 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp - # . if (eax == false) goto run-main - 3d/compare-eax-and 0/imm32/false - 74/jump-if-= $run-main/disp8 - # run-tests() - e8/call run-tests/disp32 - # syscall(exit, *Num-test-failures) - 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx - eb/jump $main:end/disp8 + # if (argc <= 1) return factorial(5) $run-main: - # - otherwise print factorial(5) + 81 7/subop/compare 1/mod/*+disp8 5/rm32/ebp . . . . 0/disp8 1/imm32 # compare *ebp + 7f/jump-if-> $main:run-tests/disp8 # eax = factorial(5) # . . push args 68/push 5/imm32 @@ -143,6 +125,28 @@ $run-main: 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp # 89/copy 3/mod/direct 3/rm32/ebx . . . 0/r32/eax . . # copy eax to ebx + eb/jump $main:end/disp8 +$main:run-tests: + # otherwise if first arg is "test", then return run_tests() + # if (!kernel-string-equal?(argv[1], "test")) goto do-nothing + # . eax = kernel-string-equal?(argv[1], "test") + # . . push args + 68/push "test"/imm32 + ff 6/subop/push 1/mod/*+disp8 5/rm32/ebp . . . . 8/disp8 . # push *(ebp+8) + # . . call + e8/call kernel-string-equal?/disp32 + # . . discard args + 81 0/subop/add 3/mod/direct 4/rm32/esp . . . . . 8/imm32 # add to esp + # . if (eax == false) goto do-nothing + 3d/compare-eax-and 0/imm32/false + 74/jump-if-= $main:do-nothing/disp8 + # run-tests() + e8/call run-tests/disp32 + # exit(*Num-test-failures) + 8b/copy 0/mod/indirect 5/rm32/.disp32 . . 3/r32/ebx Num-test-failures/disp32 # copy *Num-test-failures to ebx + eb/jump $main:end/disp8 +$main:do-nothing: + bb/copy-to-ebx 0/imm32 $main:end: e8/call syscall_exit/disp32 diff --git a/apps/factorial2.subx b/apps/factorial2.subx index 7d303227..55723f75 100644 --- a/apps/factorial2.subx +++ b/apps/factorial2.subx @@ -20,31 +20,33 @@ == code -factorial: # n: int -> int/eax +factorial: # n: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp - 53/push-ebx + # save registers + 51/push-ecx # if (n <= 1) return 1 b8/copy-to-eax 1/imm32 81 7/subop/compare *(ebp+8) 1/imm32 7e/jump-if-<= $factorial:end/disp8 - # var ebx: int = n-1 - 8b/-> *(ebp+8) 3/r32/ebx - 4b/decrement-ebx - # var eax: int = factorial(n-1) + # n > 1; return n * factorial(n-1) + 8b/-> *(ebp+8) 1/r32/ecx + 49/decrement-ecx + # var tmp/eax: int = factorial(n-1) # . . push args - 53/push-ebx + 51/push-ecx # . . call e8/call factorial/disp32 # . . discard args 81 0/subop/add %esp 4/imm32 - # return n * factorial(n-1) + # return n * tmp f7 4/subop/multiply-into-eax *(ebp+8) # TODO: check for overflow $factorial:end: + # restore registers + 59/pop-to-ecx # . epilogue - 5b/pop-to-ebx 89/<- %esp 5/r32/ebp 5d/pop-to-ebp c3/return @@ -73,7 +75,7 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # . prologue 89/<- %ebp 4/r32/esp - # initialize heap + # initialize heap (needed by tests elsewhere) # . Heap = new-segment(Heap-size) # . . push args 68/push Heap/imm32 @@ -83,11 +85,21 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # . . discard args 81 0/subop/add %esp 8/imm32 - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main + # if (argc <= 1) return factorial(5) 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 7f/jump-if-> $main:run-tests/disp8 + # . . push args + 68/push 5/imm32 + # . . call + e8/call factorial/disp32 + # . . discard args + 81 0/subop/add %esp 4/imm32 + # . + 89/<- %ebx 0/r32/eax + eb/jump $main:end/disp8 +$main:run-tests: + # otherwise if first arg is "test", then return run_tests() + # if (!kernel-string-equal?(argv[1], "test")) goto do-nothing # . eax = kernel-string-equal?(argv[1], "test") # . . push args 68/push "test"/imm32 @@ -96,24 +108,15 @@ Entry: # run tests if necessary, compute `factorial(5)` if not e8/call kernel-string-equal?/disp32 # . . discard args 81 0/subop/add %esp 8/imm32 - # . if (eax == false) goto run-main + # . if (eax == false) goto do-nothing 3d/compare-eax-and 0/imm32/false - 74/jump-if-= $run-main/disp8 + 74/jump-if-= $main:do-nothing/disp8 # run-tests() e8/call run-tests/disp32 - # syscall(exit, *Num-test-failures) + # exit(*Num-test-failures) 8b/-> *Num-test-failures 3/r32/ebx eb/jump $main:end/disp8 -$run-main: - # - otherwise return factorial(5) - # ebx = factorial(5) - # . . push args - 68/push 5/imm32 - # . . call - e8/call factorial/disp32 - # . . discard args - 81 0/subop/add %esp 4/imm32 - # - 89/<- %ebx 0/r32/eax +$main:do-nothing: + bb/copy-to-ebx 0/imm32 $main:end: e8/call syscall_exit/disp32 diff --git a/apps/factorial3.subx b/apps/factorial3.subx index eb07b5ca..b2624fe7 100644 --- a/apps/factorial3.subx +++ b/apps/factorial3.subx @@ -21,27 +21,25 @@ == code -factorial: # n: int -> int/eax +factorial: # n: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp # save registers - 53/push-ebx + 51/push-ecx # if (n <= 1) return 1 b8/copy-to-eax 1/imm32 81 7/subop/compare *(ebp+8) 1/imm32 7e/jump-if-<= $factorial:end/disp8 - # var ebx: int = n-1 - 8b/-> *(ebp+8) 3/r32/ebx - 4b/decrement-ebx - # - (factorial %ebx) # => eax - # return n * factorial(n-1) + # n > 1; return n * factorial(n-1) + 8b/-> *(ebp+8) 1/r32/ecx + 49/decrement-ecx + (factorial %ecx) # => eax f7 4/subop/multiply-into-eax *(ebp+8) # TODO: check for overflow $factorial:end: # restore registers - 5b/pop-to-ebx + 59/pop-to-ecx # . epilogue 89/<- %esp 5/r32/ebp 5d/pop-to-ebp @@ -59,23 +57,24 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # initialize heap (needed by tests elsewhere) (new-segment *Heap-size Heap) - # - if argc > 1 and argv[1] == "test", then return run_tests() - # if (argc <= 1) goto run-main + # if (argc <= 1) return factorial(5) 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= $run-main/disp8 - # if (!kernel-string-equal?(argv[1], "test")) goto run-main + 7f/jump-if-> $main:run-tests/disp8 + (factorial 5) # => eax + 89/<- %ebx 0/r32/eax + eb/jump $main:end/disp8 +$main:run-tests: + # otherwise if first arg is "test", then return run_tests() + # if (!kernel-string-equal?(argv[1], "test")) goto do-nothing (kernel-string-equal? *(ebp+8) "test") # => eax - # . if (eax == false) goto run-main 3d/compare-eax-and 0/imm32/false - 74/jump-if-= $run-main/disp8 + 74/jump-if-= $main:do-nothing/disp8 # (run-tests) - # syscall(exit, *Num-test-failures) + # exit(*Num-test-failures) 8b/-> *Num-test-failures 3/r32/ebx eb/jump $main:end/disp8 -$run-main: - # - otherwise - (factorial 5) # => eax - 89/<- %ebx 0/r32/eax +$main:do-nothing: + bb/copy-to-ebx 0/imm32 $main:end: e8/call syscall_exit/disp32 diff --git a/apps/factorial4.subx b/apps/factorial4.subx index 6228f9ab..e39c2178 100644 --- a/apps/factorial4.subx +++ b/apps/factorial4.subx @@ -22,7 +22,7 @@ == code -factorial: # n: int -> int/eax +factorial: # n: int -> _/eax: int # . prologue 55/push-ebp 89/<- %ebp 4/r32/esp @@ -33,16 +33,15 @@ factorial: # n: int -> int/eax { 7f/jump-if-> break/disp8 b8/copy-to-eax 1/imm32 + eb/jump $factorial:end/disp8 } - # if (n > 1) return n * factorial(n-1) - { - 7e/jump-if-<= break/disp8 - # var tmp/ecx: int = n-1 - 8b/-> *(ebp+8) 1/r32/ecx - 49/decrement-ecx - (factorial %ecx) # => eax - f7 4/subop/multiply-into-eax *(ebp+8) - } + # n > 1; return n * factorial(n-1) + 8b/-> *(ebp+8) 1/r32/ecx + 49/decrement-ecx + (factorial %ecx) # => eax + f7 4/subop/multiply-into-eax *(ebp+8) + # TODO: check for overflow +$factorial:end: # restore registers 59/pop-to-ecx # . epilogue @@ -70,20 +69,20 @@ Entry: # run tests if necessary, compute `factorial(5)` if not # ebx = factorial(5) (factorial 5) # => eax 89/<- %ebx 0/r32/eax + eb/jump $main:end/disp8 } - # otherwise if an arg exists and is "test", then return run_tests() + # otherwise if first arg is "test", then return run_tests() { - # if (argc <= 1) break - 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= break/disp8 # if (!kernel-string-equal?(argv[1], "test")) break (kernel-string-equal? *(ebp+8) "test") # => eax 3d/compare-eax-and 0/imm32/false 74/jump-if-= break/disp8 # (run-tests) - # ebx = *Num-test-failures + # exit(*Num-test-failures) 8b/-> *Num-test-failures 3/r32/ebx + eb/jump $main:end/disp8 } - + bb/copy-to-ebx 0/imm32 +$main:end: e8/call syscall_exit/disp32 diff --git a/apps/hello.mu b/apps/hello.mu index a305edf0..5a656b96 100644 --- a/apps/hello.mu +++ b/apps/hello.mu @@ -4,7 +4,7 @@ # $ ./translate_mu apps/hello.mu # $ ./a.elf -fn main -> exit-status/ebx: int { +fn main -> _/ebx: int { print-string 0, "Hello world!\n" - exit-status <- copy 0 + return 0 } diff --git a/apps/mulisp.subx b/apps/mulisp.subx deleted file mode 100644 index b433fa17..00000000 --- a/apps/mulisp.subx +++ /dev/null @@ -1,233 +0,0 @@ -# Toy lisp interpreter. Incomplete. -# -# To run: -# $ ./translate_subx init.linux 0*.subx apps/mulisp.subx -# $ ./a.elf -# 42 -# => 42 -# ^D -# $ - -== code - -Entry: # run tests if necessary, a REPL if not - # . prologue - 89/<- %ebp 4/r32/esp - # initialize heap - (new-segment *Heap-size Heap) - { - # if (argc <= 1) break - 81 7/subop/compare *ebp 1/imm32 - 7e/jump-if-<= break/disp8 - # if (argv[1] != "test")) break - (kernel-string-equal? *(ebp+8) "test") # => eax - 3d/compare-eax-and 0/imm32/false - 74/jump-if-= break/disp8 - # - (run-tests) - # syscall(exit, *Num-test-failures) - 8b/-> *Num-test-failures 3/r32/ebx - eb/jump $main:end/disp8 - } - (repl Stdin Stdout) - # syscall(exit, 0) - bb/copy-to-ebx 0/imm32 -$main:end: - e8/call syscall_exit/disp32 - -# Data structures -# -# Lisp is dynamically typed. Values always carry around knowledge of their -# type. -# -# There's several types of types in the description below, so we need a -# glossary and notational convention to disambiguate: -# lisp type: what Lisp code can see. Looks how you type it at the prompt. -# nil num char string symbol pair array -# type tag: the numeric code for a lisp type. All caps. -# NIL NUM CHAR STRING SYMBOL PAIR ARRAY -# memory type: a type specifying memory layout at the SubX level. Starts -# with a '$'. -# $int $array $(addr _) -# -# Lisp values are represented in memory by the _cell_ data structure. A cell -# is 12 bytes long: -# tag: $int (4 bytes; we're not concerned about wasting space) -# data: 8 bytes whose contents and meaning depend on tag -# -# What values of the different Lisp types look like in memory: -# - nil: cell{ tag: 0/NIL, data: 0 0 } -# - num: cell{ tag: 1/NUM, data: $int 0 } -# data contains the number -# - char: cell{ tag: 2/CHAR, data: $int 0 } -# data contains the utf-8 code of the character (no compound glyphs, no -# modifiers, etc., etc.) -# - string: cell{ tag: 3/STRING, data: $(addr stream byte) -# data contains an (addr array byte) containing the string in utf-8 -# - symbol: cell{ tag: 4/SYMBOL, data: $(addr array byte) 0 } -# data contains an (addr array byte) containing the name of the symbol in utf-8 -# alternatively, data could contain an index into the table of interned symbols -# - pair: cell{ tag: 5/PAIR, data: $(addr cell) $(addr cell) } -# data contains pointers to car and cdr -# - array: cell{ tag: 6/ARRAY, data: $tag $(addr stream data) -# data contains a pointer to an array of 8-byte data fields and the common -# tag for them all - -repl: # in: (addr buffered-file), out: (addr buffered-file) - # . prologue - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 50/push-eax - { - (lisp-read Stdin) # => eax: (handle cell) - # if (eax == 0) break - 3d/compare-eax-and 0/imm32 - 74/jump-if-= break/disp8 - # - (lisp-eval %eax) # => eax: (handle cell) - (lisp-print Stdout %eax) - eb/jump loop/disp8 - } -$repl:end: - # . restore registers - 58/pop-to-eax - # . epilogue - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -# numbers start with a digit and are always in hex -# characters start with a backslash -# pairs start with '(' -# arrays start with '[' -# symbols start with anything else but quote, backquote, unquote or splice -# only one s-expression per line -lisp-read: # in: (addr buffered-file) -> eax: (handle cell) - # . prologue - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 51/push-ecx - # var s/ecx: (stream byte 512) - 81 5/subop/subtract %esp 0x200/imm32 - 68/push 0x200/imm32/size - 68/push 0/imm32/read - 68/push 0/imm32/write - 89/<- %ecx 4/r32/esp - { - # read line into s - (clear-stream %ecx) - (read-line-buffered *(ebp+8) %ecx) - # if (s->write == 0) return null - { - 81 7/subop/compare *ecx 0/imm32 - 75/jump-if-!= break/disp8 - b8/copy-to-eax 0/imm32/eof - eb/jump $lisp-read:end/disp8 - } - # ... -#? eb/jump loop/disp8 - } - # return s - 89/<- %eax 1/r32/ecx -$lisp-read:end: - # . reclaim locals - 81 0/subop/add %esp 0x20c/imm32 - # . restore registers - 59/pop-to-ecx - # . epilogue - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -# lisp-read: in: (addr buffered-file) -> (handle cell) -# token tmp = next-mulisp-token(in) -# if is-int(tmp) return cell(tmp) -# if is-string(tmp) return cell(tmp) -# if is-pair(tmp) ... -# if is-array(tmp) ... - -next-mulisp-token: # in: (addr buffered-file), line: (addr stream byte), result: (addr slice) - # pseudocode: - # if (line->read >= line->write) - # read-line-buffered(in, line) - # recurse - # if (line->data[line->read] == ' ') - # skip-chars-matching-whitespace(line) - # recurse - # if (line->data[line->read] == '#') - # read-line-buffered(in, line) - # recurse - # eax = line->data[line->read] - # if (eax == '"') - # result->start = &line->data[line->read] - # skip-string(in) - # result->end = &line->data[line->read] - # return - # if (is-digit(eax)) - # result->start = &line->data[line->read] - # skip-hex-int(in) - # result->end = &line->data[line->read] - # return - # if (eax in '(' ')' '[' ']') - # result->start = &line->data[line->read] - # ++line->read - # result->en = &line->data[line->read] - # return - # else - # result->start = &line->data[line->read] - # skip-lisp-word(line) - # result->en = &line->data[line->read] - # return - # - # . prologue - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers -$next-mulisp-token:end: - # . reclaim locals - # . restore registers - # . epilogue - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -new-int-cell: # in: (addr slice) -> eax: (handle cell) - -new-string-cell: # in: (addr slice) -> eax: (handle cell) - -lisp-eval: # in: (addr cell) -> eax: (handle cell) - # . prologue - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - 8b/-> *(ebp+8) 0/r32/eax -$lisp-eval:end: - # . restore registers - # . epilogue - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -lisp-print: # out: (addr buffered-file), x: (addr cell) - # . prologue - 55/push-ebp - 89/<- %ebp 4/r32/esp - # . save registers - # write(x) - (write-buffered Stdout "=> ") - (write-stream-data Stdout *(ebp+0xc)) - (flush Stdout) -$lisp-print:end: - # . restore registers - # . epilogue - 89/<- %esp 5/r32/ebp - 5d/pop-to-ebp - c3/return - -== data - -Nil: - 0/imm32/tag - 0/imm32/data |