1
2
3
4
5
6 scenario table-read-write [
7 local-scope
8 tab:&:table:num:num <- new-table 30
9 run [
10 put-index tab, 12, 34
11 60:num/raw, 61:bool/raw <- index tab, 12
12 ]
13 memory-should-contain [
14 60 <- 34
15 61 <- 1
16 ]
17 ]
18
19 scenario table-read-write-non-integer [
20 local-scope
21 tab:&:table:text:num <- new-table 30
22 run [
23 put-index tab, [abc def], 34
24 1:num/raw, 2:bool/raw <- index tab, [abc def]
25 ]
26 memory-should-contain [
27 1 <- 34
28 2 <- 1
29 ]
30 ]
31
32 scenario table-read-not-found [
33 local-scope
34 tab:&:table:text:num <- new-table 30
35 run [
36 1:num/raw, 2:bool/raw <- index tab, [abc def]
37 ]
38 memory-should-contain [
39 1 <- 0
40 2 <- 0
41 ]
42 ]
43
44 container table:_key:_value [
45 length:num
46 capacity:num
47 data:&:@:table-row:_key:_value
48 ]
49
50 container table-row:_key:_value [
51 occupied?:bool
52 key:_key
53 value:_value
54 ]
55
56 def new-table capacity:num -> result:&:table:_key:_value [
57 local-scope
58 load-inputs
59 result <- new {(table _key _value): type}
60 data:&:@:table-row:_key:_value <- new {(table-row _key _value): type}, capacity
61 *result <- merge 0/length, capacity, data
62 ]
63
64
65
66 def put-index table:&:table:_key:_value, key:_key, value:_value -> table:&:table:_key:_value [
67 local-scope
68 load-inputs
69 hash:num <- hash key
70 hash <- abs hash
71 capacity:num <- get *table, capacity:offset
72 _, hash-key:num <- divide-with-remainder hash, capacity
73 hash-key <- abs hash-key
74 table-data:&:@:table-row:_key:_value <- get *table, data:offset
75 x:table-row:_key:_value <- index *table-data, hash-key
76 occupied?:bool <- get x, occupied?:offset
77 not-occupied?:bool <- not occupied?:bool
78 assert not-occupied?, [can't handle collisions yet]
79 new-row:table-row:_key:_value <- merge true, key, value
80 *table-data <- put-index *table-data, hash-key, new-row
81 ]
82
83 def index table:&:table:_key:_value, key:_key -> result:_value, found?:bool [
84 local-scope
85 load-inputs
86 hash:num <- hash key
87 hash <- abs hash
88 capacity:num <- get *table, capacity:offset
89 _, hash-key:num <- divide-with-remainder hash, capacity
90 hash-key <- abs hash-key
91 table-data:&:@:table-row:_key:_value <- get *table, data:offset
92 x:table-row:_key:_value <- index *table-data, hash-key
93 empty:&:_value <- new _value:type
94 result <- copy *empty
95 found?:bool <- get x, occupied?:offset
96 return-unless found?
97 key2:_key <- get x, key:offset
98 found?:bool <- equal key, key2
99 return-unless found?
100 result <- get x, value:offset
101 ]
102
103 def abs n:num -> result:num [
104 local-scope
105 load-inputs
106 positive?:bool <- greater-or-equal n, 0
107 return-if positive?, n
108 result <- multiply n, -1
109 ]