Snapshot: tile currently segfaulting. I need to back up and make it easier
to debug.
This commit is contained in:
Kartik Agaram 2020-09-26 13:41:23 -07:00
parent fca30f0f86
commit e0bceffe08
7 changed files with 152 additions and 12 deletions

View File

@ -55,3 +55,61 @@ $copy-bytes:end:
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
stream-to-string: # in: (addr stream _), out: (addr handle array _)
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# . save registers
50/push-eax
51/push-ecx
52/push-edx
56/push-esi
# esi = s
8b/-> *(ebp+8) 6/r32/esi
# var len/ecx: int = s->write - s->read
8b/-> *esi 1/r32/ecx
2b/subtract *(esi+4) 1/r32/ecx
# allocate
(allocate-array Heap %ecx *(ebp+0xc))
# var in/edx: (addr byte) = s->data + s->read
8b/-> *(esi+4) 2/r32/edx
8d/copy-address *(esi+edx+0xc) 2/r32/edx
# var dest/eax: (addr byte) = data for out
8b/-> *(ebp+0xc) 0/r32/eax
(lookup *eax *(eax+4)) # => eax
8d/copy-address *(eax+4) 0/r32/eax
#
(copy-bytes %edx %eax %ecx)
$stream-to-string:end:
# . restore registers
5e/pop-to-esi
5a/pop-to-edx
59/pop-to-ecx
58/pop-to-eax
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return
test-stream-to-string:
# . prologue
55/push-ebp
89/<- %ebp 4/r32/esp
# setup
(clear-stream _test-input-stream)
(write _test-input-stream "abc")
# skip something
(read-byte _test-input-stream) # => eax
# var out/ecx: (handle array byte)
68/push 0/imm32
68/push 0/imm32
89/<- %ecx 4/r32/esp
#
(stream-to-string _test-input-stream %ecx)
(lookup *ecx *(ecx+4)) # => eax
(check-strings-equal %eax "bc")
# . epilogue
89/<- %esp 5/r32/ebp
5d/pop-to-ebp
c3/return

1
400.mu
View File

@ -173,5 +173,6 @@ sig new-buffered-file out: (addr handle buffered-file)
sig stream-empty? s: (addr stream _) -> result/eax: boolean
sig stream-full? s: (addr stream _) -> result/eax: boolean
sig stream-to-string in: (addr stream _), out: (addr handle array _)
sig copy-bytes src: (addr byte), dest: (addr byte), n: int

View File

@ -177,9 +177,7 @@ fn render _env: (addr environment) {
var _program/eax: (addr program) <- lookup *program-ah
var program/esi: (addr program) <- copy _program
# defs
var defs-ah/edx: (addr handle function) <- get program, defs
var _defs/eax: (addr function) <- lookup *defs-ah
var defs/edx: (addr function) <- copy _defs
var defs/edx: (addr handle function) <- get program, defs
# line
var sandbox-ah/esi: (addr handle sandbox) <- get program, sandboxes
var sandbox/eax: (addr sandbox) <- lookup *sandbox-ah
@ -194,7 +192,7 @@ fn render _env: (addr environment) {
move-cursor screen, 3, cursor-col # input-row
}
fn render-line screen: (addr screen), defs: (addr function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) {
fn render-line screen: (addr screen), defs: (addr handle function), bindings: (addr table), _line: (addr line), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) {
# curr-word
var line/esi: (addr line) <- copy _line
var first-word-ah/eax: (addr handle word) <- get line, data
@ -222,7 +220,7 @@ fn render-line screen: (addr screen), defs: (addr function), bindings: (addr tab
# - Return the farthest column written.
# - If final-word is same as cursor-word, do some additional computation to set
# cursor-col-a.
fn render-column screen: (addr screen), defs: (addr function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
fn render-column screen: (addr screen), defs: (addr handle function), bindings: (addr table), scratch: (addr line), final-word: (addr word), top-row: int, left-col: int, cursor-word: (addr word), cursor-col-a: (addr int) -> right-col/ecx: int {
var max-width/ecx: int <- copy 0
{
# render stack for all but final column

View File

@ -27,6 +27,13 @@ fn initialize-gap-buffer-with self: (addr gap-buffer), s: (addr array byte) {
}
}
fn gap-buffer-to-string self: (addr gap-buffer), out: (addr handle array byte) {
var s-storage: (stream byte 0x100)
var s/ecx: (addr stream byte) <- address s-storage
emit-gap-buffer self, s
stream-to-string s, out
}
fn emit-gap-buffer _self: (addr gap-buffer), out: (addr stream byte) {
var self/esi: (addr gap-buffer) <- copy _self
clear-stream out

View File

@ -1,4 +1,4 @@
fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) {
fn evaluate defs: (addr handle function), bindings: (addr table), scratch: (addr line), end: (addr word), out: (addr int-stack) {
var line/eax: (addr line) <- copy scratch
var word-ah/eax: (addr handle word) <- get line, data
var curr/eax: (addr word) <- lookup *word-ah
@ -46,8 +46,16 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line),
push-int-stack out, a
break $evaluate:process-word
}
# HERE: if curr-text is a known function name, call it appropriately
# if curr-text is a known function name, call it appropriately
{
var callee-h: (handle function)
var callee-ah/eax: (addr handle function) <- address callee-h
find-function defs, curr-text, callee-ah
var callee/eax: (addr function) <- lookup *callee-ah
compare callee, 0
break-if-=
perform-call callee, out, defs
break $evaluate:process-word
}
# otherwise it's an int
{
@ -66,6 +74,67 @@ fn evaluate defs: (addr function), bindings: (addr table), scratch: (addr line),
}
}
fn find-function first: (addr handle function), name: (addr stream byte), out: (addr handle function) {
var curr/esi: (addr handle function) <- copy first
$find-function:loop: {
var _f/eax: (addr function) <- lookup *curr
var f/ecx: (addr function) <- copy _f
compare f, 0
break-if-=
var curr-name-ah/eax: (addr handle array byte) <- get f, name
var curr-name/eax: (addr array byte) <- lookup *curr-name-ah
var done?/eax: boolean <- stream-data-equal? name, curr-name
compare done?, 0 # false
{
break-if-=
copy-handle *curr, out
break $find-function:loop
}
curr <- get f, next
loop
}
}
fn perform-call _callee: (addr function), caller-stack: (addr int-stack), defs: (addr handle function) {
var callee/ecx: (addr function) <- copy _callee
# create bindings for args
var table-storage: table
var table/esi: (addr table) <- address table-storage
initialize-table table
#
var curr-arg-ah/eax: (addr handle word) <- get callee, args
var curr-arg/eax: (addr word) <- lookup *curr-arg-ah
#
var curr-key-storage: (handle array byte)
var curr-key/edx: (addr handle array byte) <- address curr-key-storage
{
compare curr-arg, 0
break-if-=
# create binding
word-to-string curr-arg, curr-key
{
var curr-val/eax: int <- pop-int-stack caller-stack
bind-int-in-table table, curr-key, curr-val
}
#
var next-arg-ah/edx: (addr handle word) <- get curr-arg, next
curr-arg <- lookup *next-arg-ah
loop
}
# obtain body
var body-ah/eax: (addr handle line) <- get callee, body
var body/eax: (addr line) <- lookup *body-ah
# perform call
var stack-storage: int-stack
var stack/edi: (addr int-stack) <- address stack-storage
print-string-to-real-screen "about to enter recursive eval\n"
evaluate defs, table, body, 0, stack
print-string-to-real-screen "exited recursive eval\n"
# stitch result from stack into caller
var result/eax: int <- pop-int-stack stack
push-int-stack caller-stack, result
}
# 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 {

View File

@ -1,10 +1,10 @@
fn initialize-table _self: (address table) {
fn initialize-table _self: (addr table) {
var self/esi: (addr table) <- copy _self
var data-ah/eax: (addr handle array bind) <- get self, data
populate data-ah, 0x10
}
fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int {
fn bind-int-in-table _self: (addr table), key: (addr handle array byte), val: int {
var self/esi: (addr table) <- copy _self
var data-ah/esi: (addr handle array bind) <- get self, data
var _data/eax: (addr array bind) <- lookup *data-ah
@ -15,7 +15,7 @@ fn bind-int-in-table _self: (addr table), key: (addr array byte), val: int {
}
# manual test: full array of binds
fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/eax: (offset bind) {
fn next-empty-slot _data: (addr array bind), key: (addr handle array byte) -> result/eax: (offset bind) {
var data/esi: (addr array bind) <- copy _data
var len/ecx: int <- length data
var i/edx: int <- copy 0
@ -36,10 +36,10 @@ fn next-empty-slot _data: (addr array bind), key: (addr array byte) -> result/ea
}
}
fn make-binding _self: (addr bind), key: (addr array byte), _val: int {
fn make-binding _self: (addr bind), key: (addr handle array byte), _val: int {
var self/esi: (addr bind) <- copy _self
var dest/eax: (addr handle array byte) <- get self, key
populate-text-with dest, key
copy-object key, dest
var dest2/eax: (addr value) <- get self, value
var dest3/eax: (addr int) <- get dest2, scalar-data
var val/ecx: int <- copy _val

View File

@ -225,3 +225,10 @@ fn emit-word _self: (addr word), out: (addr stream byte) {
var data/eax: (addr gap-buffer) <- lookup *data-ah
emit-gap-buffer data, out
}
fn word-to-string _self: (addr word), out: (addr handle array byte) {
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
gap-buffer-to-string data, out
}