diff options
| author | Mustafa Quraish <[email protected]> | 2022-02-07 03:02:39 -0500 |
|---|---|---|
| committer | Mustafa Quraish <[email protected]> | 2022-02-07 03:18:08 -0500 |
| commit | 3817688851fae07b1d6a13ba2ce1906fc9811f8f (patch) | |
| tree | bb936b224cada39dc7ede856d9f15a4000950526 /compiler/ast.cup | |
| parent | Add missing files to self-hosted directory (diff) | |
| download | cup-3817688851fae07b1d6a13ba2ce1906fc9811f8f.tar.xz cup-3817688851fae07b1d6a13ba2ce1906fc9811f8f.zip | |
[cup] Self-hosting is now possible! Make some tweaks to match C output
A bit of a chonky commit, but this ports over the remaining (well,
almost) everything from the C implementation to the self-hosted
compiler.
The only things that really remain right now are (1) defer support
and (2) support for constants in local scopes. There were used barely
enough so for now their uses have been removed, but I'll implement
them back later. Not sure how useful (2) is though.
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 |