about summary refs log tree commit diff stats
path: root/shell/global.mu
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2021-04-05 23:52:13 -0700
committerKartik K. Agaram <vc@akkartik.com>2021-04-05 23:55:13 -0700
commit0db683ffdbf09ef6830857c6bedc887d654de78f (patch)
treeb5aa9c3143057230bee405c3d1b314d52dbdcc6e /shell/global.mu
parent9142cd8519e11564c097ec4ccb5933a94ed6fea0 (diff)
downloadmu-0db683ffdbf09ef6830857c6bedc887d654de78f.tar.gz
shell: extensible array of globals
I'm not bothering with full dynamic scope for now.
Diffstat (limited to 'shell/global.mu')
-rw-r--r--shell/global.mu105
1 files changed, 105 insertions, 0 deletions
diff --git a/shell/global.mu b/shell/global.mu
new file mode 100644
index 00000000..5aa1e22c
--- /dev/null
+++ b/shell/global.mu
@@ -0,0 +1,105 @@
+type global {
+  name: (handle array byte)
+  value: (handle cell)
+}
+
+type global-table {
+  data: (handle array global)
+  final-index: int
+}
+
+fn initialize-globals _self: (addr global-table) {
+  var self/esi: (addr global-table) <- copy _self
+  var data-ah/eax: (addr handle array global) <- get self, data
+  populate data-ah, 0x10
+  append-primitive self, "+"
+  append-primitive self, "-"
+  append-primitive self, "*"
+  append-primitive self, "/"
+}
+
+fn append-primitive _self: (addr global-table), name: (addr array byte) {
+  var self/esi: (addr global-table) <- copy _self
+  var final-index-addr/ecx: (addr int) <- get self, final-index
+  increment *final-index-addr
+  var curr-index/ecx: int <- copy *final-index-addr
+  var data-ah/eax: (addr handle array global) <- get self, data
+  var data/eax: (addr array global) <- lookup *data-ah
+  var curr-offset/esi: (offset global) <- compute-offset data, curr-index
+  var curr/esi: (addr global) <- index data, curr-offset
+  var curr-name-ah/eax: (addr handle array byte) <- get curr, name
+  copy-array-object name, curr-name-ah
+  var curr-value-ah/eax: (addr handle cell) <- get curr, value
+  new-primitive-function curr-value-ah, curr-index
+}
+
+# a little strange; goes from value to name and selects primitive based on name
+fn apply-primitive _f: (addr cell), args-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), _globals: (addr global-table), trace: (addr trace) {
+  var f/esi: (addr cell) <- copy _f
+  var f-index-a/ecx: (addr int) <- get f, index-data
+  var f-index/ecx: int <- copy *f-index-a
+  var globals/eax: (addr global-table) <- copy _globals
+  var global-data-ah/eax: (addr handle array global) <- get globals, data
+  var global-data/eax: (addr array global) <- lookup *global-data-ah
+  var f-offset/ecx: (offset global) <- compute-offset global-data, f-index
+  var f-value/ecx: (addr global) <- index global-data, f-offset
+  var f-name-ah/ecx: (addr handle array byte) <- get f-value, name
+  var f-name/eax: (addr array byte) <- lookup *f-name-ah
+  {
+    var is-add?/eax: boolean <- string-equal? f-name, "+"
+    compare is-add?, 0/false
+    break-if-=
+    apply-add args-ah, out, env-h, trace
+    return
+  }
+  abort "unknown primitive function"
+}
+
+fn apply-add _args-ah: (addr handle cell), out: (addr handle cell), env-h: (handle cell), trace: (addr trace) {
+  trace-text trace, "eval", "apply +"
+  var args-ah/eax: (addr handle cell) <- copy _args-ah
+  var _args/eax: (addr cell) <- lookup *args-ah
+  var args/esi: (addr cell) <- copy _args
+  var _env/eax: (addr cell) <- lookup env-h
+  var env/edi: (addr cell) <- copy _env
+  # TODO: check that args is a pair
+  var empty-args?/eax: boolean <- nil? args
+  compare empty-args?, 0/false
+  {
+    break-if-=
+    error trace, "+ needs 2 args but got 0"
+    return
+  }
+  # args->left->value
+  var first-ah/eax: (addr handle cell) <- get args, left
+  var first/eax: (addr cell) <- lookup *first-ah
+  var first-type/ecx: (addr int) <- get first, type
+  compare *first-type, 1/number
+  {
+    break-if-=
+    error trace, "first arg for + is not a number"
+    return
+  }
+  var first-value/ecx: (addr float) <- get first, number-data
+  # args->right->left->value
+  var right-ah/eax: (addr handle cell) <- get args, right
+#?   dump-cell right-ah
+#?   abort "aaa"
+  var right/eax: (addr cell) <- lookup *right-ah
+  # TODO: check that right is a pair
+  var second-ah/eax: (addr handle cell) <- get right, left
+  var second/eax: (addr cell) <- lookup *second-ah
+  var second-type/edx: (addr int) <- get second, type
+  compare *second-type, 1/number
+  {
+    break-if-=
+    error trace, "second arg for + is not a number"
+    return
+  }
+  var second-value/edx: (addr float) <- get second, number-data
+  # add
+  var result/xmm0: float <- copy *first-value
+  result <- add *second-value
+  new-float out, result
+}
+