git @ Cat's Eye Technologies Castile / a940b22
Types on every AST node; simpler AST structure; AST.copy(). catseye 12 years ago
3 changed file(s) with 55 addition(s) and 60 deletion(s). Raw diff Collapse all Expand all
00 class AST(object):
1 def __init__(self, tag, children=None, value=None):
2 # TODO 'type' should be
3 # the type, in the type system, of the value this node evaluates to
4 self._tag = tag
5 self._value = value
1 def __init__(self, tag, children=None, value=None, type=None, aux=None):
2 self.tag = tag
3 self.value = value
4 # typechecker may populate this. parser will not.
5 self.type = type
6 # typechecker may populate this. parser will not.
7 # TODO document what it means for particular nodes
8 self.aux = aux
69 if children is not None:
7 self._children = children
10 self.children = children
811 else:
9 self._children = []
12 self.children = []
1013 assert isinstance(self.children, list)
1114 for child in self.children:
1215 assert isinstance(child, AST), \
1316 "child %r of %r is not an AST node" % (child, self)
14 self.type = None # typechecker may populate this
15 self.aux = None # typechecker may populate this
16 # TODO document what it means for particular nodes
1717 #print "created %r" % self
1818
19 @property
20 def tag(self):
21 return self._tag
22
23 @property
24 def value(self):
25 return self._value
26
27 @property
28 def children(self):
29 return self._children
19 def copy(self, children=None, value=None, type=None, aux=None):
20 if children is None:
21 children = self.children
22 if value is None:
23 value = self.value
24 if type is None:
25 type = self.type
26 if aux is None:
27 aux = self.aux
28 return AST(self.tag, children=children, value=value,
29 type=type, aux=aux)
3030
3131 def __repr__(self):
3232 if self.value is None:
3333 return 'AST(%r,%r)' % (self.tag, self.children)
3434 if not self.children:
35 return 'AST(%r,value=%r)' % (self.ttag, self.value)
35 return 'AST(%r,value=%r)' % (self.tag, self.value)
3636 return 'AST(%r,%r,value=%r)' % (self.tag, self.children, self.value)
3737
3838 def minirepr(self):
113113 types = []
114114 for child in ast.children:
115115 types.append(self.type_of(child))
116 return types
116 return types # NOT A TYPE
117117 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]))
119119 elif ast.tag == 'Type':
120120 map = {
121121 'integer': Integer(),
123123 'string': String(),
124124 'void': Void(),
125125 }
126 return map[ast.value]
126 ast.type = map[ast.value]
127127 elif ast.tag == 'Body':
128128 self.context = ScopedContext({}, self.context)
129129 for child in ast.children:
130130 self.assert_eq(self.type_of(child), Void())
131131 self.context = self.context.parent
132 return Void()
132 ast.type = Void()
133133 elif ast.tag == 'VarDecls':
134134 for child in ast.children:
135135 self.assert_eq(self.type_of(child), Void())
136 return Void()
136 ast.type = Void()
137137 elif ast.tag == 'VarDecl':
138138 name = ast.value
139139 if name in self.context:
140140 raise CastileTypeError('declaration of %s shadows previous' % name)
141141 self.assignable[name] = True
142142 self.set(name, self.type_of(ast.children[0]))
143 return Void()
143 ast.type = Void()
144144 elif ast.tag == 'FunType':
145145 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:]],
147147 return_type)
148148 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])
150150 elif ast.tag == 'StructType':
151 return Struct(ast.value)
151 ast.type = Struct(ast.value)
152152 elif ast.tag == 'VarRef':
153153 ast.type = self.context[ast.value]
154154 ast.aux = self.context.level(ast.value)
171171 self.return_type = t1
172172 else:
173173 self.assert_eq(t1, self.return_type)
174 return Void()
174 ast.type = Void()
175175 elif ast.tag == 'Break':
176 return Void()
176 ast.type = Void()
177177 elif ast.tag == 'If':
178178 t1 = self.type_of(ast.children[0])
179179 assert t1 == Boolean()
180180 t2 = self.type_of(ast.children[1])
181181 if len(ast.children) == 3:
182 # TODO useless! is void.
182183 t3 = self.type_of(ast.children[2])
183184 self.assert_eq(t2, t3)
184 return t2
185 ast.type = t2
185186 else:
186 return Void()
187 ast.type = Void()
187188 elif ast.tag == 'While':
188189 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()
192193 elif ast.tag == 'Block':
193194 for child in ast.children:
194195 self.assert_eq(self.type_of(child), Void())
195 return Void()
196 ast.type = Void()
196197 elif ast.tag == 'Assignment':
197198 t1 = self.type_of(ast.children[0])
198199 if not self.is_assignable(ast.children[0]):
199200 raise CastileTypeError('cannot assign to non-local')
200201 t2 = self.type_of(ast.children[1])
201202 self.assert_eq(t1, t2)
202 return Void()
203 ast.type = Void()
203204 elif ast.tag == 'Make':
204205 t = self.type_of(ast.children[0])
205206 if t.name not in self.structs:
217218 i += 1
218219 ast.type = t
219220 elif ast.tag == 'FieldInit':
220 return self.type_of(ast.children[0])
221 ast.type = self.type_of(ast.children[0])
221222 elif ast.tag == 'Index':
222223 t = self.type_of(ast.children[0])
223224 field_name = ast.value
240241 assert ast.children[0].tag == 'VarRef'
241242 self.context = ScopedContext({}, self.context)
242243 self.context[ast.children[0].value] = t2
243 t3 = self.type_of(ast.children[2])
244 ast.type = self.type_of(ast.children[2])
244245 self.context = self.context.parent
245246 ast.aux = str(t2)
246 return t3
247247 elif ast.tag == 'Program':
248248 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()
251251 elif ast.tag == 'Defn':
252252 # reset assignable
253253 self.assignable = {}
262262 # we compare it against itself
263263 rt = t.return_type
264264 self.assert_eq(t, Function([], rt))
265 return t
265 ast.type = Void()
266266 elif ast.tag == 'Forward':
267267 t = self.type_of(ast.children[0])
268268 self.forwards[ast.value] = t
269 return self.set(ast.value, t)
269 self.set(ast.value, t)
270 ast.type = Void()
270271 elif ast.tag == 'StructDefn':
271 pass
272 ast.type = Void()
272273 elif ast.tag == 'TypeCast':
273274 val_t = self.type_of(ast.children[0])
274275 uni_t = self.type_of(ast.children[1])
3535 else:
3636 non_fun_defns.append(child)
3737 children = non_fun_defns + lifted_defns + non_lifted_defns
38 return AST(ast.tag, children, value=ast.value)
38 return ast.copy(children=children)
3939 elif ast.tag == 'Defn':
4040 # skip toplevel funlits; they don't have to be lifted.
4141 children = []
4444 grandchildren = []
4545 for grandchild in child.children:
4646 grandchildren.append(self.lift_functions(grandchild))
47 children.append(AST('FunLit', grandchildren, value=child.value))
47 children.append(child.copy(children=grandchildren))
4848 else:
4949 children.append(self.lift_functions(child))
50 return AST(ast.tag, children, value=ast.value)
50 return ast.copy(children=children)
5151 elif ast.tag == 'FunLit':
5252 children = []
5353 for child in ast.children:
5454 children.append(self.lift_functions(child))
55 new_ast = AST(ast.tag, children, value=ast.value)
56 new_ast.aux = ast.aux # TODO i wish there was a nicer way
5755 name = self.make_name()
58 self.lifted_functions.append((name, new_ast))
59 a = AST('VarRef', value=name)
60 a.aux = 'toplevel'
61 return a
56 self.lifted_functions.append((name, ast.copy(children=children)))
57 return AST('VarRef', value=name, type=ast.type, aux='toplevel')
6258 else:
6359 children = []
6460 for child in ast.children:
6561 children.append(self.lift_functions(child))
66 a = AST(ast.tag, children, value=ast.value)
67 a.aux = ast.aux
68 return a
62 return ast.copy(children=children)