113 | 113 |
types = []
|
114 | 114 |
for child in ast.children:
|
115 | 115 |
types.append(self.type_of(child))
|
116 | |
return types
|
|
116 |
return types # NOT A TYPE
|
117 | 117 |
elif ast.tag == 'Arg':
|
118 | |
return self.set(ast.value, self.type_of(ast.children[0]))
|
|
118 |
ast.type = self.set(ast.value, self.type_of(ast.children[0]))
|
119 | 119 |
elif ast.tag == 'Type':
|
120 | 120 |
map = {
|
121 | 121 |
'integer': Integer(),
|
|
123 | 123 |
'string': String(),
|
124 | 124 |
'void': Void(),
|
125 | 125 |
}
|
126 | |
return map[ast.value]
|
|
126 |
ast.type = map[ast.value]
|
127 | 127 |
elif ast.tag == 'Body':
|
128 | 128 |
self.context = ScopedContext({}, self.context)
|
129 | 129 |
for child in ast.children:
|
130 | 130 |
self.assert_eq(self.type_of(child), Void())
|
131 | 131 |
self.context = self.context.parent
|
132 | |
return Void()
|
|
132 |
ast.type = Void()
|
133 | 133 |
elif ast.tag == 'VarDecls':
|
134 | 134 |
for child in ast.children:
|
135 | 135 |
self.assert_eq(self.type_of(child), Void())
|
136 | |
return Void()
|
|
136 |
ast.type = Void()
|
137 | 137 |
elif ast.tag == 'VarDecl':
|
138 | 138 |
name = ast.value
|
139 | 139 |
if name in self.context:
|
140 | 140 |
raise CastileTypeError('declaration of %s shadows previous' % name)
|
141 | 141 |
self.assignable[name] = True
|
142 | 142 |
self.set(name, self.type_of(ast.children[0]))
|
143 | |
return Void()
|
|
143 |
ast.type = Void()
|
144 | 144 |
elif ast.tag == 'FunType':
|
145 | 145 |
return_type = self.type_of(ast.children[0])
|
146 | |
return Function([self.type_of(c) for c in ast.children[1:]],
|
|
146 |
ast.type = Function([self.type_of(c) for c in ast.children[1:]],
|
147 | 147 |
return_type)
|
148 | 148 |
elif ast.tag == 'UnionType':
|
149 | |
return Union([self.type_of(c) for c in ast.children])
|
|
149 |
ast.type = Union([self.type_of(c) for c in ast.children])
|
150 | 150 |
elif ast.tag == 'StructType':
|
151 | |
return Struct(ast.value)
|
|
151 |
ast.type = Struct(ast.value)
|
152 | 152 |
elif ast.tag == 'VarRef':
|
153 | 153 |
ast.type = self.context[ast.value]
|
154 | 154 |
ast.aux = self.context.level(ast.value)
|
|
171 | 171 |
self.return_type = t1
|
172 | 172 |
else:
|
173 | 173 |
self.assert_eq(t1, self.return_type)
|
174 | |
return Void()
|
|
174 |
ast.type = Void()
|
175 | 175 |
elif ast.tag == 'Break':
|
176 | |
return Void()
|
|
176 |
ast.type = Void()
|
177 | 177 |
elif ast.tag == 'If':
|
178 | 178 |
t1 = self.type_of(ast.children[0])
|
179 | 179 |
assert t1 == Boolean()
|
180 | 180 |
t2 = self.type_of(ast.children[1])
|
181 | 181 |
if len(ast.children) == 3:
|
|
182 |
# TODO useless! is void.
|
182 | 183 |
t3 = self.type_of(ast.children[2])
|
183 | 184 |
self.assert_eq(t2, t3)
|
184 | |
return t2
|
|
185 |
ast.type = t2
|
185 | 186 |
else:
|
186 | |
return Void()
|
|
187 |
ast.type = Void()
|
187 | 188 |
elif ast.tag == 'While':
|
188 | 189 |
t1 = self.type_of(ast.children[0])
|
189 | |
assert t1 == Boolean()
|
190 | |
t2 = self.type_of(ast.children[1])
|
191 | |
return Void()
|
|
190 |
self.assert_eq(t1, Boolean())
|
|
191 |
t2 = self.type_of(ast.children[1])
|
|
192 |
ast.type = Void()
|
192 | 193 |
elif ast.tag == 'Block':
|
193 | 194 |
for child in ast.children:
|
194 | 195 |
self.assert_eq(self.type_of(child), Void())
|
195 | |
return Void()
|
|
196 |
ast.type = Void()
|
196 | 197 |
elif ast.tag == 'Assignment':
|
197 | 198 |
t1 = self.type_of(ast.children[0])
|
198 | 199 |
if not self.is_assignable(ast.children[0]):
|
199 | 200 |
raise CastileTypeError('cannot assign to non-local')
|
200 | 201 |
t2 = self.type_of(ast.children[1])
|
201 | 202 |
self.assert_eq(t1, t2)
|
202 | |
return Void()
|
|
203 |
ast.type = Void()
|
203 | 204 |
elif ast.tag == 'Make':
|
204 | 205 |
t = self.type_of(ast.children[0])
|
205 | 206 |
if t.name not in self.structs:
|
|
217 | 218 |
i += 1
|
218 | 219 |
ast.type = t
|
219 | 220 |
elif ast.tag == 'FieldInit':
|
220 | |
return self.type_of(ast.children[0])
|
|
221 |
ast.type = self.type_of(ast.children[0])
|
221 | 222 |
elif ast.tag == 'Index':
|
222 | 223 |
t = self.type_of(ast.children[0])
|
223 | 224 |
field_name = ast.value
|
|
240 | 241 |
assert ast.children[0].tag == 'VarRef'
|
241 | 242 |
self.context = ScopedContext({}, self.context)
|
242 | 243 |
self.context[ast.children[0].value] = t2
|
243 | |
t3 = self.type_of(ast.children[2])
|
|
244 |
ast.type = self.type_of(ast.children[2])
|
244 | 245 |
self.context = self.context.parent
|
245 | 246 |
ast.aux = str(t2)
|
246 | |
return t3
|
247 | 247 |
elif ast.tag == 'Program':
|
248 | 248 |
for defn in ast.children:
|
249 | |
t1 = self.type_of(defn)
|
250 | |
return Void()
|
|
249 |
self.assert_eq(self.type_of(defn), Void())
|
|
250 |
ast.type = Void()
|
251 | 251 |
elif ast.tag == 'Defn':
|
252 | 252 |
# reset assignable
|
253 | 253 |
self.assignable = {}
|
|
262 | 262 |
# we compare it against itself
|
263 | 263 |
rt = t.return_type
|
264 | 264 |
self.assert_eq(t, Function([], rt))
|
265 | |
return t
|
|
265 |
ast.type = Void()
|
266 | 266 |
elif ast.tag == 'Forward':
|
267 | 267 |
t = self.type_of(ast.children[0])
|
268 | 268 |
self.forwards[ast.value] = t
|
269 | |
return self.set(ast.value, t)
|
|
269 |
self.set(ast.value, t)
|
|
270 |
ast.type = Void()
|
270 | 271 |
elif ast.tag == 'StructDefn':
|
271 | |
pass
|
|
272 |
ast.type = Void()
|
272 | 273 |
elif ast.tag == 'TypeCast':
|
273 | 274 |
val_t = self.type_of(ast.children[0])
|
274 | 275 |
uni_t = self.type_of(ast.children[1])
|