7159 - explicitly use 'return' everywhere

https://github.com/akkartik/mu/issues/45#issuecomment-719990879, task 2.
This commit is contained in:
Kartik Agaram 2020-11-02 19:50:34 -08:00
parent 951c3f4c92
commit a3f7791586
18 changed files with 412 additions and 460 deletions

View File

@ -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
#? }

View File

@ -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) {

View 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 {

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}
}
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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
}

View File

@ -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 {

View File

@ -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
}

View File

@ -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) {

View File

@ -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 {

View File

@ -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) {

View File

@ -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
}