about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik Agaram <vc@akkartik.com>2019-09-07 01:27:19 -0700
committerKartik Agaram <vc@akkartik.com>2019-09-07 01:34:07 -0700
commitd7dc6cf12f19db15c0f32f626ce135775ed9599c (patch)
tree4e6bfbff16eff7568173b97d5540e99d8d6f8a0f
parente850764d8c792e85252d876be04761274c997d47 (diff)
downloadmu-d7dc6cf12f19db15c0f32f626ce135775ed9599c.tar.gz
5633 - start of a toy lisp interpreter
-rw-r--r--apps/mulisp.subx76
1 files changed, 76 insertions, 0 deletions
diff --git a/apps/mulisp.subx b/apps/mulisp.subx
new file mode 100644
index 00000000..8b38c215
--- /dev/null
+++ b/apps/mulisp.subx
@@ -0,0 +1,76 @@
+# Toy lisp interpreter
+#
+# Current status: repeatedly reads line of text and prints it out.
+#
+# To run:
+#   $ ./ntranslate 0*.subx apps/subx-common.subx apps/mulisp.subx
+#   $ ./a.elf
+#   42
+#   => 42
+#   ^D
+#   $
+#
+# Or, for emulated mode (veeery slow):
+#   $ cat 0*.subx apps/mulisp.subx  |  ./subx run apps/desugar > a.desugar
+#   $ ./subx translate a.desugar -o a.elf
+
+== code
+
+Entry:  # run tests if necessary, a REPL if not
+    # . prolog
+    89/<- %ebp 4/r32/esp
+    # initialize heap
+    (new-segment Heap-size Heap)
+    # if (argc <= 1) goto run-main
+    81 7/subop/compare *ebp 1/imm32
+    7e/jump-if-lesser-or-equal $run-main/disp8
+    # if (argv[1] != "test")) goto run-main
+    (kernel-string-equal? *(ebp+8) "test")  # => eax
+    3d/compare-eax-and 0/imm32
+    74/jump-if-equal $run-main/disp8
+    #
+    (run-tests)
+    # syscall(exit, *Num-test-failures)
+    8b/-> *Num-test-failures 3/r32/ebx
+    eb/jump $main:end/disp8
+$run-main:
+    (repl Stdin Stdout)
+    # syscall(exit, 0)
+    bb/copy-to-ebx 0/imm32
+$main:end:
+    b8/copy-to-eax 1/imm32/exit
+    cd/syscall 0x80/imm8
+
+repl:  # in : (address buffered-file), out : (address buffered-file) -> <void>
+    # . prolog
+    55/push-ebp
+    89/<- %ebp 4/r32/esp
+    # . save registers
+    51/push-ecx
+    # var s/ecx : (address stream)
+    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
+$repl:loop:
+    (clear-stream %ecx)
+    (read-line-buffered Stdin %ecx)
+    # if (s->write == 0) break
+    81 7/subop/compare *ecx 0/imm32
+    74/jump-if-equal $repl:end/disp8
+    # write(s)
+    (write-buffered Stdout "=> ")
+    (write-stream-data Stdout %ecx)
+    (flush Stdout)
+    # loop
+    eb/jump $repl:loop/disp8
+$repl:end:
+    # . reclaim locals
+    81 0/subop/add %esp 0x20c/imm32
+    # . restore registers
+    59/pop-to-ecx
+    # . epilog
+    89/<- %esp 5/r32/ebp
+    5d/pop-to-ebp
+    c3/return