In C backend, generate field initializers in the correct order.
Chris Pressey
3 years ago
820 | 820 |
|
821 | 821 |
Order of field initialization when making a struct doesn't matter.
|
822 | 822 |
|
823 | |
/| struct person { name: string; age: integer }
|
824 | |
/| main = fun() {
|
825 | |
/| j = make person(age: 23, name:"Jake");
|
826 | |
/| j.age
|
827 | |
/| }
|
828 | |
/= 23
|
|
823 |
| struct person { name: string; age: integer }
|
|
824 |
| main = fun() {
|
|
825 |
| j = make person(age: 23, name:"Jake");
|
|
826 |
| j.age
|
|
827 |
| }
|
|
828 |
= 23
|
829 | 829 |
|
830 | 830 |
Structs can be tested for equality. (Since structs are immutable, it
|
831 | 831 |
doesn't matter if this is structural equality or identity.)
|
76 | 76 |
self.out.write(x)
|
77 | 77 |
|
78 | 78 |
def write_indent(self, x):
|
79 | |
self.out.write(' ' * self.indent)
|
|
79 |
self.out.write(' ' * self.indent)
|
80 | 80 |
self.out.write(x)
|
81 | 81 |
|
82 | 82 |
# as used in local variable declarations
|
|
161 | 161 |
elif ast.tag == 'Forward':
|
162 | 162 |
self.write_indent('extern %s;\n' % self.c_decl(ast.children[0].type, ast.value))
|
163 | 163 |
elif ast.tag == 'StructDefn':
|
164 | |
self.write_indent('struct %s {' % ast.value)
|
|
164 |
self.write_indent('struct %s {\n' % ast.value)
|
165 | 165 |
self.indent += 1
|
166 | 166 |
for child in ast.children:
|
167 | 167 |
self.compile(child)
|
168 | 168 |
self.indent -= 1
|
169 | |
self.write_indent('};\n')
|
|
169 |
self.write_indent('};\n\n')
|
170 | 170 |
elif ast.tag == 'FieldDefn':
|
171 | 171 |
self.write_indent('%s;\n' % self.c_decl(ast.children[0].type, ast.value))
|
172 | 172 |
elif ast.tag == 'FunLit':
|
|
264 | 264 |
self.compile(ast.children[1])
|
265 | 265 |
elif ast.tag == 'Make':
|
266 | 266 |
self.write('&(struct %s){ ' % ast.type.name)
|
267 | |
self.commas(ast.children[1:])
|
|
267 |
def find_field(name):
|
|
268 |
for field in ast.children[1:]:
|
|
269 |
if field.value == name:
|
|
270 |
return field
|
|
271 |
ordered_fields = []
|
|
272 |
for field_name in ast.type.defn.field_names_in_order():
|
|
273 |
ordered_fields.append(find_field(field_name))
|
|
274 |
self.commas(ordered_fields)
|
268 | 275 |
self.write(' }')
|
269 | 276 |
elif ast.tag == 'FieldInit':
|
270 | 277 |
self.commas(ast.children)
|
12 | 12 |
self.field_names = field_names # dict of name -> position
|
13 | 13 |
self.content_types = content_types # list of types in order
|
14 | 14 |
|
|
15 |
def field_names_in_order(self):
|
|
16 |
m = {}
|
|
17 |
for k, v in self.field_names.items():
|
|
18 |
m[v] = k
|
|
19 |
l = []
|
|
20 |
for i in range(len(m)):
|
|
21 |
l.append(m[i])
|
|
22 |
return l
|
15 | 23 |
|
16 | 24 |
class TypeChecker(object):
|
17 | 25 |
def __init__(self):
|