parent
e46cfc2e0c
commit
5babe16f2d
|
@ -1,7 +1,8 @@
|
|||
Some apps written in SubX and Mu. Check out:
|
||||
|
||||
* `tile`: [A text-mode postfix calculator](https://mastodon.social/@akkartik/104896128141863951)
|
||||
that updates as you type.
|
||||
that updates as you type. Prototype. Look at this to see what is currently
|
||||
possible, not how I recommend building software.
|
||||
|
||||
<img alt='tile app' src='../html/rpn5.png' width='500px'>
|
||||
|
||||
|
|
|
@ -2,21 +2,21 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
|
|||
var line/eax: (addr line) <- copy scratch
|
||||
var word-ah/eax: (addr handle word) <- get line, data
|
||||
var curr/eax: (addr word) <- lookup *word-ah
|
||||
var curr-text-storage: (stream byte 0x10)
|
||||
var curr-text/edi: (addr stream byte) <- address curr-text-storage
|
||||
var curr-stream-storage: (stream byte 0x10)
|
||||
var curr-stream/edi: (addr stream byte) <- address curr-stream-storage
|
||||
clear-int-stack out
|
||||
$evaluate:loop: {
|
||||
# precondition (should never hit)
|
||||
compare curr, 0
|
||||
break-if-=
|
||||
# update curr-text
|
||||
emit-word curr, curr-text
|
||||
#? print-stream-to-real-screen curr-text
|
||||
# update curr-stream
|
||||
emit-word curr, curr-stream
|
||||
#? print-stream-to-real-screen curr-stream
|
||||
#? print-string-to-real-screen "\n"
|
||||
$evaluate:process-word: {
|
||||
# if curr-text is an operator, perform it
|
||||
# if curr-stream is an operator, perform it
|
||||
{
|
||||
var is-add?/eax: boolean <- stream-data-equal? curr-text, "+"
|
||||
var is-add?/eax: boolean <- stream-data-equal? curr-stream, "+"
|
||||
compare is-add?, 0
|
||||
break-if-=
|
||||
var _b/eax: int <- pop-int-stack out
|
||||
|
@ -27,7 +27,7 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
|
|||
break $evaluate:process-word
|
||||
}
|
||||
{
|
||||
var is-sub?/eax: boolean <- stream-data-equal? curr-text, "-"
|
||||
var is-sub?/eax: boolean <- stream-data-equal? curr-stream, "-"
|
||||
compare is-sub?, 0
|
||||
break-if-=
|
||||
var _b/eax: int <- pop-int-stack out
|
||||
|
@ -38,7 +38,7 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
|
|||
break $evaluate:process-word
|
||||
}
|
||||
{
|
||||
var is-mul?/eax: boolean <- stream-data-equal? curr-text, "*"
|
||||
var is-mul?/eax: boolean <- stream-data-equal? curr-stream, "*"
|
||||
compare is-mul?, 0
|
||||
break-if-=
|
||||
var _b/eax: int <- pop-int-stack out
|
||||
|
@ -48,20 +48,42 @@ fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr
|
|||
push-int-stack out, a
|
||||
break $evaluate:process-word
|
||||
}
|
||||
# if curr-text is a known function name, call it appropriately
|
||||
# if curr-stream is a known function name, call it appropriately
|
||||
{
|
||||
var callee-h: (handle function)
|
||||
var callee-ah/eax: (addr handle function) <- address callee-h
|
||||
find-function defs, curr-text, callee-ah
|
||||
find-function defs, curr-stream, callee-ah
|
||||
var callee/eax: (addr function) <- lookup *callee-ah
|
||||
compare callee, 0
|
||||
break-if-=
|
||||
perform-call callee, out, defs
|
||||
break $evaluate:process-word
|
||||
}
|
||||
# otherwise it's an int
|
||||
# if it's a name, push its value
|
||||
{
|
||||
var n/eax: int <- parse-decimal-int-from-stream curr-text
|
||||
compare bindings, 0
|
||||
break-if-=
|
||||
var tmp: (handle array byte)
|
||||
var curr-string-ah/edx: (addr handle array byte) <- address tmp
|
||||
stream-to-string curr-stream, curr-string-ah
|
||||
var _curr-string/eax: (addr array byte) <- lookup *curr-string-ah
|
||||
var curr-string/edx: (addr array byte) <- copy _curr-string
|
||||
var result/eax: int <- copy 0
|
||||
var found?/ecx: boolean <- copy 0 # false
|
||||
result, found? <- lookup-binding bindings, curr-string
|
||||
compare found?, 0 # false
|
||||
break-if-=
|
||||
#? print-string-to-real-screen "value of "
|
||||
#? print-string-to-real-screen curr-string
|
||||
#? print-string-to-real-screen " is "
|
||||
#? print-int32-hex-to-real-screen result
|
||||
#? print-string-to-real-screen "\n"
|
||||
push-int-stack out, result
|
||||
break $evaluate:process-word
|
||||
}
|
||||
# otherwise assume it's a literal int and push it
|
||||
{
|
||||
var n/eax: int <- parse-decimal-int-from-stream curr-stream
|
||||
push-int-stack out, n
|
||||
}
|
||||
}
|
||||
|
@ -102,7 +124,7 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
|
|||
# create bindings for args
|
||||
var table-storage: table
|
||||
var table/esi: (addr table) <- address table-storage
|
||||
initialize-table table
|
||||
initialize-table table, 0x10
|
||||
#
|
||||
var curr-arg-ah/eax: (addr handle word) <- get callee, args
|
||||
var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
|
||||
|
@ -115,7 +137,13 @@ fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs:
|
|||
# create binding
|
||||
word-to-string curr-arg, curr-key
|
||||
{
|
||||
#? var tmp/eax: (addr array byte) <- lookup *curr-key
|
||||
#? print-string-to-real-screen "binding "
|
||||
#? print-string-to-real-screen tmp
|
||||
#? print-string-to-real-screen " to "
|
||||
var curr-val/eax: int <- pop-int-stack caller-stack
|
||||
#? print-int32-decimal-to-real-screen curr-val
|
||||
#? print-string-to-real-screen "\n"
|
||||
bind-int-in-table table, curr-key, curr-val
|
||||
}
|
||||
#
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
fn initialize-table _self: (addr table) {
|
||||
fn initialize-table _self: (addr table), n: int {
|
||||
var self/esi: (addr table) <- copy _self
|
||||
var data-ah/eax: (addr handle array bind) <- get self, data
|
||||
populate data-ah, 0x10
|
||||
populate data-ah, n
|
||||
}
|
||||
|
||||
fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int {
|
||||
|
@ -45,3 +45,38 @@ fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
|
|||
var val/ecx: int <- copy _val
|
||||
copy-to *dest3, val
|
||||
}
|
||||
|
||||
# TODO: supporting non-integers
|
||||
# That'll require radical surgery.
|
||||
fn lookup-binding _self: (addr table), key: (addr array byte) -> result/eax: int, found?/ecx: boolean {
|
||||
var self/esi: (addr table) <- copy _self
|
||||
var data-ah/esi: (addr handle array bind) <- get self, data
|
||||
var _data/eax: (addr array bind) <- lookup *data-ah
|
||||
var data/esi: (addr array bind) <- copy _data
|
||||
var len/edx: int <- length data
|
||||
var i/ebx: int <- copy 0
|
||||
found? <- copy 0 # false
|
||||
$lookup-binding:loop: {
|
||||
compare i, len
|
||||
break-if->=
|
||||
{
|
||||
var offset/edx: (offset bind) <- compute-offset data, i
|
||||
var target-bind/esi: (addr bind) <- index data, offset
|
||||
var target2/edx: (addr handle array byte) <- get target-bind, key
|
||||
var target3/eax: (addr array byte) <- lookup *target2
|
||||
compare target3, 0
|
||||
break-if-= $lookup-binding:loop
|
||||
var is-match?/eax: boolean <- string-equal? target3, key
|
||||
compare is-match?, 0 # false
|
||||
break-if-=
|
||||
# found
|
||||
found? <- copy 1 # true
|
||||
var dest2/eax: (addr value) <- get target-bind, value
|
||||
var dest3/eax: (addr int) <- get dest2, scalar-data
|
||||
result <- copy *dest3
|
||||
break $lookup-binding:loop
|
||||
}
|
||||
i <- increment
|
||||
loop
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue