diff --git a/TODO.md b/TODO.md index 44ce7d8..a4ecb9f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,9 +1,7 @@ TODO ---- -Don't output final value. Command-line arguments passed to `main`. (`sysmain`?) - -Name mangling for compilers (prepend with `_` most likely.) +### Tests ### Tests for unions of unions. @@ -11,13 +9,17 @@ Test for equality of union values. Tests for multiple occurrences of same type in a union. +Test for casting a union to the same union or a different union. + ### Implementation ### +Name mangling for compilers (prepend with `_` most likely.) + Struct equality in Javascript, stackmac backends. Figure out a way to do `input`, `read`, and `write` with node.js backend. -Implement `int`, `str`, `chr`, `ord` for Ruby, Javascript, stackmac. +Implement `int`, `chr`, `ord` for Ruby, Javascript, stackmac. TaggedValue -> just a tuple. @@ -27,10 +29,17 @@ and void types in unions of (void, X) should only be one value. AST nodes should have source line numbers, it would be really nice. -C backend. Other backends (Python? Java? CIL? Scheme?) +Finish C backend. + +Implement garbage collection of some sort in the C backend. Either that +or implement some kind of resource-awareness in the language itself. + +Other backends (Python? Java? CIL? Scheme?) ### Design ### +Don't output final value. Command-line arguments passed to `main`. (`sysmain`?) + Convenience: * Should we have automatic promotion (value tagging?) diff --git a/src/castile/backends/c.py b/src/castile/backends/c.py index 78a9676..9f84a89 100644 --- a/src/castile/backends/c.py +++ b/src/castile/backends/c.py @@ -183,6 +183,26 @@ def compile(self, ast): self.compile(child) self.indent -= 1 self.write_indent('};\n\n') + self.write_indent('struct %s * make_%s(' % (ast.value, ast.value)) + + for child in ast.children[:-1]: + assert child.tag == 'FieldDefn' + self.write('%s, ' % self.c_decl(child.children[0].type, child.value)) + child = ast.children[-1] + assert child.tag == 'FieldDefn' + self.write('%s' % self.c_decl(child.children[0].type, child.value)) + + self.write(') {\n') + self.indent += 1 + self.write_indent('struct %s *x = malloc(sizeof(struct %s));\n' % (ast.value, ast.value)) + + for child in ast.children: + assert child.tag == 'FieldDefn' + self.write_indent('x->%s = %s;\n' % (child.value, child.value)) + + self.write_indent('return x;\n') + self.indent -= 1 + self.write_indent('}\n') elif ast.tag == 'FieldDefn': self.write_indent('%s;\n' % self.c_decl(ast.children[0].type, ast.value)) elif ast.tag == 'FunLit': @@ -283,7 +303,7 @@ def compile(self, ast): self.write(' = ') self.compile(ast.children[1]) elif ast.tag == 'Make': - self.write('&(struct %s){ ' % ast.type.name) + self.write('make_%s(' % ast.type.name) def find_field(name): for field in ast.children[1:]: if field.value == name: @@ -292,7 +312,7 @@ def find_field(name): for field_name in ast.type.defn.field_names_in_order(): ordered_fields.append(find_field(field_name)) self.commas(ordered_fields) - self.write(' }') + self.write(')') elif ast.tag == 'FieldInit': self.commas(ast.children) elif ast.tag == 'Index':