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
|
fn initialize-table _self: (addr table), n: int {
var self/esi: (addr table) <- copy _self
var data-ah/eax: (addr handle array bind) <- get self, data
populate data-ah, n
}
fn bind-in-table _self: (addr table), key: (addr handle array byte), val: (addr value) {
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
var data/esi: (addr array bind) <- copy _data
var next-empty-slot-index/eax: (offset bind) <- next-empty-slot data, key
var dest/eax: (addr bind) <- index data, next-empty-slot-index
make-binding dest, key, val
}
# manual test: full array of binds
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
$next-empty-slot:loop: {
result <- compute-offset data, i
compare i, len
break-if->=
{
var target/esi: (addr bind) <- index data, result
var target2/esi: (addr handle array byte) <- get target, key
var target3/eax: (addr array byte) <- lookup *target2
compare target3, 0
break-if-= $next-empty-slot:loop
# TODO: how to indicate that key already exists? we don't want to permit rebinding
}
i <- increment
loop
}
}
fn make-int-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
copy-object key, dest
var dest2/eax: (addr handle value) <- get self, value
allocate dest2
var dest3/eax: (addr value) <- lookup *dest2
var dest4/eax: (addr int) <- get dest3, int-data
var val/ecx: int <- copy _val
copy-to *dest4, val
}
fn make-binding _self: (addr bind), key: (addr handle array byte), val: (addr value) {
var self/esi: (addr bind) <- copy _self
var dest/eax: (addr handle array byte) <- get self, key
copy-object key, dest
var dest2/eax: (addr handle value) <- get self, value
allocate dest2
var dest3/eax: (addr value) <- lookup *dest2
copy-object val, dest3
}
fn lookup-binding _self: (addr table), key: (addr array byte), out: (addr handle value) {
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
var data/esi: (addr array bind) <- copy _data
var len/edx: int <- length data
var i/ebx: int <- copy 0
$lookup-binding:loop: {
compare i, len
break-if->=
{
var offset/edx: (offset bind) <- compute-offset data, i
var target-bind/esi: (addr bind) <- index data, offset
var target2/edx: (addr handle array byte) <- get target-bind, key
var target3/eax: (addr array byte) <- lookup *target2
compare target3, 0
break-if-= $lookup-binding:loop
var is-match?/eax: boolean <- string-equal? target3, key
compare is-match?, 0 # false
break-if-=
# found
var target/eax: (addr handle value) <- get target-bind, value
copy-object target, out
break $lookup-binding:loop
}
i <- increment
loop
}
}
|