diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2021-04-05 23:52:13 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2021-04-05 23:55:13 -0700 |
commit | 0db683ffdbf09ef6830857c6bedc887d654de78f (patch) | |
tree | b5aa9c3143057230bee405c3d1b314d52dbdcc6e /shell/global.mu | |
parent | 9142cd8519e11564c097ec4ccb5933a94ed6fea0 (diff) | |
download | mu-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.mu | 105 |
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 +} + |