diff options
Diffstat (limited to 'compiler/ast.cup')
| -rw-r--r-- | compiler/ast.cup | 28 |
1 files changed, 28 insertions, 0 deletions
diff --git a/compiler/ast.cup b/compiler/ast.cup index b452241..2eb96f0 100644 --- a/compiler/ast.cup +++ b/compiler/ast.cup @@ -75,6 +75,7 @@ struct Node { body: Node *; max_locals_size: int; args: Vector *; // Vector<Variable> + is_defined: int; }; block: struct { @@ -462,4 +463,31 @@ fn type_check_binary(node: Node*, token: Token*): Node* node.etyp = type_new(TYPE_INT); } return node; +} + +// FIXME: These should be in `types.cup` ideally, but `Variable` is not defined +// there and we can't forward-declare types. +fn compound_push_field(compound: Type*, name: char*, typ: Type*): int { + if (compound.typ != TYPE_STRUCT && compound.typ != TYPE_UNION) + die("compound_push_field: not a compound type"); + + let is_union = compound.typ == TYPE_UNION; + + let field_size = size_for_type(typ); + let offset_factor = min(field_size, 8); + let offset = is_union ? 0 : align_up(compound.size, offset_factor); + compound.size = is_union ? max(field_size, compound.size) : offset + field_size; + + vector_push(compound.fields, variable_new(name, typ, offset)); + return offset; +} + +fn compound_find_field(typ: Type*, name: char*): Variable* { + for (let i = 0; i < typ.fields.size; ++i) { + let field: Variable* = typ.fields.data[i]; + if (streq(field.name, name)) { + return field; + } + } + return null; }
\ No newline at end of file |