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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
|
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=UTF-8">
<title>Mu - 070table.mu</title>
<meta name="Generator" content="Vim/7.4">
<meta name="plugin-version" content="vim7.4_v2">
<meta name="syntax" content="none">
<meta name="settings" content="use_css,pre_wrap,no_foldcolumn,expand_tabs,prevent_copy=">
<meta name="colorscheme" content="minimal">
<style type="text/css">
<!--
pre { white-space: pre-wrap; font-family: monospace; color: #eeeeee; background-color: #080808; }
body { font-size: 12pt; font-family: monospace; color: #eeeeee; background-color: #080808; }
* { font-size: 12pt; font-size: 1em; }
.muData { color: #ffff00; }
.muControl { color: #c0a020; }
.Delimiter { color: #800080; }
.Comment { color: #9090ff; }
.Constant { color: #00a0a0; }
.Special { color: #c00000; }
.muRecipe { color: #ff8700; }
.muScenario { color: #00af00; }
-->
</style>
<script type='text/javascript'>
<!--
-->
</script>
</head>
<body>
<pre id='vimCodeElement'>
<span class="Comment"># A table is like an array, except that its keys are not integers but</span>
<span class="Comment"># arbitrary types.</span>
<span class="muScenario">scenario</span> table-read-write [
<span class="Constant">local-scope</span>
tab:&:table:num:num <span class="Special"><-</span> new-table<span class="Constant"> 30</span>
run [
put-index tab,<span class="Constant"> 12</span>,<span class="Constant"> 34</span>
60:num/<span class="Special">raw</span>, 61:bool/<span class="Special">raw</span> <span class="Special"><-</span> index tab,<span class="Constant"> 12</span>
]
memory-should-contain [
<span class="Constant"> 60</span> <span class="Special"><-</span><span class="Constant"> 34</span>
<span class="Constant"> 61</span> <span class="Special"><-</span><span class="Constant"> 1</span> <span class="Comment"># found</span>
]
]
<span class="muScenario">scenario</span> table-read-write-non-integer [
<span class="Constant">local-scope</span>
tab:&:table:text:num <span class="Special"><-</span> new-table<span class="Constant"> 30</span>
run [
put-index tab, <span class="Constant">[abc def]</span>,<span class="Constant"> 34</span>
1:num/<span class="Special">raw</span>, 2:bool/<span class="Special">raw</span> <span class="Special"><-</span> index tab, <span class="Constant">[abc def]</span>
]
memory-should-contain [
<span class="Constant"> 1</span> <span class="Special"><-</span><span class="Constant"> 34</span>
<span class="Constant"> 2</span> <span class="Special"><-</span><span class="Constant"> 1</span> <span class="Comment"># found</span>
]
]
<span class="muScenario">scenario</span> table-read-not-found [
<span class="Constant">local-scope</span>
tab:&:table:text:num <span class="Special"><-</span> new-table<span class="Constant"> 30</span>
run [
1:num/<span class="Special">raw</span>, 2:bool/<span class="Special">raw</span> <span class="Special"><-</span> index tab, <span class="Constant">[abc def]</span>
]
memory-should-contain [
<span class="Constant"> 1</span> <span class="Special"><-</span><span class="Constant"> 0</span>
<span class="Constant"> 2</span> <span class="Special"><-</span><span class="Constant"> 0</span> <span class="Comment"># not found</span>
]
]
<span class="muData">container</span> table:_key:_value [
length:num
capacity:num
data:&:@:table-row:_key:_value
]
<span class="muData">container</span> table-row:_key:_value [
occupied?:bool
key:_key
value:_value
]
<span class="muRecipe">def</span> new-table capacity:num<span class="muRecipe"> -> </span>result:&:table:_key:_value [
<span class="Constant">local-scope</span>
<span class="Constant">load-ingredients</span>
result <span class="Special"><-</span> new <span class="Delimiter">{</span>(table _key _value): type<span class="Delimiter">}</span>
data:&:@:table-row:_key:_value <span class="Special"><-</span> new <span class="Delimiter">{</span>(table-row _key _value): type<span class="Delimiter">}</span>, capacity
*result <span class="Special"><-</span> merge <span class="Constant">0/length</span>, capacity, data
]
<span class="muRecipe">def</span> put-index table:&:table:_key:_value, key:_key, value:_value<span class="muRecipe"> -> </span>table:&:table:_key:_value [
<span class="Constant">local-scope</span>
<span class="Constant">load-ingredients</span>
hash:num <span class="Special"><-</span> hash key
hash <span class="Special"><-</span> abs hash
capacity:num <span class="Special"><-</span> get *table, <span class="Constant">capacity:offset</span>
_, hash-key:num <span class="Special"><-</span> divide-with-remainder hash, capacity
hash-key <span class="Special"><-</span> abs hash-key <span class="Comment"># in case hash overflows from a double into a negative integer inside 'divide-with-remainder' above</span>
table-data:&:@:table-row:_key:_value <span class="Special"><-</span> get *table, <span class="Constant">data:offset</span>
x:table-row:_key:_value <span class="Special"><-</span> index *table-data, hash-key
occupied?:bool <span class="Special"><-</span> get x, <span class="Constant">occupied?:offset</span>
not-occupied?:bool <span class="Special"><-</span> not occupied?:bool
assert not-occupied?, <span class="Constant">[can't handle collisions yet]</span>
new-row:table-row:_key:_value <span class="Special"><-</span> merge <span class="Constant">1/true</span>, key, value
*table-data <span class="Special"><-</span> put-index *table-data, hash-key, new-row
]
<span class="muRecipe">def</span> index table:&:table:_key:_value, key:_key<span class="muRecipe"> -> </span>result:_value, found?:bool [
<span class="Constant">local-scope</span>
<span class="Constant">load-ingredients</span>
hash:num <span class="Special"><-</span> hash key
hash <span class="Special"><-</span> abs hash
capacity:num <span class="Special"><-</span> get *table, <span class="Constant">capacity:offset</span>
_, hash-key:num <span class="Special"><-</span> divide-with-remainder hash, capacity
hash-key <span class="Special"><-</span> abs hash-key <span class="Comment"># in case hash overflows from a double into a negative integer inside 'divide-with-remainder' above</span>
table-data:&:@:table-row:_key:_value <span class="Special"><-</span> get *table, <span class="Constant">data:offset</span>
x:table-row:_key:_value <span class="Special"><-</span> index *table-data, hash-key
empty:&:_value <span class="Special"><-</span> new <span class="Constant">_value:type</span>
result <span class="Special"><-</span> copy *empty
found?:bool <span class="Special"><-</span> get x, <span class="Constant">occupied?:offset</span>
<span class="muControl">return-unless</span> found?
key2:_key <span class="Special"><-</span> get x, <span class="Constant">key:offset</span>
found?:bool <span class="Special"><-</span> equal key, key2
<span class="muControl">return-unless</span> found?
result <span class="Special"><-</span> get x, <span class="Constant">value:offset</span>
]
<span class="muRecipe">def</span> abs n:num<span class="muRecipe"> -> </span>result:num [
<span class="Constant">local-scope</span>
<span class="Constant">load-ingredients</span>
positive?:bool <span class="Special"><-</span> greater-or-equal n,<span class="Constant"> 0</span>
<span class="muControl">return-if</span> positive?, n
result <span class="Special"><-</span> multiply n,<span class="Constant"> -1</span>
]
</pre>
</body>
</html>
<!-- vim: set foldmethod=manual : -->
|