diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-27 21:04:26 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-03-27 21:04:26 -0400 |
commit | 7cf5a8735ecbd37faf5e9f740d5f1a49939eea07 (patch) | |
tree | d1bc70b482513ceab88c049fb8b8369581111472 | |
parent | 67c33cc90c737aa15f9b7214f9838c17253298c4 (diff) |
improved struct field lookup
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 16 | ||||
-rw-r--r-- | types.c | 19 |
3 files changed, 20 insertions, 18 deletions
@@ -8,7 +8,8 @@ /* TODO: -make sure that struct["member"] still works +do we really need StructDef.constants +all big Statement members should be pointers use - use with a decl, e.g. use p : Point; local structs should not be named in C @@ -1,10 +1,10 @@ -main ::= fn() { - Point ::= struct { - x: int; - y, z: int; +s ::= fn(t:: Type) Type { + struct { + m: t; } - p: Point; - p.x = 6; - p.y = 13; - p.z = 43902; +} + +main ::= fn() { + o: s(int); + x := o.m; } @@ -2892,16 +2892,16 @@ static Status types_expr(Typer *tr, Expression *e) { /* replace with BINARY_DOT */ e->binary.op = BINARY_DOT; - bool is_field = false; if (!eval_expr(tr->evalr, rhs, &field_name)) return false; - arr_foreach(lhs_type->struc->fields, Field, f) { - if (ident_eq_str(f->name, field_name.slice.data)) { - is_field = true; - *t = *f->type; - e->binary.dot.field = f; - } - } - if (!is_field) { + + /* get the field, if it exists */ + Identifier ident = ident_get_with_len(&lhs_type->struc->body.idents, + field_name.slice.data, (size_t)field_name.slice.n); + if (ident_is_declared(ident)) { + assert(ident->decl_kind == IDECL_DECL); + Field *f = ident->decl->field + ident_index_in_decl(ident, ident->decl); + e->binary.dot.field = f; + } else { char *fstr = err_malloc((size_t)(field_name.slice.n + 1)); memcpy(fstr, field_name.slice.data, (size_t)field_name.slice.n); fstr[field_name.slice.n] = 0; /* null-terminate */ @@ -3013,6 +3013,7 @@ static Status types_expr(Typer *tr, Expression *e) { Field *field = struct_ident->decl->field; field += ident_index_in_decl(struct_ident, struct_ident->decl); e->binary.dot.field = field; + *t = *field->type; } else { if (!get_struct_constant(struct_type->struc, rhs->ident, e)) return false; |