7159 - explicitly use 'return' everywhere
https://github.com/akkartik/mu/issues/45#issuecomment-719990879, task 2.
This commit is contained in:
parent
951c3f4c92
commit
a3f7791586
|
@ -162,10 +162,10 @@ $print-float:body: {
|
|||
}
|
||||
}
|
||||
|
||||
#? fn main -> r/ebx: int {
|
||||
#? fn main -> _/ebx: int {
|
||||
#? run-tests
|
||||
#? #? test-print-float-negative-zero
|
||||
#? #? print-int32-hex 0, 0
|
||||
#? #? test-print-float-normal
|
||||
#? r <- copy 0
|
||||
#? return 0
|
||||
#? }
|
||||
|
|
|
@ -1,33 +1,29 @@
|
|||
fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
||||
fn main args-on-stack: (addr array addr array byte) -> _/ebx: int {
|
||||
var args/eax: (addr array addr array byte) <- copy args-on-stack
|
||||
var len/ecx: int <- length args
|
||||
$main-body: {
|
||||
# if (len(args) <= 1) print usage and exit
|
||||
compare len, 1
|
||||
{
|
||||
break-if->
|
||||
print-string-to-real-screen "usage: browse [filename]\n"
|
||||
print-string-to-real-screen " or browse test\n"
|
||||
exit-status <- copy 1
|
||||
break $main-body
|
||||
}
|
||||
# if (args[1] == "test") run-tests()
|
||||
var tmp/ecx: (addr addr array byte) <- index args, 1
|
||||
var tmp2/eax: boolean <- string-equal? *tmp, "test"
|
||||
compare tmp2, 0
|
||||
{
|
||||
break-if-=
|
||||
run-tests
|
||||
exit-status <- copy 0 # TODO: get at Num-test-failures somehow
|
||||
break $main-body
|
||||
}
|
||||
# otherwise interactive mode
|
||||
exit-status <- interactive args-on-stack
|
||||
# if (len(args) <= 1) print usage and exit
|
||||
compare len, 1
|
||||
{
|
||||
break-if->
|
||||
print-string-to-real-screen "usage: browse [filename]\n"
|
||||
print-string-to-real-screen " or browse test\n"
|
||||
return 1
|
||||
}
|
||||
# if (args[1] == "test") run-tests()
|
||||
var tmp/ecx: (addr addr array byte) <- index args, 1
|
||||
var tmp2/eax: boolean <- string-equal? *tmp, "test"
|
||||
compare tmp2, 0
|
||||
{
|
||||
break-if-=
|
||||
run-tests
|
||||
return 0 # TODO: get at Num-test-failures somehow
|
||||
}
|
||||
# otherwise interactive mode
|
||||
var result/ebx: int <- interactive args-on-stack
|
||||
return result
|
||||
}
|
||||
|
||||
fn interactive _args: (addr array addr array byte) -> exit-status/ebx: int {
|
||||
$interactive:body: {
|
||||
fn interactive _args: (addr array addr array byte) -> _/ebx: int {
|
||||
# initialize fs from args[1]
|
||||
var args/eax: (addr array addr array byte) <- copy _args
|
||||
var arg/eax: (addr addr array byte) <- index args, 1
|
||||
|
@ -42,8 +38,7 @@ $interactive:body: {
|
|||
compare fs, 0
|
||||
break-if-!=
|
||||
print-string-to-real-screen "file not found\n"
|
||||
exit-status <- copy 1
|
||||
break $interactive:body
|
||||
return 1
|
||||
}
|
||||
#
|
||||
enable-screen-grid-mode
|
||||
|
@ -62,8 +57,7 @@ $interactive:body: {
|
|||
}
|
||||
enable-keyboard-type-mode
|
||||
enable-screen-type-mode
|
||||
exit-status <- copy 0
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
fn render screen: (addr paginated-screen), fs: (addr buffered-file) {
|
||||
|
|
|
@ -122,8 +122,7 @@ fn start-drawing _self: (addr paginated-screen) {
|
|||
reposition-cursor self
|
||||
}
|
||||
|
||||
fn done-drawing? _self: (addr paginated-screen) -> result/eax: boolean {
|
||||
$done-drawing?:body: {
|
||||
fn done-drawing? _self: (addr paginated-screen) -> _/eax: boolean {
|
||||
# if (self->leftcol == left-margin + 1) return false
|
||||
var self/esi: (addr paginated-screen) <- copy _self
|
||||
var tmp/eax: (addr int) <- get self, left-margin
|
||||
|
@ -133,8 +132,7 @@ $done-drawing?:body: {
|
|||
$done-drawing:first-page?: {
|
||||
compare first-col, *tmp
|
||||
break-if-!=
|
||||
result <- copy 0
|
||||
break $done-drawing?:body
|
||||
return 0 # false
|
||||
}
|
||||
# return self->rightcol > self->ncols + 1
|
||||
tmp <- get self, ncols
|
||||
|
@ -149,14 +147,9 @@ $done-drawing?:body: {
|
|||
compare *tmp, max
|
||||
{
|
||||
break-if->
|
||||
result <- copy 0 # false
|
||||
break $done-drawing?:body
|
||||
return 0 # false
|
||||
}
|
||||
{
|
||||
break-if-<=
|
||||
result <- copy 1 # true
|
||||
}
|
||||
}
|
||||
return 1 # true
|
||||
}
|
||||
|
||||
fn add-grapheme _self: (addr paginated-screen), c: grapheme {
|
||||
|
|
|
@ -7,7 +7,7 @@
|
|||
# $ ./translate_mu apps/raytracing/1.mu
|
||||
# $ ./a.elf > 1.ppm
|
||||
|
||||
fn main -> exit-status/ebx: int {
|
||||
fn main -> _/ebx: int {
|
||||
print-string 0, "P3\n256 256\n255\n"
|
||||
var j/ecx: int <- copy 0xff
|
||||
{
|
||||
|
@ -27,5 +27,5 @@ fn main -> exit-status/ebx: int {
|
|||
j <- decrement
|
||||
loop
|
||||
}
|
||||
exit-status <- copy 1
|
||||
return 0
|
||||
}
|
||||
|
|
|
@ -6,7 +6,7 @@
|
|||
# $ ./translate_mu apps/raytracing/2.mu
|
||||
# $ ./a.elf > 2.ppm
|
||||
|
||||
fn main -> exit-status/ebx: int {
|
||||
fn main -> _/ebx: int {
|
||||
print-string 0, "P3\n256 256\n255\n"
|
||||
var _four/edx: int <- copy 4
|
||||
var four/xmm1: float <- convert _four
|
||||
|
@ -47,7 +47,7 @@ fn main -> exit-status/ebx: int {
|
|||
j <- decrement
|
||||
loop
|
||||
}
|
||||
exit-status <- copy 1
|
||||
return 0
|
||||
}
|
||||
|
||||
type rgb {
|
||||
|
|
|
@ -59,7 +59,7 @@ fn ray-color _in: (addr ray), _out: (addr rgb) {
|
|||
#? print-string 0, "\n"
|
||||
}
|
||||
|
||||
fn main -> exit-status/ebx: int {
|
||||
fn main -> _/ebx: int {
|
||||
|
||||
# image
|
||||
# width = 400
|
||||
|
@ -221,7 +221,7 @@ fn main -> exit-status/ebx: int {
|
|||
j <- decrement
|
||||
loop
|
||||
}
|
||||
exit-status <- copy 1
|
||||
return 0
|
||||
}
|
||||
|
||||
type ray {
|
||||
|
@ -457,18 +457,19 @@ fn vec3-unit in: (addr vec3), out: (addr vec3) {
|
|||
vec3-scale-down out, len
|
||||
}
|
||||
|
||||
fn vec3-length v: (addr vec3) -> result/xmm0: float {
|
||||
result <- vec3-length-squared v
|
||||
fn vec3-length v: (addr vec3) -> _/xmm0: float {
|
||||
var result/xmm0: float <- vec3-length-squared v
|
||||
result <- square-root result
|
||||
return result
|
||||
}
|
||||
|
||||
fn vec3-length-squared _v: (addr vec3) -> result/xmm0: float {
|
||||
fn vec3-length-squared _v: (addr vec3) -> _/xmm0: float {
|
||||
var v/esi: (addr vec3) <- copy _v
|
||||
# result = v.x * v.x
|
||||
var src/eax: (addr float) <- get v, x
|
||||
var tmp/xmm1: float <- copy *src
|
||||
tmp <- multiply tmp
|
||||
result <- copy tmp
|
||||
var result/xmm0: float <- copy tmp
|
||||
# result += v.y * v.y
|
||||
src <- get v, y
|
||||
tmp <- copy *src
|
||||
|
@ -479,4 +480,5 @@ fn vec3-length-squared _v: (addr vec3) -> result/xmm0: float {
|
|||
tmp <- copy *src
|
||||
tmp <- multiply tmp
|
||||
result <- add tmp
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -102,18 +102,19 @@ fn vec3-unit in: (addr vec3), out: (addr vec3) {
|
|||
vec3-scale-down out, len
|
||||
}
|
||||
|
||||
fn vec3-length v: (addr vec3) -> result/xmm0: float {
|
||||
result <- vec3-length-squared v
|
||||
fn vec3-length v: (addr vec3) -> _/xmm0: float {
|
||||
var result/xmm0: float <- vec3-length-squared v
|
||||
result <- square-root result
|
||||
return result
|
||||
}
|
||||
|
||||
fn vec3-length-squared _v: (addr vec3) -> result/xmm0: float {
|
||||
fn vec3-length-squared _v: (addr vec3) -> _/xmm0: float {
|
||||
var v/esi: (addr vec3) <- copy _v
|
||||
# result = v.x * v.x
|
||||
var src/eax: (addr float) <- get v, x
|
||||
var tmp/xmm1: float <- copy *src
|
||||
tmp <- multiply tmp
|
||||
result <- copy tmp
|
||||
var result/xmm0: float <- copy tmp
|
||||
# result += v.y * v.y
|
||||
src <- get v, y
|
||||
tmp <- copy *src
|
||||
|
@ -124,6 +125,7 @@ fn vec3-length-squared _v: (addr vec3) -> result/xmm0: float {
|
|||
tmp <- copy *src
|
||||
tmp <- multiply tmp
|
||||
result <- add tmp
|
||||
return result
|
||||
}
|
||||
|
||||
fn vec3-dot _v1: (addr vec3), _v2: (addr vec3) -> result/xmm0: float {
|
||||
|
|
|
@ -377,27 +377,28 @@ fn function-body functions: (addr handle function), _word: (addr handle word), o
|
|||
}
|
||||
}
|
||||
|
||||
fn body-length functions: (addr handle function), function-name: (addr handle word) -> result/eax: int {
|
||||
fn body-length functions: (addr handle function), function-name: (addr handle word) -> _/eax: int {
|
||||
var body-storage: (handle line)
|
||||
var body-ah/edi: (addr handle line) <- address body-storage
|
||||
function-body functions, function-name, body-ah
|
||||
var body/eax: (addr line) <- lookup *body-ah
|
||||
result <- line-length body
|
||||
var result/eax: int <- line-length body
|
||||
return result
|
||||
}
|
||||
|
||||
fn line-length _in: (addr line) -> result/eax: int {
|
||||
fn line-length _in: (addr line) -> _/eax: int {
|
||||
var in/esi: (addr line) <- copy _in
|
||||
var curr-ah/ecx: (addr handle word) <- get in, data
|
||||
var out/edi: int <- copy 0
|
||||
var result/edi: int <- copy 0
|
||||
{
|
||||
var curr/eax: (addr word) <- lookup *curr-ah
|
||||
compare curr, 0
|
||||
break-if-=
|
||||
curr-ah <- get curr, next
|
||||
out <- increment
|
||||
result <- increment
|
||||
loop
|
||||
}
|
||||
result <- copy out
|
||||
return result
|
||||
}
|
||||
|
||||
fn populate-text-with _out: (addr handle array byte), _in: (addr array byte) {
|
||||
|
@ -440,9 +441,8 @@ fn initialize-path-from-line _line: (addr line), _out: (addr handle call-path-el
|
|||
copy-object src, dest
|
||||
}
|
||||
|
||||
fn find-in-call-paths call-paths: (addr handle call-path), needle: (addr handle call-path-element) -> result/eax: boolean {
|
||||
fn find-in-call-paths call-paths: (addr handle call-path), needle: (addr handle call-path-element) -> _/eax: boolean {
|
||||
var curr-ah/esi: (addr handle call-path) <- copy call-paths
|
||||
var out/edi: boolean <- copy 0 # false
|
||||
$find-in-call-path:loop: {
|
||||
var curr/eax: (addr call-path) <- lookup *curr-ah
|
||||
compare curr, 0
|
||||
|
@ -453,18 +453,16 @@ fn find-in-call-paths call-paths: (addr handle call-path), needle: (addr handle
|
|||
compare match?, 0 # false
|
||||
{
|
||||
break-if-=
|
||||
out <- copy 1 # true
|
||||
break $find-in-call-path:loop
|
||||
return 1 # true
|
||||
}
|
||||
}
|
||||
curr-ah <- get curr, next
|
||||
loop
|
||||
}
|
||||
result <- copy out
|
||||
return 0 # false
|
||||
}
|
||||
|
||||
fn call-path-element-match? _x: (addr handle call-path-element), _y: (addr handle call-path-element) -> result/eax: boolean {
|
||||
$call-path-element-match?:body: {
|
||||
fn call-path-element-match? _x: (addr handle call-path-element), _y: (addr handle call-path-element) -> _/eax: boolean {
|
||||
var x-ah/eax: (addr handle call-path-element) <- copy _x
|
||||
var x-a/eax: (addr call-path-element) <- lookup *x-ah
|
||||
var x/esi: (addr call-path-element) <- copy x-a
|
||||
|
@ -474,20 +472,17 @@ $call-path-element-match?:body: {
|
|||
compare x, y
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $call-path-element-match?:body
|
||||
return 1 # true
|
||||
}
|
||||
compare x, 0
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 0 # false
|
||||
break $call-path-element-match?:body
|
||||
return 0 # false
|
||||
}
|
||||
compare y, 0
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 0 # false
|
||||
break $call-path-element-match?:body
|
||||
return 0 # false
|
||||
}
|
||||
# compare word addresses, not contents
|
||||
var x-data-ah/ecx: (addr handle word) <- get x, word
|
||||
|
@ -504,13 +499,12 @@ $call-path-element-match?:body: {
|
|||
compare x-data, y-data
|
||||
{
|
||||
break-if-=
|
||||
result <- copy 0 # false
|
||||
break $call-path-element-match?:body
|
||||
return 0 # false
|
||||
}
|
||||
var x-next/ecx: (addr handle call-path-element) <- get x, next
|
||||
var y-next/eax: (addr handle call-path-element) <- get y, next
|
||||
result <- call-path-element-match? x-next, y-next
|
||||
}
|
||||
var result/eax: boolean <- call-path-element-match? x-next, y-next
|
||||
return result
|
||||
}
|
||||
|
||||
# order is irrelevant
|
||||
|
@ -551,7 +545,6 @@ fn deep-copy-call-path-element _src: (addr handle call-path-element), _dest: (ad
|
|||
}
|
||||
|
||||
fn delete-in-call-path list: (addr handle call-path), needle: (addr handle call-path-element) {
|
||||
$delete-in-call-path:body: {
|
||||
var curr-ah/esi: (addr handle call-path) <- copy list
|
||||
$delete-in-call-path:loop: {
|
||||
var _curr/eax: (addr call-path) <- lookup *curr-ah
|
||||
|
@ -573,7 +566,6 @@ $delete-in-call-path:body: {
|
|||
loop
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn increment-final-element list: (addr handle call-path-element) {
|
||||
var final-ah/eax: (addr handle call-path-element) <- copy list
|
||||
|
@ -658,7 +650,6 @@ fn drop-nested-calls _list: (addr handle call-path-element) {
|
|||
}
|
||||
|
||||
fn dump-call-path-element screen: (addr screen), _x-ah: (addr handle call-path-element) {
|
||||
$dump-call-path-element:body: {
|
||||
var x-ah/ecx: (addr handle call-path-element) <- copy _x-ah
|
||||
var _x/eax: (addr call-path-element) <- lookup *x-ah
|
||||
var x/esi: (addr call-path-element) <- copy _x
|
||||
|
@ -672,17 +663,12 @@ $dump-call-path-element:body: {
|
|||
break-if-=
|
||||
print-string screen, " "
|
||||
dump-call-path-element screen, next-ah
|
||||
break $dump-call-path-element:body
|
||||
return
|
||||
}
|
||||
{
|
||||
break-if-!=
|
||||
print-string screen, "\n"
|
||||
}
|
||||
}
|
||||
print-string screen, "\n"
|
||||
}
|
||||
|
||||
fn dump-call-paths screen: (addr screen), _x-ah: (addr handle call-path) {
|
||||
$dump-call-paths:body: {
|
||||
var x-ah/ecx: (addr handle call-path) <- copy _x-ah
|
||||
var x/eax: (addr call-path) <- lookup *x-ah
|
||||
compare x, 0
|
||||
|
@ -695,7 +681,5 @@ $dump-call-paths:body: {
|
|||
{
|
||||
break-if-=
|
||||
dump-call-paths screen, next-ah
|
||||
break $dump-call-paths:body
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -760,61 +760,65 @@ fn copy-unbound-words-to-args _functions: (addr handle function) {
|
|||
}
|
||||
}
|
||||
|
||||
fn bound-function? w: (addr word), functions-ah: (addr handle function) -> result/ebx: boolean {
|
||||
result <- copy 1 # true
|
||||
# if w == "+" return true
|
||||
var subresult/eax: boolean <- word-equal? w, "+"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "-" return true
|
||||
subresult <- word-equal? w, "-"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "*" return true
|
||||
subresult <- word-equal? w, "*"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "len" return true
|
||||
subresult <- word-equal? w, "len"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "open" return true
|
||||
subresult <- word-equal? w, "open"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "read" return true
|
||||
subresult <- word-equal? w, "read"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "slurp" return true
|
||||
subresult <- word-equal? w, "slurp"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "lines" return true
|
||||
subresult <- word-equal? w, "lines"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "dup" return true
|
||||
subresult <- word-equal? w, "dup"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "swap" return true
|
||||
subresult <- word-equal? w, "swap"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# return w in functions
|
||||
var out-h: (handle function)
|
||||
var out/eax: (addr handle function) <- address out-h
|
||||
callee functions-ah, w, out
|
||||
var found?/eax: (addr function) <- lookup *out
|
||||
result <- copy found?
|
||||
fn bound-function? w: (addr word), functions-ah: (addr handle function) -> _/ebx: boolean {
|
||||
var result/ebx: boolean <- copy 1 # true
|
||||
{
|
||||
# if w == "+" return true
|
||||
var subresult/eax: boolean <- word-equal? w, "+"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "-" return true
|
||||
subresult <- word-equal? w, "-"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "*" return true
|
||||
subresult <- word-equal? w, "*"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "len" return true
|
||||
subresult <- word-equal? w, "len"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "open" return true
|
||||
subresult <- word-equal? w, "open"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "read" return true
|
||||
subresult <- word-equal? w, "read"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "slurp" return true
|
||||
subresult <- word-equal? w, "slurp"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "lines" return true
|
||||
subresult <- word-equal? w, "lines"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "dup" return true
|
||||
subresult <- word-equal? w, "dup"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# if w == "swap" return true
|
||||
subresult <- word-equal? w, "swap"
|
||||
compare subresult, 0 # false
|
||||
break-if-!=
|
||||
# return w in functions
|
||||
var out-h: (handle function)
|
||||
var out/eax: (addr handle function) <- address out-h
|
||||
callee functions-ah, w, out
|
||||
var found?/eax: (addr function) <- lookup *out
|
||||
result <- copy found?
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn arg-exists? _f-ah: (addr handle function), arg: (addr word) -> result/ebx: boolean {
|
||||
fn arg-exists? _f-ah: (addr handle function), arg: (addr word) -> _/ebx: boolean {
|
||||
var f-ah/eax: (addr handle function) <- copy *_f-ah
|
||||
var f/eax: (addr function) <- lookup *f-ah
|
||||
var args-ah/eax: (addr handle word) <- get f, args
|
||||
result <- word-exists? args-ah, arg
|
||||
var result/ebx: boolean <- word-exists? args-ah, arg
|
||||
return result
|
||||
}
|
||||
|
||||
# construct a call to `f` with copies of exactly its args
|
||||
|
@ -1177,32 +1181,33 @@ fn render-line-without-stack screen: (addr screen), _line: (addr line), curr-row
|
|||
}
|
||||
}
|
||||
|
||||
fn call-depth-at-cursor _sandbox: (addr sandbox) -> result/eax: int {
|
||||
fn call-depth-at-cursor _sandbox: (addr sandbox) -> _/eax: int {
|
||||
var sandbox/esi: (addr sandbox) <- copy _sandbox
|
||||
var cursor-call-path/edi: (addr handle call-path-element) <- get sandbox, cursor-call-path
|
||||
result <- call-path-element-length cursor-call-path
|
||||
result <- add 2 # input-row-1
|
||||
var result/eax: int <- call-path-element-length cursor-call-path
|
||||
result <- add 2 # input-row - 1
|
||||
return result
|
||||
}
|
||||
|
||||
fn call-path-element-length _x: (addr handle call-path-element) -> result/eax: int {
|
||||
fn call-path-element-length _x: (addr handle call-path-element) -> _/eax: int {
|
||||
var curr-ah/ecx: (addr handle call-path-element) <- copy _x
|
||||
var out/edi: int <- copy 0
|
||||
var result/edi: int <- copy 0
|
||||
{
|
||||
var curr/eax: (addr call-path-element) <- lookup *curr-ah
|
||||
compare curr, 0
|
||||
break-if-=
|
||||
curr-ah <- get curr, next
|
||||
out <- increment
|
||||
result <- increment
|
||||
loop
|
||||
}
|
||||
result <- copy out
|
||||
return result
|
||||
}
|
||||
|
||||
# Render the line of words in line, along with the state of the stack under each word.
|
||||
# Also render any expanded function calls using recursive calls.
|
||||
#
|
||||
# Along the way, compute the column the cursor should be positioned at (cursor-col-addr).
|
||||
fn render-line screen: (addr screen), functions: (addr handle function), bindings: (addr table), first-line: (addr line), _line: (addr line), expanded-words: (addr handle call-path), top-row: int, left-col: int, curr-path: (addr handle call-path-element), cursor-word: (addr word), cursor-call-path: (addr handle call-path-element), cursor-row-addr: (addr int), cursor-col-addr: (addr int) -> right-col/ecx: int {
|
||||
fn render-line screen: (addr screen), functions: (addr handle function), bindings: (addr table), first-line: (addr line), _line: (addr line), expanded-words: (addr handle call-path), top-row: int, left-col: int, curr-path: (addr handle call-path-element), cursor-word: (addr word), cursor-call-path: (addr handle call-path-element), cursor-row-addr: (addr int), cursor-col-addr: (addr int) -> _/ecx: int {
|
||||
#? print-string 0, "--\n"
|
||||
# curr-word
|
||||
var line/esi: (addr line) <- copy _line
|
||||
|
@ -1331,7 +1336,7 @@ fn render-line screen: (addr screen), functions: (addr handle function), binding
|
|||
increment-final-element curr-path
|
||||
loop
|
||||
}
|
||||
right-col <- copy curr-col
|
||||
return curr-col
|
||||
}
|
||||
|
||||
fn callee functions: (addr handle function), word: (addr word), out: (addr handle function) {
|
||||
|
@ -1346,7 +1351,7 @@ fn callee functions: (addr handle function), word: (addr word), out: (addr handl
|
|||
# - starting somewhere below at left-col: the stack result from interpreting first-world to final-word (inclusive)
|
||||
#
|
||||
# Return the farthest column written.
|
||||
fn render-column screen: (addr screen), functions: (addr handle function), bindings: (addr table), first-line: (addr line), line: (addr line), final-word: (addr word), top-row: int, left-col: int -> right-col/ecx: int {
|
||||
fn render-column screen: (addr screen), functions: (addr handle function), bindings: (addr table), first-line: (addr line), line: (addr line), final-word: (addr word), top-row: int, left-col: int -> _/ecx: int {
|
||||
#? print-string 0, "render-column\n"
|
||||
var max-width/esi: int <- copy 0
|
||||
{
|
||||
|
@ -1396,13 +1401,14 @@ fn render-column screen: (addr screen), functions: (addr handle function), bindi
|
|||
}
|
||||
|
||||
# post-process right-col
|
||||
right-col <- copy left-col
|
||||
var right-col/ecx: int <- copy left-col
|
||||
right-col <- add max-width
|
||||
right-col <- add 1 # margin-right
|
||||
#? print-int32-decimal 0, left-col
|
||||
#? print-string 0, " => "
|
||||
#? print-int32-decimal 0, right-col
|
||||
#? print-string 0, "\n"
|
||||
return right-col
|
||||
}
|
||||
|
||||
fn render-value screen: (addr screen), _val: (addr value), max-width: int {
|
||||
|
@ -1522,8 +1528,9 @@ fn render-array screen: (addr screen), _a: (addr array value) {
|
|||
print-grapheme screen, 0x5d # ']'
|
||||
}
|
||||
|
||||
fn hash-color val: int -> result/eax: int {
|
||||
result <- try-modulo val, 7 # assumes that 7 is always the background color
|
||||
fn hash-color val: int -> _/eax: int {
|
||||
var result/eax: int <- try-modulo val, 7 # assumes that 7 is always the background color
|
||||
return result
|
||||
}
|
||||
|
||||
fn clear-canvas _env: (addr environment) {
|
||||
|
@ -1604,7 +1611,7 @@ fn clear-canvas _env: (addr environment) {
|
|||
}
|
||||
|
||||
# only single-line functions supported for now
|
||||
fn render-function screen: (addr screen), row: int, col: int, _f: (addr function) -> out-row/ebx: int {
|
||||
fn render-function screen: (addr screen), row: int, col: int, _f: (addr function) -> _/ebx: int {
|
||||
var f/esi: (addr function) <- copy _f
|
||||
var args/ecx: (addr handle word) <- get f, args
|
||||
move-cursor screen, row, col
|
||||
|
@ -1622,48 +1629,41 @@ fn render-function screen: (addr screen), row: int, col: int, _f: (addr function
|
|||
var body/eax: (addr line) <- lookup *body-ah
|
||||
var body-words-ah/eax: (addr handle word) <- get body, data
|
||||
print-words screen, body-words-ah
|
||||
out-row <- copy row
|
||||
return row
|
||||
}
|
||||
|
||||
fn real-grapheme? g: grapheme -> result/eax: boolean {
|
||||
$real-grapheme?:body: {
|
||||
fn real-grapheme? g: grapheme -> _/eax: boolean {
|
||||
# if g == newline return true
|
||||
compare g, 0xa
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $real-grapheme?:body
|
||||
return 1 # true
|
||||
}
|
||||
# if g == tab return true
|
||||
compare g, 9
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $real-grapheme?:body
|
||||
return 1 # true
|
||||
}
|
||||
# if g < 32 return false
|
||||
compare g, 0x20
|
||||
{
|
||||
break-if->=
|
||||
result <- copy 0 # false
|
||||
break $real-grapheme?:body
|
||||
return 0 # false
|
||||
}
|
||||
# if g <= 255 return true
|
||||
compare g, 0xff
|
||||
{
|
||||
break-if->
|
||||
result <- copy 1 # true
|
||||
break $real-grapheme?:body
|
||||
return 1 # true
|
||||
}
|
||||
# if (g&0xff == Esc) it's an escape sequence
|
||||
and-with g, 0xff
|
||||
compare g, 0x1b # Esc
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 0 # false
|
||||
break $real-grapheme?:body
|
||||
return 0 # false
|
||||
}
|
||||
# otherwise return true
|
||||
result <- copy 1 # true
|
||||
}
|
||||
return 1 # true
|
||||
}
|
||||
|
|
|
@ -88,15 +88,16 @@ fn render-gap-buffer screen: (addr screen), _gap: (addr gap-buffer) {
|
|||
render-stack-from-top right, screen
|
||||
}
|
||||
|
||||
fn gap-buffer-length _gap: (addr gap-buffer) -> result/eax: int {
|
||||
fn gap-buffer-length _gap: (addr gap-buffer) -> _/eax: int {
|
||||
var gap/esi: (addr gap-buffer) <- copy _gap
|
||||
var left/eax: (addr grapheme-stack) <- get gap, left
|
||||
var tmp/eax: (addr int) <- get left, top
|
||||
var left-length/ecx: int <- copy *tmp
|
||||
var right/esi: (addr grapheme-stack) <- get gap, right
|
||||
tmp <- get right, top
|
||||
result <- copy *tmp
|
||||
var result/eax: int <- copy *tmp
|
||||
result <- add left-length
|
||||
return result
|
||||
}
|
||||
|
||||
fn add-grapheme-at-gap _self: (addr gap-buffer), g: grapheme {
|
||||
|
@ -121,63 +122,59 @@ fn gap-to-end self: (addr gap-buffer) {
|
|||
}
|
||||
}
|
||||
|
||||
fn gap-at-start? _self: (addr gap-buffer) -> result/eax: boolean {
|
||||
fn gap-at-start? _self: (addr gap-buffer) -> _/eax: boolean {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
var left/eax: (addr grapheme-stack) <- get self, left
|
||||
result <- grapheme-stack-empty? left
|
||||
var result/eax: boolean <- grapheme-stack-empty? left
|
||||
return result
|
||||
}
|
||||
|
||||
fn gap-at-end? _self: (addr gap-buffer) -> result/eax: boolean {
|
||||
fn gap-at-end? _self: (addr gap-buffer) -> _/eax: boolean {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
var right/eax: (addr grapheme-stack) <- get self, right
|
||||
result <- grapheme-stack-empty? right
|
||||
var result/eax: boolean <- grapheme-stack-empty? right
|
||||
return result
|
||||
}
|
||||
|
||||
fn gap-right _self: (addr gap-buffer) -> result/eax: grapheme {
|
||||
$gap-right:body: {
|
||||
fn gap-right _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
var g/edx: grapheme <- copy 0
|
||||
{
|
||||
var right/ecx: (addr grapheme-stack) <- get self, right
|
||||
result <- pop-grapheme-stack right
|
||||
compare result, -1
|
||||
break-if-= $gap-right:body
|
||||
g <- copy result
|
||||
}
|
||||
var g/eax: grapheme <- copy 0
|
||||
var right/ecx: (addr grapheme-stack) <- get self, right
|
||||
g <- pop-grapheme-stack right
|
||||
compare g, -1
|
||||
{
|
||||
break-if-=
|
||||
var left/ecx: (addr grapheme-stack) <- get self, left
|
||||
push-grapheme-stack left, g
|
||||
}
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
fn gap-left _self: (addr gap-buffer) -> result/eax: grapheme {
|
||||
$gap-left:body: {
|
||||
fn gap-left _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
var g/edx: grapheme <- copy 0
|
||||
var g/eax: grapheme <- copy 0
|
||||
{
|
||||
var left/ecx: (addr grapheme-stack) <- get self, left
|
||||
result <- pop-grapheme-stack left
|
||||
compare result, -1
|
||||
break-if-= $gap-left:body
|
||||
g <- copy result
|
||||
g <- pop-grapheme-stack left
|
||||
}
|
||||
compare g, -1
|
||||
{
|
||||
break-if-=
|
||||
var right/ecx: (addr grapheme-stack) <- get self, right
|
||||
push-grapheme-stack right, g
|
||||
}
|
||||
}
|
||||
return g
|
||||
}
|
||||
|
||||
fn gap-index _self: (addr gap-buffer) -> result/eax: int {
|
||||
fn gap-index _self: (addr gap-buffer) -> _/eax: int {
|
||||
var self/eax: (addr gap-buffer) <- copy _self
|
||||
var left/eax: (addr grapheme-stack) <- get self, left
|
||||
var top-addr/eax: (addr int) <- get left, top
|
||||
result <- copy *top-addr
|
||||
var result/eax: int <- copy *top-addr
|
||||
return result
|
||||
}
|
||||
|
||||
fn first-grapheme-in-gap-buffer _self: (addr gap-buffer) -> result/eax: grapheme {
|
||||
$first-grapheme-in-gap-buffer:body: {
|
||||
fn first-grapheme-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
# try to read from left
|
||||
var left/eax: (addr grapheme-stack) <- get self, left
|
||||
|
@ -188,8 +185,7 @@ $first-grapheme-in-gap-buffer:body: {
|
|||
var data-ah/eax: (addr handle array grapheme) <- get left, data
|
||||
var data/eax: (addr array grapheme) <- lookup *data-ah
|
||||
var result-addr/eax: (addr grapheme) <- index data, 0
|
||||
result <- copy *result-addr
|
||||
break $first-grapheme-in-gap-buffer:body
|
||||
return *result-addr
|
||||
}
|
||||
# try to read from right
|
||||
var right/eax: (addr grapheme-stack) <- get self, right
|
||||
|
@ -202,16 +198,13 @@ $first-grapheme-in-gap-buffer:body: {
|
|||
var top/ecx: int <- copy *top-addr
|
||||
top <- decrement
|
||||
var result-addr/eax: (addr grapheme) <- index data, top
|
||||
result <- copy *result-addr
|
||||
break $first-grapheme-in-gap-buffer:body
|
||||
return *result-addr
|
||||
}
|
||||
# give up
|
||||
result <- copy -1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fn grapheme-before-cursor-in-gap-buffer _self: (addr gap-buffer) -> result/eax: grapheme {
|
||||
$grapheme-before-cursor-in-gap-buffer:body: {
|
||||
fn grapheme-before-cursor-in-gap-buffer _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
# try to read from left
|
||||
var left/ecx: (addr grapheme-stack) <- get self, left
|
||||
|
@ -219,13 +212,12 @@ $grapheme-before-cursor-in-gap-buffer:body: {
|
|||
compare *top-addr, 0
|
||||
{
|
||||
break-if-<=
|
||||
result <- pop-grapheme-stack left
|
||||
var result/eax: grapheme <- pop-grapheme-stack left
|
||||
push-grapheme-stack left, result
|
||||
break $grapheme-before-cursor-in-gap-buffer:body
|
||||
return result
|
||||
}
|
||||
# give up
|
||||
result <- copy -1
|
||||
}
|
||||
return -1
|
||||
}
|
||||
|
||||
fn delete-before-gap _self: (addr gap-buffer) {
|
||||
|
@ -234,14 +226,14 @@ fn delete-before-gap _self: (addr gap-buffer) {
|
|||
var dummy/eax: grapheme <- pop-grapheme-stack left
|
||||
}
|
||||
|
||||
fn pop-after-gap _self: (addr gap-buffer) -> result/eax: grapheme {
|
||||
fn pop-after-gap _self: (addr gap-buffer) -> _/eax: grapheme {
|
||||
var self/eax: (addr gap-buffer) <- copy _self
|
||||
var right/eax: (addr grapheme-stack) <- get self, right
|
||||
result <- pop-grapheme-stack right
|
||||
var result/eax: grapheme <- pop-grapheme-stack right
|
||||
return result
|
||||
}
|
||||
|
||||
fn gap-buffer-equal? _self: (addr gap-buffer), s: (addr array byte) -> result/eax: boolean {
|
||||
$gap-buffer-equal?:body: {
|
||||
fn gap-buffer-equal? _self: (addr gap-buffer), s: (addr array byte) -> _/eax: boolean {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
# complication: graphemes may be multiple bytes
|
||||
# so don't rely on length
|
||||
|
@ -251,17 +243,23 @@ $gap-buffer-equal?:body: {
|
|||
write expected-stream, s
|
||||
# compare left
|
||||
var left/edx: (addr grapheme-stack) <- get self, left
|
||||
result <- prefix-match? left, expected-stream
|
||||
var result/eax: boolean <- prefix-match? left, expected-stream
|
||||
compare result, 0 # false
|
||||
break-if-= $gap-buffer-equal?:body
|
||||
{
|
||||
break-if-!=
|
||||
return result
|
||||
}
|
||||
# compare right
|
||||
var right/edx: (addr grapheme-stack) <- get self, right
|
||||
result <- suffix-match? right, expected-stream
|
||||
compare result, 0 # false
|
||||
break-if-= $gap-buffer-equal?:body
|
||||
{
|
||||
break-if-!=
|
||||
return result
|
||||
}
|
||||
# ensure there's nothing left over
|
||||
result <- stream-empty? expected-stream
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn test-gap-buffer-equal-from-end? {
|
||||
|
@ -331,12 +329,15 @@ fn copy-gap-buffer _src-ah: (addr handle gap-buffer), _dest-ah: (addr handle gap
|
|||
copy-grapheme-stack src, dest
|
||||
}
|
||||
|
||||
fn gap-buffer-is-decimal-integer? _self: (addr gap-buffer) -> result/eax: boolean {
|
||||
fn gap-buffer-is-decimal-integer? _self: (addr gap-buffer) -> _/eax: boolean {
|
||||
var self/esi: (addr gap-buffer) <- copy _self
|
||||
var curr/ecx: (addr grapheme-stack) <- get self, left
|
||||
result <- grapheme-stack-is-decimal-integer? curr
|
||||
compare result, 0 # false
|
||||
break-if-=
|
||||
curr <- get self, right
|
||||
result <- grapheme-stack-is-decimal-integer? curr
|
||||
var result/eax: boolean <- grapheme-stack-is-decimal-integer? curr
|
||||
{
|
||||
compare result, 0 # false
|
||||
break-if-=
|
||||
curr <- get self, right
|
||||
result <- grapheme-stack-is-decimal-integer? curr
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -17,18 +17,15 @@ fn clear-grapheme-stack _self: (addr grapheme-stack) {
|
|||
copy-to *top, 0
|
||||
}
|
||||
|
||||
fn grapheme-stack-empty? _self: (addr grapheme-stack) -> result/eax: boolean {
|
||||
$grapheme-stack-empty?:body: {
|
||||
fn grapheme-stack-empty? _self: (addr grapheme-stack) -> _/eax: boolean {
|
||||
var self/esi: (addr grapheme-stack) <- copy _self
|
||||
var top/eax: (addr int) <- get self, top
|
||||
compare *top, 0
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $grapheme-stack-empty?:body
|
||||
return 1 # true
|
||||
}
|
||||
result <- copy 0 # false
|
||||
}
|
||||
return 0 # false
|
||||
}
|
||||
|
||||
fn push-grapheme-stack _self: (addr grapheme-stack), _val: grapheme {
|
||||
|
@ -43,23 +40,20 @@ fn push-grapheme-stack _self: (addr grapheme-stack), _val: grapheme {
|
|||
add-to *top-addr, 1
|
||||
}
|
||||
|
||||
fn pop-grapheme-stack _self: (addr grapheme-stack) -> val/eax: grapheme {
|
||||
$pop-grapheme-stack:body: {
|
||||
fn pop-grapheme-stack _self: (addr grapheme-stack) -> _/eax: grapheme {
|
||||
var self/esi: (addr grapheme-stack) <- copy _self
|
||||
var top-addr/ecx: (addr int) <- get self, top
|
||||
{
|
||||
compare *top-addr, 0
|
||||
break-if->
|
||||
val <- copy -1
|
||||
break $pop-grapheme-stack:body
|
||||
return -1
|
||||
}
|
||||
subtract-from *top-addr, 1
|
||||
var data-ah/edx: (addr handle array grapheme) <- get self, data
|
||||
var data/eax: (addr array grapheme) <- lookup *data-ah
|
||||
var top/edx: int <- copy *top-addr
|
||||
var result-addr/eax: (addr grapheme) <- index data, top
|
||||
val <- copy *result-addr
|
||||
}
|
||||
return *result-addr
|
||||
}
|
||||
|
||||
fn copy-grapheme-stack _src: (addr grapheme-stack), dest: (addr grapheme-stack) {
|
||||
|
@ -120,8 +114,7 @@ fn render-stack-from-top _self: (addr grapheme-stack), screen: (addr screen) {
|
|||
|
||||
# compare from bottom
|
||||
# beware: modifies 'stream', which must be disposed of after a false result
|
||||
fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> result/eax: boolean {
|
||||
$prefix-match?:body: {
|
||||
fn prefix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
|
||||
var self/esi: (addr grapheme-stack) <- copy _self
|
||||
var data-ah/edi: (addr handle array grapheme) <- get self, data
|
||||
var _data/eax: (addr array grapheme) <- lookup *data-ah
|
||||
|
@ -138,21 +131,18 @@ $prefix-match?:body: {
|
|||
{
|
||||
compare expected, *curr-a
|
||||
break-if-=
|
||||
result <- copy 0 # false
|
||||
break $prefix-match?:body
|
||||
return 0 # false
|
||||
}
|
||||
}
|
||||
i <- increment
|
||||
loop
|
||||
}
|
||||
result <- copy 1 # true
|
||||
}
|
||||
return 1 # true
|
||||
}
|
||||
|
||||
# compare from bottom
|
||||
# beware: modifies 'stream', which must be disposed of after a false result
|
||||
fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> result/eax: boolean {
|
||||
$suffix-match?:body: {
|
||||
fn suffix-match? _self: (addr grapheme-stack), s: (addr stream byte) -> _/eax: boolean {
|
||||
var self/esi: (addr grapheme-stack) <- copy _self
|
||||
var data-ah/edi: (addr handle array grapheme) <- get self, data
|
||||
var _data/eax: (addr array grapheme) <- lookup *data-ah
|
||||
|
@ -170,24 +160,23 @@ $suffix-match?:body: {
|
|||
{
|
||||
compare expected, *curr-a
|
||||
break-if-=
|
||||
result <- copy 0 # false
|
||||
break $suffix-match?:body
|
||||
return 0 # false
|
||||
}
|
||||
}
|
||||
i <- decrement
|
||||
loop
|
||||
}
|
||||
result <- copy 1 # true
|
||||
}
|
||||
return 1 # true
|
||||
}
|
||||
|
||||
fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> result/eax: boolean {
|
||||
fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> _/eax: boolean {
|
||||
var self/esi: (addr grapheme-stack) <- copy _self
|
||||
var data-ah/eax: (addr handle array grapheme) <- get self, data
|
||||
var _data/eax: (addr array grapheme) <- lookup *data-ah
|
||||
var data/edx: (addr array grapheme) <- copy _data
|
||||
var top-addr/ecx: (addr int) <- get self, top
|
||||
var i/ebx: int <- copy 0
|
||||
var result/eax: boolean <- copy 1 # true
|
||||
$grapheme-stack-is-integer?:loop: {
|
||||
compare i, *top-addr
|
||||
break-if->=
|
||||
|
@ -198,4 +187,5 @@ fn grapheme-stack-is-decimal-integer? _self: (addr grapheme-stack) -> result/eax
|
|||
i <- increment
|
||||
loop
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -29,41 +29,35 @@ fn push-int-stack _self: (addr int-stack), _val: int {
|
|||
add-to *top-addr, 1
|
||||
}
|
||||
|
||||
fn pop-int-stack _self: (addr int-stack) -> val/eax: int {
|
||||
$pop-int-stack:body: {
|
||||
fn pop-int-stack _self: (addr int-stack) -> _/eax: int {
|
||||
var self/esi: (addr int-stack) <- copy _self
|
||||
var top-addr/ecx: (addr int) <- get self, top
|
||||
{
|
||||
compare *top-addr, 0
|
||||
break-if->
|
||||
val <- copy 0
|
||||
break $pop-int-stack:body
|
||||
return 0
|
||||
}
|
||||
subtract-from *top-addr, 1
|
||||
var data-ah/edx: (addr handle array int) <- get self, data
|
||||
var data/eax: (addr array int) <- lookup *data-ah
|
||||
var top/edx: int <- copy *top-addr
|
||||
var result-addr/eax: (addr int) <- index data, top
|
||||
val <- copy *result-addr
|
||||
}
|
||||
return *result-addr
|
||||
}
|
||||
|
||||
fn int-stack-empty? _self: (addr int-stack) -> result/eax: boolean {
|
||||
$int-stack-empty?:body: {
|
||||
fn int-stack-empty? _self: (addr int-stack) -> _/eax: boolean {
|
||||
var self/esi: (addr int-stack) <- copy _self
|
||||
var top-addr/eax: (addr int) <- get self, top
|
||||
compare *top-addr, 0
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $int-stack-empty?:body
|
||||
return 1 # true
|
||||
}
|
||||
result <- copy 0 # false
|
||||
}
|
||||
return 0 # false
|
||||
}
|
||||
|
||||
fn int-stack-length _self: (addr int-stack) -> result/eax: int {
|
||||
fn int-stack-length _self: (addr int-stack) -> _/eax: int {
|
||||
var self/esi: (addr int-stack) <- copy _self
|
||||
var top-addr/eax: (addr int) <- get self, top
|
||||
result <- copy *top-addr
|
||||
return *top-addr
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
||||
fn main args-on-stack: (addr array addr array byte) -> _/ebx: int {
|
||||
var args/eax: (addr array addr array byte) <- copy args-on-stack
|
||||
var len/ecx: int <- length args
|
||||
$main-body: {
|
||||
|
@ -12,8 +12,7 @@ fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
{
|
||||
break-if-=
|
||||
run-tests
|
||||
exit-status <- copy 0 # TODO: get at Num-test-failures somehow
|
||||
break $main-body
|
||||
return 0 # TODO: get at Num-test-failures somehow
|
||||
}
|
||||
# if single arg is 'screen', run in full-screen mode
|
||||
tmp2 <- string-equal? *tmp, "screen"
|
||||
|
@ -21,8 +20,7 @@ fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
{
|
||||
break-if-=
|
||||
interactive
|
||||
exit-status <- copy 0
|
||||
break $main-body
|
||||
return 0
|
||||
}
|
||||
# if single arg is 'type', run in typewriter mode
|
||||
tmp2 <- string-equal? *tmp, "type"
|
||||
|
@ -30,8 +28,7 @@ fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
{
|
||||
break-if-=
|
||||
repl
|
||||
exit-status <- copy 0
|
||||
break $main-body
|
||||
return 0
|
||||
}
|
||||
# if single arg is 'test' ...
|
||||
tmp2 <- string-equal? *tmp, "test2"
|
||||
|
@ -39,8 +36,7 @@ fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
{
|
||||
break-if-=
|
||||
test
|
||||
exit-status <- copy 0
|
||||
break $main-body
|
||||
return 0
|
||||
}
|
||||
}
|
||||
# otherwise error message
|
||||
|
@ -48,7 +44,7 @@ fn main args-on-stack: (addr array addr array byte) -> exit-status/ebx: int {
|
|||
print-string-to-real-screen " to run tests: tile test\n"
|
||||
print-string-to-real-screen " full-screen mode: tile screen\n"
|
||||
print-string-to-real-screen " regular REPL: tile type\n"
|
||||
exit-status <- copy 1
|
||||
return 1
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -72,16 +68,17 @@ fn interactive {
|
|||
}
|
||||
|
||||
fn test {
|
||||
var env-storage: environment
|
||||
var env/esi: (addr environment) <- address env-storage
|
||||
initialize-environment-with-fake-screen env, 5, 0xa
|
||||
var g/eax: grapheme <- copy 0x22 # '"'
|
||||
process env, g
|
||||
g <- copy 0x61 # 'a'
|
||||
process env, g
|
||||
g <- copy 0x22 # '"'
|
||||
process env, g
|
||||
render env
|
||||
test-surface-pin-at-origin
|
||||
#? var env-storage: environment
|
||||
#? var env/esi: (addr environment) <- address env-storage
|
||||
#? initialize-environment-with-fake-screen env, 5, 0xa
|
||||
#? var g/eax: grapheme <- copy 0x22 # '"'
|
||||
#? process env, g
|
||||
#? g <- copy 0x61 # 'a'
|
||||
#? process env, g
|
||||
#? g <- copy 0x22 # '"'
|
||||
#? process env, g
|
||||
#? render env
|
||||
}
|
||||
|
||||
fn repl {
|
||||
|
|
|
@ -560,10 +560,10 @@ fn bind-args _callee: (addr function), _caller-stack: (addr value-stack), table:
|
|||
|
||||
# Copy of 'simplify' that just tracks the maximum stack depth needed
|
||||
# Doesn't actually need to simulate the stack, since every word has a predictable effect.
|
||||
fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/edi: int {
|
||||
fn max-stack-depth first-word: (addr word), final-word: (addr word) -> _/edi: int {
|
||||
var curr-word/eax: (addr word) <- copy first-word
|
||||
var curr-depth/ecx: int <- copy 0
|
||||
result <- copy 0
|
||||
var result/edi: int <- copy 0
|
||||
$max-stack-depth:loop: {
|
||||
$max-stack-depth:process-word: {
|
||||
# handle operators
|
||||
|
@ -606,4 +606,5 @@ fn max-stack-depth first-word: (addr word), final-word: (addr word) -> result/ed
|
|||
#
|
||||
loop
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
|
|
@ -166,107 +166,102 @@ fn print-screen-cell screen: (addr screen), _cell: (addr screen-cell) {
|
|||
#? print-string-to-real-screen "\n"
|
||||
}
|
||||
|
||||
fn surface-screen-cell-index _self: (addr surface), row: int, col: int -> result/eax: int {
|
||||
fn surface-screen-cell-index _self: (addr surface), row: int, col: int -> _/eax: int {
|
||||
var self/esi: (addr surface) <- copy _self
|
||||
#? print-int32-hex-to-real-screen row
|
||||
#? print-string-to-real-screen ", "
|
||||
#? print-int32-hex-to-real-screen col
|
||||
#? print-string-to-real-screen "\n"
|
||||
result <- copy -1
|
||||
compare row, 1
|
||||
break-if-<
|
||||
compare col, 1
|
||||
break-if-<
|
||||
var nrows-addr/ecx: (addr int) <- get self, nrows
|
||||
var nrows/ecx: int <- copy *nrows-addr
|
||||
compare row, nrows
|
||||
break-if->
|
||||
var ncols-addr/ecx: (addr int) <- get self, ncols
|
||||
var ncols/ecx: int <- copy *ncols-addr
|
||||
compare col, ncols
|
||||
break-if->
|
||||
#? print-string-to-real-screen "!\n"
|
||||
result <- copy row
|
||||
result <- subtract 1
|
||||
result <- multiply ncols
|
||||
result <- add col
|
||||
result <- subtract 1
|
||||
var result/eax: int <- copy -1
|
||||
{
|
||||
compare row, 1
|
||||
break-if-<
|
||||
compare col, 1
|
||||
break-if-<
|
||||
var nrows-addr/ecx: (addr int) <- get self, nrows
|
||||
var nrows/ecx: int <- copy *nrows-addr
|
||||
compare row, nrows
|
||||
break-if->
|
||||
var ncols-addr/ecx: (addr int) <- get self, ncols
|
||||
var ncols/ecx: int <- copy *ncols-addr
|
||||
compare col, ncols
|
||||
break-if->
|
||||
#? print-string-to-real-screen "!\n"
|
||||
result <- copy row
|
||||
result <- subtract 1
|
||||
result <- multiply ncols
|
||||
result <- add col
|
||||
result <- subtract 1
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn screen-row-to-surface _self: (addr surface), screen-row: int -> result/ecx: int {
|
||||
fn screen-row-to-surface _self: (addr surface), screen-row: int -> _/ecx: int {
|
||||
var self/esi: (addr surface) <- copy _self
|
||||
result <- copy screen-row
|
||||
var result/ecx: int <- copy screen-row
|
||||
var tmp/eax: (addr int) <- get self, pin-row
|
||||
result <- add *tmp
|
||||
tmp <- get self, pin-screen-row
|
||||
result <- subtract *tmp
|
||||
return result
|
||||
}
|
||||
|
||||
fn max a: int, b: int -> result/eax: int {
|
||||
$max:body: {
|
||||
var a2/eax: int <- copy a
|
||||
compare a2, b
|
||||
fn max _a: int, b: int -> _/eax: int {
|
||||
var a/eax: int <- copy _a
|
||||
compare a, b
|
||||
{
|
||||
break-if->
|
||||
result <- copy b
|
||||
break $max:body
|
||||
return b
|
||||
}
|
||||
{
|
||||
break-if-<=
|
||||
result <- copy a2
|
||||
}
|
||||
}
|
||||
return a
|
||||
}
|
||||
|
||||
fn min a: int, b: int -> result/eax: int {
|
||||
$min:body: {
|
||||
var a2/eax: int <- copy a
|
||||
compare a2, b
|
||||
fn min _a: int, b: int -> _/eax: int {
|
||||
var a/eax: int <- copy _a
|
||||
compare a, b
|
||||
{
|
||||
break-if->
|
||||
result <- copy a2
|
||||
break $min:body
|
||||
return a
|
||||
}
|
||||
{
|
||||
break-if-<=
|
||||
result <- copy b
|
||||
}
|
||||
}
|
||||
return b
|
||||
}
|
||||
|
||||
fn screen-col-to-surface _self: (addr surface), screen-col: int -> result/edx: int {
|
||||
fn screen-col-to-surface _self: (addr surface), screen-col: int -> _/edx: int {
|
||||
var self/esi: (addr surface) <- copy _self
|
||||
result <- copy screen-col
|
||||
var result/edx: int <- copy screen-col
|
||||
var tmp/eax: (addr int) <- get self, pin-col
|
||||
result <- add *tmp
|
||||
tmp <- get self, pin-screen-col
|
||||
result <- subtract *tmp
|
||||
return result
|
||||
}
|
||||
|
||||
fn surface-row-to-screen _self: (addr surface), row: int -> result/ecx: int {
|
||||
fn surface-row-to-screen _self: (addr surface), row: int -> _/ecx: int {
|
||||
var self/esi: (addr surface) <- copy _self
|
||||
result <- copy row
|
||||
var result/ecx: int <- copy row
|
||||
var tmp/eax: (addr int) <- get self, pin-screen-row
|
||||
result <- add *tmp
|
||||
tmp <- get self, pin-row
|
||||
result <- subtract *tmp
|
||||
return result
|
||||
}
|
||||
|
||||
fn surface-col-to-screen _self: (addr surface), col: int -> result/edx: int {
|
||||
fn surface-col-to-screen _self: (addr surface), col: int -> _/edx: int {
|
||||
var self/esi: (addr surface) <- copy _self
|
||||
result <- copy col
|
||||
var result/edx: int <- copy col
|
||||
var tmp/eax: (addr int) <- get self, pin-screen-col
|
||||
result <- add *tmp
|
||||
tmp <- get self, pin-col
|
||||
result <- subtract *tmp
|
||||
return result
|
||||
}
|
||||
|
||||
# assumes last line doesn't end in '\n'
|
||||
fn num-lines in: (addr array byte) -> result/ecx: int {
|
||||
fn num-lines in: (addr array byte) -> _/ecx: int {
|
||||
var s: (stream byte 0x100)
|
||||
var s-addr/esi: (addr stream byte) <- address s
|
||||
write s-addr, in
|
||||
result <- copy 1
|
||||
var result/ecx: int <- copy 1
|
||||
{
|
||||
var done?/eax: boolean <- stream-empty? s-addr
|
||||
compare done?, 0 # false
|
||||
|
@ -277,13 +272,14 @@ fn num-lines in: (addr array byte) -> result/ecx: int {
|
|||
result <- increment
|
||||
loop
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn first-line-length in: (addr array byte) -> result/edx: int {
|
||||
fn first-line-length in: (addr array byte) -> _/edx: int {
|
||||
var s: (stream byte 0x100)
|
||||
var s-addr/esi: (addr stream byte) <- address s
|
||||
write s-addr, in
|
||||
result <- copy 0
|
||||
var result/edx: int <- copy 0
|
||||
{
|
||||
var done?/eax: boolean <- stream-empty? s-addr
|
||||
compare done?, 0 # false
|
||||
|
@ -294,6 +290,7 @@ fn first-line-length in: (addr array byte) -> result/edx: int {
|
|||
result <- increment
|
||||
loop
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn fill-in _out: (addr array screen-cell), in: (addr array byte) {
|
||||
|
|
|
@ -15,10 +15,11 @@ fn bind-in-table _self: (addr table), key: (addr handle array byte), val: (addr
|
|||
}
|
||||
|
||||
# manual test: full array of binds
|
||||
fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> result/eax: (offset bind) {
|
||||
fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> _/eax: (offset bind) {
|
||||
var data/esi: (addr array bind) <- copy _data
|
||||
var len/ecx: int <- length data
|
||||
var i/edx: int <- copy 0
|
||||
var result/eax: (offset bind) <- copy 0
|
||||
$next-empty-slot:loop: {
|
||||
result <- compute-offset data, i
|
||||
compare i, len
|
||||
|
@ -34,6 +35,7 @@ fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> re
|
|||
i <- increment
|
||||
loop
|
||||
}
|
||||
return result
|
||||
}
|
||||
|
||||
fn make-int-binding _self: (addr bind), key: (addr handle array byte), _val: int {
|
||||
|
|
|
@ -83,15 +83,13 @@ fn push-value-stack _self: (addr value-stack), val: (addr value) {
|
|||
increment *top-addr
|
||||
}
|
||||
|
||||
fn pop-int-from-value-stack _self: (addr value-stack) -> val/eax: int {
|
||||
$pop-int-from-value-stack:body: {
|
||||
fn pop-int-from-value-stack _self: (addr value-stack) -> _/eax: int {
|
||||
var self/esi: (addr value-stack) <- copy _self
|
||||
var top-addr/ecx: (addr int) <- get self, top
|
||||
{
|
||||
compare *top-addr, 0
|
||||
break-if->
|
||||
val <- copy -1
|
||||
break $pop-int-from-value-stack:body
|
||||
return -1
|
||||
}
|
||||
decrement *top-addr
|
||||
var data-ah/edx: (addr handle array value) <- get self, data
|
||||
|
@ -100,145 +98,134 @@ $pop-int-from-value-stack:body: {
|
|||
var dest-offset/edx: (offset value) <- compute-offset data, top
|
||||
var result-addr/eax: (addr value) <- index data, dest-offset
|
||||
var result-addr2/eax: (addr int) <- get result-addr, int-data
|
||||
val <- copy *result-addr2
|
||||
}
|
||||
return *result-addr2
|
||||
}
|
||||
|
||||
fn value-stack-empty? _self: (addr value-stack) -> result/eax: boolean {
|
||||
$value-stack-empty?:body: {
|
||||
fn value-stack-empty? _self: (addr value-stack) -> _/eax: boolean {
|
||||
var self/esi: (addr value-stack) <- copy _self
|
||||
var top/eax: (addr int) <- get self, top
|
||||
compare *top, 0
|
||||
{
|
||||
break-if-!=
|
||||
result <- copy 1 # true
|
||||
break $value-stack-empty?:body
|
||||
return 1 # true
|
||||
}
|
||||
result <- copy 0 # false
|
||||
}
|
||||
return 0 # false
|
||||
}
|
||||
|
||||
fn value-stack-length _self: (addr value-stack) -> result/eax: int {
|
||||
fn value-stack-length _self: (addr value-stack) -> _/eax: int {
|
||||
var self/esi: (addr value-stack) <- copy _self
|
||||
var top-addr/eax: (addr int) <- get self, top
|
||||
result <- copy *top-addr
|
||||
return *top-addr
|
||||
}
|
||||
|
||||
fn value-stack-max-width _self: (addr value-stack) -> result/eax: int {
|
||||
fn value-stack-max-width _self: (addr value-stack) -> _/eax: int {
|
||||
var self/esi: (addr value-stack) <- copy _self
|
||||
var data-ah/edi: (addr handle array value) <- get self, data
|
||||
var _data/eax: (addr array value) <- lookup *data-ah
|
||||
var data/edi: (addr array value) <- copy _data
|
||||
var top-addr/ecx: (addr int) <- get self, top
|
||||
var i/ebx: int <- copy 0
|
||||
var out: int
|
||||
var result: int
|
||||
{
|
||||
compare i, *top-addr
|
||||
break-if->=
|
||||
var o/edx: (offset value) <- compute-offset data, i
|
||||
var v/edx: (addr value) <- index data, o
|
||||
var w/eax: int <- value-width v, 1 # top-level=true
|
||||
# if (w > out) w = out
|
||||
# if (w > result) w = result
|
||||
{
|
||||
compare w, out
|
||||
compare w, result
|
||||
break-if-<=
|
||||
copy-to out, w
|
||||
copy-to result, w
|
||||
}
|
||||
i <- increment
|
||||
loop
|
||||
}
|
||||
result <- copy out
|
||||
return result
|
||||
}
|
||||
|
||||
fn value-width _v: (addr value), top-level: boolean -> result/eax: int {
|
||||
var out/edi: int <- copy 0
|
||||
$value-width:core: {
|
||||
var v/esi: (addr value) <- copy _v
|
||||
var type/eax: (addr int) <- get v, type
|
||||
{
|
||||
compare *type, 0 # int
|
||||
break-if-!=
|
||||
var v-int/edx: (addr int) <- get v, int-data
|
||||
var _out/eax: int <- decimal-size *v-int
|
||||
out <- copy _out
|
||||
break $value-width:core
|
||||
}
|
||||
{
|
||||
compare *type, 1 # string
|
||||
break-if-!=
|
||||
var s-ah/eax: (addr handle array byte) <- get v, text-data
|
||||
var s/eax: (addr array byte) <- lookup *s-ah
|
||||
compare s, 0
|
||||
break-if-=
|
||||
var _out/eax: int <- length s
|
||||
out <- copy _out
|
||||
compare out, 0xd # max string size
|
||||
{
|
||||
break-if-<=
|
||||
out <- copy 0xd
|
||||
}
|
||||
# if it's a nested string, include space for quotes
|
||||
# we don't do this for the top-level, where the quotes will overflow
|
||||
# into surrounding padding.
|
||||
compare top-level, 0 # false
|
||||
{
|
||||
break-if-!=
|
||||
out <- add 2
|
||||
}
|
||||
break $value-width:core
|
||||
}
|
||||
{
|
||||
compare *type, 2 # array
|
||||
break-if-!=
|
||||
var a-ah/eax: (addr handle array value) <- get v, array-data
|
||||
var a/eax: (addr array value) <- lookup *a-ah
|
||||
compare a, 0
|
||||
break-if-=
|
||||
var _out/eax: int <- array-width a
|
||||
out <- copy _out
|
||||
break $value-width:core
|
||||
}
|
||||
{
|
||||
compare *type, 3 # file handle
|
||||
break-if-!=
|
||||
var f-ah/eax: (addr handle buffered-file) <- get v, file-data
|
||||
var f/eax: (addr buffered-file) <- lookup *f-ah
|
||||
compare f, 0
|
||||
break-if-=
|
||||
# TODO
|
||||
out <- copy 4
|
||||
break $value-width:core
|
||||
}
|
||||
fn value-width _v: (addr value), top-level: boolean -> _/eax: int {
|
||||
var v/esi: (addr value) <- copy _v
|
||||
var type/eax: (addr int) <- get v, type
|
||||
{
|
||||
compare *type, 0 # int
|
||||
break-if-!=
|
||||
var v-int/edx: (addr int) <- get v, int-data
|
||||
var result/eax: int <- decimal-size *v-int
|
||||
return result
|
||||
}
|
||||
result <- copy out
|
||||
{
|
||||
compare *type, 1 # string
|
||||
break-if-!=
|
||||
var s-ah/eax: (addr handle array byte) <- get v, text-data
|
||||
var s/eax: (addr array byte) <- lookup *s-ah
|
||||
compare s, 0
|
||||
break-if-=
|
||||
var result/eax: int <- length s
|
||||
compare result, 0xd # max string size
|
||||
{
|
||||
break-if-<=
|
||||
result <- copy 0xd
|
||||
}
|
||||
# if it's a nested string, include space for quotes
|
||||
# we don't do this for the top-level, where the quotes will overflow
|
||||
# into surrounding padding.
|
||||
compare top-level, 0 # false
|
||||
{
|
||||
break-if-!=
|
||||
result <- add 2
|
||||
}
|
||||
return result
|
||||
}
|
||||
{
|
||||
compare *type, 2 # array
|
||||
break-if-!=
|
||||
var a-ah/eax: (addr handle array value) <- get v, array-data
|
||||
var a/eax: (addr array value) <- lookup *a-ah
|
||||
compare a, 0
|
||||
break-if-=
|
||||
var result/eax: int <- array-width a
|
||||
return result
|
||||
}
|
||||
{
|
||||
compare *type, 3 # file handle
|
||||
break-if-!=
|
||||
var f-ah/eax: (addr handle buffered-file) <- get v, file-data
|
||||
var f/eax: (addr buffered-file) <- lookup *f-ah
|
||||
compare f, 0
|
||||
break-if-=
|
||||
# TODO: visualizing file handles
|
||||
return 4
|
||||
}
|
||||
return 0
|
||||
}
|
||||
|
||||
# keep sync'd with render-array
|
||||
fn array-width _a: (addr array value) -> result/eax: int {
|
||||
fn array-width _a: (addr array value) -> _/eax: int {
|
||||
var a/esi: (addr array value) <- copy _a
|
||||
var max/ecx: int <- length a
|
||||
var i/eax: int <- copy 0
|
||||
var out/edi: int <- copy 0
|
||||
var result/edi: int <- copy 0
|
||||
{
|
||||
compare i, max
|
||||
break-if->=
|
||||
{
|
||||
compare i, 0
|
||||
break-if-=
|
||||
out <- increment # for space
|
||||
result <- increment # for space
|
||||
}
|
||||
var off/ecx: (offset value) <- compute-offset a, i
|
||||
var x/ecx: (addr value) <- index a, off
|
||||
{
|
||||
var w/eax: int <- value-width x, 0
|
||||
out <- add w
|
||||
result <- add w
|
||||
}
|
||||
i <- increment
|
||||
loop
|
||||
}
|
||||
result <- copy out
|
||||
# we won't add 2 for surrounding brackets since we don't surround arrays in
|
||||
# spaces like other value types
|
||||
return result
|
||||
}
|
||||
|
||||
fn save-lines in-h: (handle array (handle array byte)), _out-ah: (addr handle array value) {
|
||||
|
|
|
@ -96,18 +96,20 @@ fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr
|
|||
}
|
||||
}
|
||||
|
||||
fn word-equal? _self: (addr word), s: (addr array byte) -> result/eax: boolean {
|
||||
fn word-equal? _self: (addr word), s: (addr array byte) -> _/eax: boolean {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-buffer-equal? data, s
|
||||
var result/eax: boolean <- gap-buffer-equal? data, s
|
||||
return result
|
||||
}
|
||||
|
||||
fn word-length _self: (addr word) -> result/eax: int {
|
||||
fn word-length _self: (addr word) -> _/eax: int {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-buffer-length data
|
||||
var result/eax: int <- gap-buffer-length data
|
||||
return result
|
||||
}
|
||||
|
||||
fn first-word _in: (addr handle word), out: (addr handle word) {
|
||||
|
@ -143,18 +145,20 @@ fn final-word _in: (addr handle word), out: (addr handle word) {
|
|||
copy-object curr-ah, out
|
||||
}
|
||||
|
||||
fn first-grapheme _self: (addr word) -> result/eax: grapheme {
|
||||
fn first-grapheme _self: (addr word) -> _/eax: grapheme {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- first-grapheme-in-gap-buffer data
|
||||
var result/eax: grapheme <- first-grapheme-in-gap-buffer data
|
||||
return result
|
||||
}
|
||||
|
||||
fn grapheme-before-cursor _self: (addr word) -> result/eax: grapheme {
|
||||
fn grapheme-before-cursor _self: (addr word) -> _/eax: grapheme {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- grapheme-before-cursor-in-gap-buffer data
|
||||
var result/eax: grapheme <- grapheme-before-cursor-in-gap-buffer data
|
||||
return result
|
||||
}
|
||||
|
||||
fn add-grapheme-to-word _self: (addr word), c: grapheme {
|
||||
|
@ -164,18 +168,20 @@ fn add-grapheme-to-word _self: (addr word), c: grapheme {
|
|||
add-grapheme-at-gap data, c
|
||||
}
|
||||
|
||||
fn cursor-at-start? _self: (addr word) -> result/eax: boolean {
|
||||
fn cursor-at-start? _self: (addr word) -> _/eax: boolean {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-at-start? data
|
||||
var result/eax: boolean <- gap-at-start? data
|
||||
return result
|
||||
}
|
||||
|
||||
fn cursor-at-end? _self: (addr word) -> result/eax: boolean {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-at-end? data
|
||||
var result/eax: boolean <- gap-at-end? data
|
||||
return result
|
||||
}
|
||||
|
||||
fn cursor-left _self: (addr word) {
|
||||
|
@ -206,11 +212,12 @@ fn cursor-to-end _self: (addr word) {
|
|||
gap-to-end data
|
||||
}
|
||||
|
||||
fn cursor-index _self: (addr word) -> result/eax: int {
|
||||
fn cursor-index _self: (addr word) -> _/eax: int {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-index data
|
||||
var result/eax: int <- gap-index data
|
||||
return result
|
||||
}
|
||||
|
||||
fn delete-before-cursor _self: (addr word) {
|
||||
|
@ -220,30 +227,29 @@ fn delete-before-cursor _self: (addr word) {
|
|||
delete-before-gap data
|
||||
}
|
||||
|
||||
fn pop-after-cursor _self: (addr word) -> result/eax: grapheme {
|
||||
fn pop-after-cursor _self: (addr word) -> _/eax: grapheme {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- pop-after-gap data
|
||||
var result/eax: grapheme <- pop-after-gap data
|
||||
return result
|
||||
}
|
||||
|
||||
fn delete-next _self: (addr word) {
|
||||
$delete-next:body: {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
var next-ah/edi: (addr handle word) <- get self, next
|
||||
var next/eax: (addr word) <- lookup *next-ah
|
||||
compare next, 0
|
||||
break-if-= $delete-next:body
|
||||
break-if-=
|
||||
var next-next-ah/ecx: (addr handle word) <- get next, next
|
||||
var self-ah/esi: (addr handle word) <- get next, prev
|
||||
copy-object next-next-ah, next-ah
|
||||
var new-next/eax: (addr word) <- lookup *next-next-ah
|
||||
compare new-next, 0
|
||||
break-if-= $delete-next:body
|
||||
break-if-=
|
||||
var dest/eax: (addr handle word) <- get new-next, prev
|
||||
copy-object self-ah, dest
|
||||
}
|
||||
}
|
||||
|
||||
fn print-word screen: (addr screen), _self: (addr word) {
|
||||
var self/esi: (addr word) <- copy _self
|
||||
|
@ -312,7 +318,6 @@ fn copy-words-in-reverse _src-ah: (addr handle word), _dest-ah: (addr handle wor
|
|||
}
|
||||
|
||||
fn copy-word-at-end src: (addr word), _dest-ah: (addr handle word) {
|
||||
$copy-word-at-end:body: {
|
||||
var dest-ah/edi: (addr handle word) <- copy _dest-ah
|
||||
# if dest is null, copy and return
|
||||
var dest-a/eax: (addr word) <- lookup *dest-ah
|
||||
|
@ -320,7 +325,7 @@ $copy-word-at-end:body: {
|
|||
{
|
||||
break-if-!=
|
||||
copy-word src, dest-ah
|
||||
break $copy-word-at-end:body
|
||||
return
|
||||
}
|
||||
# copy current word
|
||||
var new: (handle word)
|
||||
|
@ -339,10 +344,8 @@ $copy-word-at-end:body: {
|
|||
}
|
||||
chain-words curr-ah, new-ah
|
||||
}
|
||||
}
|
||||
|
||||
fn append-word-at-end-with _dest-ah: (addr handle word), s: (addr array byte) {
|
||||
$append-word-at-end-with:body: {
|
||||
var dest-ah/edi: (addr handle word) <- copy _dest-ah
|
||||
# if dest is null, copy and return
|
||||
var dest-a/eax: (addr word) <- lookup *dest-ah
|
||||
|
@ -350,7 +353,7 @@ $append-word-at-end-with:body: {
|
|||
{
|
||||
break-if-!=
|
||||
allocate-word-with dest-ah, s
|
||||
break $append-word-at-end-with:body
|
||||
return
|
||||
}
|
||||
# otherwise append at end
|
||||
var curr-ah/edi: (addr handle word) <- copy dest-ah
|
||||
|
@ -365,7 +368,6 @@ $append-word-at-end-with:body: {
|
|||
}
|
||||
append-word-with *curr-ah, s
|
||||
}
|
||||
}
|
||||
|
||||
fn copy-word _src-a: (addr word), _dest-ah: (addr handle word) {
|
||||
var dest-ah/eax: (addr handle word) <- copy _dest-ah
|
||||
|
@ -511,37 +513,43 @@ fn word-to-string _self: (addr word), out: (addr handle array byte) {
|
|||
gap-buffer-to-string data, out
|
||||
}
|
||||
|
||||
fn word-is-decimal-integer? _self: (addr word) -> result/eax: boolean {
|
||||
fn word-is-decimal-integer? _self: (addr word) -> _/eax: boolean {
|
||||
var self/eax: (addr word) <- copy _self
|
||||
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
|
||||
var data/eax: (addr gap-buffer) <- lookup *data-ah
|
||||
result <- gap-buffer-is-decimal-integer? data
|
||||
var result/eax: boolean <- gap-buffer-is-decimal-integer? data
|
||||
return result
|
||||
}
|
||||
|
||||
# ABSOLUTELY GHASTLY
|
||||
fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> result/ebx: boolean {
|
||||
fn word-exists? _haystack-ah: (addr handle word), _needle: (addr word) -> _/ebx: boolean {
|
||||
var needle-name-storage: (handle addr byte)
|
||||
var needle-name-ah/eax: (addr handle array byte) <- address needle-name-storage
|
||||
word-to-string _needle, needle-name-ah # profligate leak
|
||||
var _needle-name/eax: (addr array byte) <- lookup *needle-name-ah
|
||||
var needle-name/edi: (addr array byte) <- copy _needle-name
|
||||
# base case
|
||||
result <- copy 0 # false
|
||||
var haystack-ah/esi: (addr handle word) <- copy _haystack-ah
|
||||
var curr/eax: (addr word) <- lookup *haystack-ah
|
||||
compare curr, 0
|
||||
break-if-=
|
||||
{
|
||||
break-if-!=
|
||||
return 0 # false
|
||||
}
|
||||
# check curr
|
||||
var curr-name-storage: (handle addr byte)
|
||||
var curr-name-ah/ecx: (addr handle array byte) <- address curr-name-storage
|
||||
word-to-string curr, curr-name-ah # profligate leak
|
||||
var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
|
||||
var found?/eax: boolean <- string-equal? needle-name, curr-name
|
||||
result <- copy found?
|
||||
compare result, 0
|
||||
break-if-!=
|
||||
compare found?, 0
|
||||
{
|
||||
break-if-=
|
||||
return 1 # true
|
||||
}
|
||||
# recurse
|
||||
var curr/eax: (addr word) <- lookup *haystack-ah
|
||||
var next-haystack-ah/eax: (addr handle word) <- get curr, next
|
||||
result <- word-exists? next-haystack-ah, _needle
|
||||
var result/ebx: boolean <- word-exists? next-haystack-ah, _needle
|
||||
return result
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue