1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
|
type sandbox {
data: (handle gap-buffer)
value: (handle stream byte)
trace: (handle trace)
}
fn initialize-sandbox _self: (addr sandbox) {
var self/esi: (addr sandbox) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, data
allocate data-ah
var data/eax: (addr gap-buffer) <- lookup *data-ah
initialize-gap-buffer data, 0x1000/4KB
var value-ah/eax: (addr handle stream byte) <- get self, value
populate-stream value-ah, 0x1000/4KB
}
## some helpers for tests
fn initialize-sandbox-with _self: (addr sandbox), s: (addr array byte) {
var self/esi: (addr sandbox) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, data
allocate data-ah
var data/eax: (addr gap-buffer) <- lookup *data-ah
initialize-gap-buffer-with data, s
}
fn allocate-sandbox-with _out: (addr handle sandbox), s: (addr array byte) {
var out/eax: (addr handle sandbox) <- copy _out
allocate out
var out-addr/eax: (addr sandbox) <- lookup *out
initialize-sandbox-with out-addr, s
}
fn add-grapheme-to-sandbox _self: (addr sandbox), c: grapheme {
var self/esi: (addr sandbox) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, data
var data/eax: (addr gap-buffer) <- lookup *data-ah
add-grapheme-at-gap data, c
}
fn delete-grapheme-before-cursor _self: (addr sandbox) {
var self/esi: (addr sandbox) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, data
var data/eax: (addr gap-buffer) <- lookup *data-ah
delete-before-gap data
}
fn render-sandbox screen: (addr screen), _self: (addr sandbox), _x: int, _y: int {
clear-screen screen
var self/esi: (addr sandbox) <- copy _self
var data-ah/eax: (addr handle gap-buffer) <- get self, data
var _data/eax: (addr gap-buffer) <- lookup *data-ah
var data/edx: (addr gap-buffer) <- copy _data
var x/eax: int <- copy _x
var y/ecx: int <- copy _y
x, y <- render-gap-buffer-wrapping-right-then-down screen, data, x, y, 0x20/xmax, 0x20/ymax, x, y, 1/true
{
var value-ah/eax: (addr handle stream byte) <- get self, value
var value/eax: (addr stream byte) <- lookup *value-ah
var done?/eax: boolean <- stream-empty? value
compare done?, 0/false
break-if-=
return
}
y <- increment
x, y <- draw-text-wrapping-right-then-down screen, "=> ", _x, y, 0x20/xmax, 0x20/ymax, _x, y, 7/fg, 0/bg
var x2/edx: int <- copy x
var value-ah/eax: (addr handle stream byte) <- get self, value
var value/eax: (addr stream byte) <- lookup *value-ah
var dummy/eax: int <- draw-stream-rightward screen, value, x2, 0x30/xmax, y, 7/fg=grey, 0/bg
}
fn edit-sandbox _self: (addr sandbox), key: byte {
var self/esi: (addr sandbox) <- copy _self
var g/edx: grapheme <- copy key
{
compare g, 8/backspace
break-if-!=
delete-grapheme-before-cursor self
return
}
{
compare g, 0x12/ctrl-r
break-if-!=
# ctrl-r: run function outside sandbox
# required: fn (addr screen), (addr keyboard)
# Mu will pass in the real screen and keyboard.
return
}
{
compare g, 0x13/ctrl-s
break-if-!=
# ctrl-s: run sandbox(es)
var data-ah/eax: (addr handle gap-buffer) <- get self, data
var _data/eax: (addr gap-buffer) <- lookup *data-ah
var data/ecx: (addr gap-buffer) <- copy _data
var value-ah/eax: (addr handle stream byte) <- get self, value
var _value/eax: (addr stream byte) <- lookup *value-ah
var value/edx: (addr stream byte) <- copy _value
var trace-ah/eax: (addr handle trace) <- get self, trace
var trace/eax: (addr trace) <- lookup *trace-ah
run data, value, trace
return
}
add-grapheme-to-sandbox self, g
}
fn run in: (addr gap-buffer), out: (addr stream byte), trace: (addr trace) {
var read-result-storage: (handle cell)
var read-result/esi: (addr handle cell) <- address read-result-storage
read-cell in, read-result, trace
var error?/eax: boolean <- has-errors? trace
{
compare error?, 0/false
break-if-=
return
}
# TODO: eval
print-cell read-result, out
}
|