DISABLE FDs (REMOVE ME).
[jackhill/mal.git] / awk / types.awk
1
2 # string"
3 # symbol '
4 # keyword :
5 # number +
6 # nil #
7 # true #
8 # false #
9 # list (
10 # vector [
11 # hash {
12 # atom ?
13 # builtin function &
14 # builtin function with meta %
15 # user defined function $
16
17 function types_allocate()
18 {
19 types_heap[types_heap_index]["ref"] = 1
20 return types_heap_index++
21 }
22
23 function types_addref(ast)
24 {
25 if (ast ~ /^[([{$%?]/) {
26 ++types_heap[substr(ast, 2)]["ref"]
27 }
28 return ast
29 }
30
31 function types_release(ast, idx, ref, i, len)
32 {
33 switch (ast) {
34 case /^[([]/:
35 idx = substr(ast, 2)
36 ref = --types_heap[idx]["ref"]
37 if (ref <= 0) {
38 if (ref < 0) {
39 print "ref count error:" ast ", " ref
40 }
41 len = types_heap[idx]["len"]
42 for (i = 0; i < len; ++i) {
43 types_release(types_heap[idx][i])
44 }
45 types_release(types_heap[idx]["meta"])
46 delete types_heap[idx]
47 }
48 return
49 case /^\{/:
50 idx = substr(ast, 2)
51 ref = --types_heap[idx]["ref"]
52 if (ref <= 0) {
53 if (ref < 0) {
54 print "ref count error:" ast ", " ref
55 }
56 for (i in types_heap[idx]) {
57 if (i ~ /^[":]/) {
58 types_release(types_heap[idx][i])
59 }
60 }
61 types_release(types_heap[idx]["meta"])
62 delete types_heap[idx]
63 }
64 return
65 case /^\$/:
66 idx = substr(ast, 2)
67 ref = --types_heap[idx]["ref"]
68 if (ref <= 0) {
69 if (ref < 0) {
70 print "ref count error:" ast ", " ref
71 }
72 types_release(types_heap[idx]["params"])
73 types_release(types_heap[idx]["body"])
74 types_release(types_heap[idx]["meta"])
75 env_release(types_heap[idx]["env"])
76 delete types_heap[idx]
77 }
78 return
79 case /^%/:
80 idx = substr(ast, 2)
81 ref = --types_heap[idx]["ref"]
82 if (ref <= 0) {
83 if (ref < 0) {
84 print "ref count error:" ast ", " ref
85 }
86 types_release(types_heap[idx]["meta"])
87 delete types_heap[idx]
88 }
89 return
90 case /^\?/:
91 idx = substr(ast, 2)
92 ref = --types_heap[idx]["ref"]
93 if (ref <= 0) {
94 if (ref < 0) {
95 print "ref count error:" ast ", " ref
96 }
97 types_release(types_heap[idx]["obj"])
98 delete types_heap[idx]
99 }
100 }
101 }
102
103 function types_check(val, idx, len, i)
104 {
105 if (val !~ /^[([{?%$]/) {
106 return
107 }
108 idx = substr(val, 2)
109 if (!(idx in types_heap)) {
110 print "dangling reference " val
111 return
112 }
113 if (types_heap[idx]["checked"]++) {
114 return
115 }
116 #types_heap[idx]["checked"] = 1
117 switch (val) {
118 case /^[([]/:
119 if (!("len" in types_heap[idx])) {
120 print "length not found in " val
121 return
122 }
123 len = types_heap[idx]["len"]
124 for (i = 0; i < len; ++i) {
125 if (!(i in types_heap[idx])) {
126 print "sequence corrupted in " val " of " i
127 } else {
128 types_check(types_heap[idx][i])
129 }
130 }
131 types_check(types_heap[idx]["meta"])
132 return
133 case /^\{/:
134 for (i in types_heap[idx]) {
135 if (i != "ref") {
136 types_check(types_heap[idx][i])
137 }
138 }
139 return
140 case /^\?/:
141 if (!("obj" in types_heap[idx])) {
142 print "atom corrupted in " val
143 } else {
144 types_check(types_heap[idx]["obj"])
145 }
146 types_check(types_heap[idx]["meta"])
147 return
148 case /^%/:
149 if (!("func" in types_heap[idx])) {
150 print "function corrupted in " val
151 } else {
152 types_check(types_heap[idx]["func"])
153 }
154 types_check(types_heap[idx]["meta"])
155 return
156 case /^\$/:
157 if (!("body" in types_heap[idx])) {
158 print "function body corrupted in " val
159 } else {
160 types_check(types_heap[idx]["body"])
161 }
162 if (!("params" in types_heap[idx])) {
163 print "function params corrupted in " val
164 } else {
165 types_check(types_heap[idx]["params"])
166 }
167 if (!("env" in types_heap[idx])) {
168 print "function env corrupted in " val
169 } else {
170 env_check(types_heap[idx]["env"])
171 }
172 types_check(types_heap[idx]["meta"])
173 return
174 default:
175 print "unknown type " val
176 return
177 }
178 }
179
180 function types_dump(i, j)
181 {
182 for (i = 0; i < types_heap_index; i++) {
183 if (i in types_heap) {
184 if (isarray(types_heap[i])) {
185 if (!("checked" in types_heap[i]) || types_heap[i]["checked"] != types_heap[i]["ref"]) {
186 for (j in types_heap[i]) {
187 print " types_heap[" i "][" j "] = " types_heap[i][j]
188 }
189 }
190 } else {
191 print " types_heap[" i "] = " types_heap[i]
192 }
193 }
194 }
195 }
196
197 function types_typename(str)
198 {
199 switch (str) {
200 case /^"/: return "string"
201 case /^'/: return "symbol"
202 case /^:/: return "keyword"
203 case /^\+/: return "number"
204 case /^#nil$/: return "nil"
205 case /^#true$/: return "true"
206 case /^#false$/: return "false"
207 case /^\(/: return "list"
208 case /^\[/: return "vector"
209 case /^\{/: return "hash"
210 case /^\?/: return "atom"
211 case /^[&%]/: return "builtin function"
212 case /^\$/: return "user defined function"
213 }
214 }
215
216 BEGIN {
217 types_heap_index = 0
218 }