diff options
| author | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-04-12 02:19:23 +0300 |
|---|---|---|
| committer | Kimplul <kimi.h.kuparinen@gmail.com> | 2024-04-12 02:19:23 +0300 |
| commit | e1f17535a043b55ce34de4d7583928d8c94bb71a (patch) | |
| tree | 256299aeb970730e56a48e6ad72ac82e848a14d1 /src/ast.c | |
| parent | 7294673a9889f968eef86930d4e09f47070439fc (diff) | |
| download | ek-e1f17535a043b55ce34de4d7583928d8c94bb71a.tar.gz ek-e1f17535a043b55ce34de4d7583928d8c94bb71a.zip | |
start work on struct handling
Diffstat (limited to 'src/ast.c')
| -rw-r--r-- | src/ast.c | 70 |
1 files changed, 70 insertions, 0 deletions
@@ -91,6 +91,7 @@ static struct type *create_empty_type() struct type *n = calloc(1, sizeof(struct type)); /* just to be safe */ n->k = TYPE_VOID; + n->size = -1; vect_append(struct ast *, types, &n); return n; } @@ -379,6 +380,11 @@ struct ast *clone_ast(struct ast *n) new->v = n->v; new->f = n->f; + /* unsure if this should be a separate step maybe? Generally this is + * unwanted, but I might run into exceptions and then it's more + * difficult to rebuild the init/actual state... */ + ast_clear_flags(new, AST_FLAG_INIT | AST_FLAG_ACTUAL); + if (n->t) new->t = clone_type_list(n->t); @@ -658,3 +664,67 @@ int equiv_type_lists(struct type *t1, struct type *t2) return 1; } + +size_t align3k(size_t o) +{ + size_t rem = o % 3; + if (rem) + o += rem; + + return o; +} + +static size_t struct_size(struct type *t) +{ + if (t->size != -1) + return t->size; + + size_t size = 0; + foreach_node(n, struct_body(t->d)) { + if (n->k != AST_VAR_DEF) + continue; + + size_t sz = type_size(n->t); + if (sz > 2) + size = align3k(size); + + size += sz; + } + + t->size = size; + return size; +} + +size_t type_size(struct type *t) +{ + switch (t->k) { + case TYPE_I9: return 1; + case TYPE_I27: return 3; + case TYPE_PTR: return 3; + case TYPE_STRUCT: return struct_size(t); + default: + } + + assert(0 && "unhandled type to get size of"); + abort(); +} + +size_t type_offsetof(struct type *t, char *m) +{ + assert(t->k == TYPE_STRUCT); + + size_t offset = 0; + foreach_node(n, struct_body(t->d)) { + if (n->k != AST_VAR_DEF) + continue; + + if (same_id(var_id(n), m)) + break; + + size_t sz = type_size(n->t); + if (sz > 2) + offset = align3k(offset); + } + + return offset; +} |
