From a0d3cac4e69101669681a4d8af6dc3e8bd2c9a6a Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sun, 15 Sep 2019 00:01:26 -0700 Subject: 5659 --- html/apps/mulisp.subx.html | 229 ++++++++++++++++++++++++++------------------- 1 file changed, 132 insertions(+), 97 deletions(-) (limited to 'html/apps') diff --git a/html/apps/mulisp.subx.html b/html/apps/mulisp.subx.html index e3c08251..7976b071 100644 --- a/html/apps/mulisp.subx.html +++ b/html/apps/mulisp.subx.html @@ -92,103 +92,138 @@ if ('onhashchange' in window) { 35 b8/copy-to-eax 1/imm32/exit 36 cd/syscall 0x80/imm8 37 - 38 # type cell = nil | num | char | symbol | pair | array | stream - 39 # tag: 0 1 2 3 4 5 6 - 40 # numbers start with a digit and are always in hex - 41 # characters start with a backslash - 42 # pairs start with '(' - 43 # arrays start with '[' - 44 # symbols start with anything else but quote, backquote, unquote or splice - 45 - 46 repl: # in : (address buffered-file), out : (address buffered-file) -> <void> - 47 # . prolog - 48 55/push-ebp - 49 89/<- %ebp 4/r32/esp - 50 # . save registers - 51 50/push-eax - 52 $repl:loop: - 53 (lisp-read Stdin) # => eax : (address cell) - 54 # if (eax == 0) break - 55 3d/compare-eax-and 0/imm32 - 56 74/jump-if-equal $repl:end/disp8 - 57 # - 58 (lisp-eval %eax) # => eax : (address cell) - 59 (lisp-print Stdout %eax) - 60 # loop - 61 eb/jump $repl:loop/disp8 - 62 $repl:end: - 63 # . restore registers - 64 58/pop-to-eax - 65 # . epilog - 66 89/<- %esp 5/r32/ebp - 67 5d/pop-to-ebp - 68 c3/return - 69 - 70 lisp-read: # in : (address buffered-file) -> eax : (address cell) - 71 # . prolog - 72 55/push-ebp - 73 89/<- %ebp 4/r32/esp - 74 # . save registers - 75 # var s/ecx : (address stream) = new-stream(512) - 76 81 5/subop/subtract %esp 0x200/imm32 - 77 68/push 0x200/imm32/size - 78 68/push 0/imm32/read - 79 68/push 0/imm32/write - 80 89/<- %ecx 4/r32/esp - 81 # - 82 (clear-stream %ecx) - 83 (read-line-buffered *(ebp+8) %ecx) - 84 # if (s->write == 0) return null - 85 81 7/subop/compare *ecx 0/imm32 - 86 75/jump-if-not-equal $lisp-read:loop/disp8 - 87 b8/copy-to-eax 0/imm32/eof - 88 eb/jump $lisp-read:end/disp8 - 89 $lisp-read:loop: - 90 # return s - 91 89/<- %eax 1/r32/ecx - 92 $lisp-read:end: - 93 # . reclaim locals - 94 81 0/subop/add %esp 0x20c/imm32 - 95 # . restore registers - 96 # . epilog - 97 89/<- %esp 5/r32/ebp - 98 5d/pop-to-ebp - 99 c3/return -100 -101 lisp-eval: # in : (address cell) -> eax : (address cell) -102 # . prolog -103 55/push-ebp -104 89/<- %ebp 4/r32/esp -105 # . save registers -106 8b/-> *(ebp+8) 0/r32/eax -107 $lisp-eval:end: -108 # . restore registers -109 # . epilog -110 89/<- %esp 5/r32/ebp -111 5d/pop-to-ebp -112 c3/return -113 -114 lisp-print: # out : (address buffered-file), x : (address cell) -115 # . prolog -116 55/push-ebp -117 89/<- %ebp 4/r32/esp -118 # . save registers -119 # write(x) -120 (write-buffered Stdout "=> ") -121 (write-stream-data Stdout *(ebp+0xc)) -122 (flush Stdout) -123 $lisp-print:end: -124 # . restore registers -125 # . epilog -126 89/<- %esp 5/r32/ebp -127 5d/pop-to-ebp -128 c3/return -129 -130 == data -131 -132 Nil: -133 0/imm32/tag -134 0/imm32/data + 38 # Data structures + 39 # + 40 # Lisp is dynamically typed. Values always carry around knowledge of their + 41 # type. + 42 # + 43 # There's several types of types in the description below, so we need a + 44 # glossary and notational convention to disambiguate: + 45 # lisp type: what Lisp code can see. Looks how you type it at the prompt. + 46 # nil num char string symbol pair array + 47 # type tag: the numeric code for a lisp type. All caps. + 48 # NIL NUM CHAR STRING SYMBOL PAIR ARRAY + 49 # memory type: a type specifying memory layout at the SubX level. Starts + 50 # with a '$'. + 51 # $int $array $(address _) + 52 # + 53 # Lisp values are represented in memory by the _cell_ data structure. A cell + 54 # is 12 bytes long: + 55 # tag: $int (4 bytes; we're not concerned about wasting space) + 56 # data: 8 bytes whose contents and meaning depend on tag + 57 # + 58 # What values of the different Lisp types look like in memory: + 59 # - nil: cell{ tag: 0/NIL, data: 0 0 } + 60 # - num: cell{ tag: 1/NUM, data: $int 0 } + 61 # data contains the number + 62 # - char: cell{ tag: 2/CHAR, data: $int 0 } + 63 # data contains the utf-8 code of the character (no compound glyphs, no + 64 # modifiers, etc., etc.) + 65 # - string: cell{ tag: 3/STRING, data: $(address array byte) + 66 # data contains an (address array byte) containing the string in utf-8 + 67 # - symbol: cell{ tag: 4/SYMBOL, data: $(address array byte) 0 } + 68 # data contains an (address array byte) containing the name of the symbol in utf-8 + 69 # alternatively, data could contain an index into the table of interned symbols + 70 # - pair: cell{ tag: 5/PAIR, data: $(address cell) $(address cell) } + 71 # data contains pointers to car and cdr + 72 # - array: cell{ tag: 6/ARRAY, data: $tag $(address array data) + 73 # data contains a pointer to an array of 8-byte data fields and the common + 74 # tag for them all + 75 + 76 repl: # in : (address buffered-file), out : (address buffered-file) -> <void> + 77 # . prolog + 78 55/push-ebp + 79 89/<- %ebp 4/r32/esp + 80 # . save registers + 81 50/push-eax + 82 $repl:loop: + 83 (lisp-read Stdin) # => eax : (address cell) + 84 # if (eax == 0) break + 85 3d/compare-eax-and 0/imm32 + 86 74/jump-if-equal $repl:end/disp8 + 87 # + 88 (lisp-eval %eax) # => eax : (address cell) + 89 (lisp-print Stdout %eax) + 90 # loop + 91 eb/jump $repl:loop/disp8 + 92 $repl:end: + 93 # . restore registers + 94 58/pop-to-eax + 95 # . epilog + 96 89/<- %esp 5/r32/ebp + 97 5d/pop-to-ebp + 98 c3/return + 99 +100 # numbers start with a digit and are always in hex +101 # characters start with a backslash +102 # pairs start with '(' +103 # arrays start with '[' +104 # symbols start with anything else but quote, backquote, unquote or splice +105 lisp-read: # in : (address buffered-file) -> eax : (address cell) +106 # . prolog +107 55/push-ebp +108 89/<- %ebp 4/r32/esp +109 # . save registers +110 # var s/ecx : (address stream) = new-stream(512) +111 81 5/subop/subtract %esp 0x200/imm32 +112 68/push 0x200/imm32/size +113 68/push 0/imm32/read +114 68/push 0/imm32/write +115 89/<- %ecx 4/r32/esp +116 # +117 (clear-stream %ecx) +118 (read-line-buffered *(ebp+8) %ecx) +119 # if (s->write == 0) return null +120 81 7/subop/compare *ecx 0/imm32 +121 75/jump-if-not-equal $lisp-read:loop/disp8 +122 b8/copy-to-eax 0/imm32/eof +123 eb/jump $lisp-read:end/disp8 +124 $lisp-read:loop: +125 # return s +126 89/<- %eax 1/r32/ecx +127 $lisp-read:end: +128 # . reclaim locals +129 81 0/subop/add %esp 0x20c/imm32 +130 # . restore registers +131 # . epilog +132 89/<- %esp 5/r32/ebp +133 5d/pop-to-ebp +134 c3/return +135 +136 lisp-eval: # in : (address cell) -> eax : (address cell) +137 # . prolog +138 55/push-ebp +139 89/<- %ebp 4/r32/esp +140 # . save registers +141 8b/-> *(ebp+8) 0/r32/eax +142 $lisp-eval:end: +143 # . restore registers +144 # . epilog +145 89/<- %esp 5/r32/ebp +146 5d/pop-to-ebp +147 c3/return +148 +149 lisp-print: # out : (address buffered-file), x : (address cell) +150 # . prolog +151 55/push-ebp +152 89/<- %ebp 4/r32/esp +153 # . save registers +154 # write(x) +155 (write-buffered Stdout "=> ") +156 (write-stream-data Stdout *(ebp+0xc)) +157 (flush Stdout) +158 $lisp-print:end: +159 # . restore registers +160 # . epilog +161 89/<- %esp 5/r32/ebp +162 5d/pop-to-ebp +163 c3/return +164 +165 == data +166 +167 Nil: +168 0/imm32/tag +169 0/imm32/data -- cgit 1.4.1-2-gfad0