This commit is contained in:
Kartik K. Agaram 2021-02-19 02:39:22 -08:00
parent 3b1686b610
commit 446a6704cb
3 changed files with 119 additions and 30 deletions

View File

@ -111,21 +111,6 @@ fn word-length _self: (addr word) -> _/eax: int {
return result
}
fn first-word _in: (addr handle word), out: (addr handle word) {
var curr-ah/esi: (addr handle word) <- copy _in
var curr/eax: (addr word) <- lookup *curr-ah
var prev/edi: (addr handle word) <- copy 0
{
prev <- get curr, prev
var curr/eax: (addr word) <- lookup *prev
compare curr, 0
break-if-=
copy-object prev, curr-ah
loop
}
copy-object curr-ah, out
}
fn final-word _in: (addr handle word), out: (addr handle word) {
var curr-h: (handle word)
var curr-ah/esi: (addr handle word) <- address curr-h

View File

@ -214,12 +214,28 @@ fn evaluate-sub _curr: (addr word), end: (addr word), out: (addr value-stack), t
var is-break?/eax: boolean <- stream-data-equal? curr-stream, "break"
compare is-break?, 0/false
break-if-=
# if curr == end, clear stack and break
# (TODO: move this into skip-rest-of-group)
compare curr, end
{
break-if-!=
clear-value-stack out
break $evaluate-sub:loop
}
# scan ahead to containing '}'
var next-word: (handle word)
var next-word-ah/eax: (addr handle word) <- address next-word
skip-rest-of-group curr, end, next-word-ah
var _curr/eax: (addr word) <- lookup *next-word-ah
curr <- copy _curr
# if '}' isn't found before end, we're rendering a word that isn't executed
# skip everything else and clear stack
var close-found?/eax: boolean <- word-equal? curr, "}"
compare close-found?, 0/false
{
break-if-!=
clear-value-stack out
}
loop $evaluate-sub:loop
}
{
@ -408,13 +424,15 @@ fn skip-word _curr: (addr word), end: (addr word), out: (addr handle word) {
copy-object result-ah, out
}
# find next "}" from curr
# if you hit 'end' before "}", return null
fn skip-rest-of-group _curr: (addr word), end: (addr word), out: (addr handle word) {
var curr/eax: (addr word) <- copy _curr
var bracket-count/ecx: int <- copy 0
var result-ah/esi: (addr handle word) <- get curr, next
$skip-rest-of-group:loop: {
var result-val/eax: (addr word) <- lookup *result-ah
compare result-val, end
compare result-val, 0
break-if-=
{
var open?/eax: boolean <- word-equal? result-val, "{"
@ -430,6 +448,12 @@ fn skip-rest-of-group _curr: (addr word), end: (addr word), out: (addr handle wo
break-if-= $skip-rest-of-group:loop
bracket-count <- decrement
}
compare result-val, end
{
break-if-!=
clear-object out
return
}
result-ah <- get result-val, next
loop
}
@ -442,7 +466,9 @@ fn scan-to-start-of-group _curr: (addr word), end: (addr word), out: (addr handl
var result-ah/esi: (addr handle word) <- get curr, prev
$scan-to-start-of-group:loop: {
var result-val/eax: (addr word) <- lookup *result-ah
compare result-val, end
compare result-val, 0
break-if-=
compare result-val, end # not sure what error-detection should happen here
break-if-=
{
var open?/eax: boolean <- word-equal? result-val, "{"
@ -780,6 +806,87 @@ fn test-eval-conditional-skips-nested-group {
# TODO: test error-handling on:
# 1 2 > -> }
# incomplete group rendering at 'break'
fn test-eval-break-incomplete {
# in
var in-storage: line
var in/esi: (addr line) <- address in-storage
parse-line "3 { 4 break", in
# end
var w-ah/eax: (addr handle word) <- get in, data
var end-h: (handle word)
var end-ah/ecx: (addr handle word) <- address end-h
final-word w-ah, end-ah
var end/eax: (addr word) <- lookup *end-ah
# out
var out-storage: value-stack
var out/edi: (addr value-stack) <- address out-storage
initialize-value-stack out, 8
#
evaluate in, end, out
# break clears stack when final word
var len/eax: int <- value-stack-length out
check-ints-equal len, 0, "F - test-eval-break-incomplete stack size"
}
# incomplete group rendering after 'break'
fn test-eval-break-incomplete-2 {
# in
var in-storage: line
var in/esi: (addr line) <- address in-storage
parse-line "3 { 4 break 5", in
# end
var w-ah/eax: (addr handle word) <- get in, data
var end-h: (handle word)
var end-ah/ecx: (addr handle word) <- address end-h
final-word w-ah, end-ah
var end/eax: (addr word) <- lookup *end-ah
# out
var out-storage: value-stack
var out/edi: (addr value-stack) <- address out-storage
initialize-value-stack out, 8
#
evaluate in, end, out
# break clears stack when final word
#? dump-stack out
var len/eax: int <- value-stack-length out
#? draw-int32-decimal-wrapping-right-then-down-from-cursor-over-full-screen 0/screen, len, 0xc/red, 0/black
check-ints-equal len, 0, "F - test-eval-break-incomplete-2 stack size"
}
# complete group rendering at 'break'
fn test-eval-break-incomplete-3 {
# in
var in-storage: line
var in/esi: (addr line) <- address in-storage
parse-line "{ 3 break 4 } 5", in
# end = 'break'
var w-ah/edx: (addr handle word) <- get in, data
var end-h: (handle word)
var end-ah/ecx: (addr handle word) <- address end-h
skip-one-word w-ah, end-ah
skip-one-word end-ah, end-ah
var end/eax: (addr word) <- lookup *end-ah
# out
var out-storage: value-stack
var out/edi: (addr value-stack) <- address out-storage
initialize-value-stack out, 8
#
evaluate in, end, out
# break clears stack when final word
var len/eax: int <- value-stack-length out
check-ints-equal len, 0, "F - test-eval-break-incomplete-3 stack size"
}
# { 1 break 2 } 3 => empty
# ^
#
# { 1 break 2 } 3 => empty
# ^
#
# { 1 break 2 } 3 => 1 3
# ^
# break skips to next containing `}`
fn test-eval-break {
# in

View File

@ -101,6 +101,11 @@ fn copy-word-contents-before-cursor _src-ah: (addr handle word), _dest-ah: (addr
fn word-equal? _self: (addr word), s: (addr array byte) -> _/eax: boolean {
var self/esi: (addr word) <- copy _self
{
compare self, 0
break-if-!=
return 0/false
}
var data-ah/eax: (addr handle gap-buffer) <- get self, scalar-data
var data/eax: (addr gap-buffer) <- lookup *data-ah
var result/eax: boolean <- gap-buffer-equal? data, s
@ -127,19 +132,11 @@ fn word-length _self: (addr word) -> _/eax: int {
return result
}
fn first-word _in: (addr handle word), out: (addr handle word) {
var curr-ah/esi: (addr handle word) <- copy _in
var curr/eax: (addr word) <- lookup *curr-ah
var prev/edi: (addr handle word) <- copy 0
{
prev <- get curr, prev
var curr/eax: (addr word) <- lookup *prev
compare curr, 0
break-if-=
copy-object prev, curr-ah
loop
}
copy-object curr-ah, out
fn skip-one-word _in: (addr handle word), out: (addr handle word) {
var in/eax: (addr handle word) <- copy _in
var curr/eax: (addr word) <- lookup *in
var next/eax: (addr handle word) <- get curr, next
copy-object next, out # modify 'out' right at the end, just in case it's same as 'in'
}
fn final-word _in: (addr handle word), out: (addr handle word) {