diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-31 17:10:36 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-31 17:10:36 -0400 |
commit | 9e55cdb1ea5cd8318a1a0b7a9f64f09e8d8ad692 (patch) | |
tree | dd30665fb9ad6e40f1bead09bda20b53e5a8e184 | |
parent | 4322b5897449db33bb8c22bae13726c285708009 (diff) |
a.b as an lvalue
-rw-r--r-- | eval.c | 22 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | parse.c | 2 | ||||
-rw-r--r-- | test.toc | 28 | ||||
-rw-r--r-- | toc.c | 8 | ||||
-rw-r--r-- | types.c | 8 |
6 files changed, 41 insertions, 28 deletions
@@ -682,7 +682,15 @@ static bool eval_set(Evaluator *ev, Expression *set, Value *to) { /* set it to to */ eval_deref_set(ptr, to, type); } break; - default: break; + case BINARY_DOT: { + Value struc; + if (!eval_expr(ev, set->binary.lhs, &struc)) + return false; + eval_struct_find_offsets(type_inner(&set->binary.lhs->type)); + void *ptr = (char *)struc.struc + set->binary.field->offset; + eval_deref_set(ptr, to, set->binary.field->type); + } break; + default: assert(0); break; } break; case EXPR_TUPLE: @@ -812,6 +820,8 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } if (o->type.kind == TYPE_ARR) v->ptr = id->val.arr; /* point directly to data */ + else if (o->type.kind == TYPE_STRUCT) + v->ptr = id->val.struc; else v->ptr = &id->val; } break; @@ -833,7 +843,14 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { return false; v->ptr = ptr; } break; - default: break; + case BINARY_DOT: { + Value struc; + if (!eval_expr(ev, o->binary.lhs, &struc)) + return false; + eval_struct_find_offsets(type_inner(&o->binary.lhs->type)); + v->ptr = (char *)struc.struc + o->binary.field->offset; + } break; + default: assert(0); break; } break; default: @@ -1163,7 +1180,6 @@ static bool eval_decl(Evaluator *ev, Declaration *d) { while (inner_type->kind == TYPE_USER) inner_type = ident_typeval(type->user.name); if (inner_type->kind == TYPE_STRUCT) { - puts("Allocating space for struct"); id->val.struc = err_calloc(1, compiler_sizeof(inner_type)); } else if (inner_type->kind == TYPE_ARR) { id->val.arr = err_calloc(inner_type->arr.n, compiler_sizeof(inner_type->arr.of)); @@ -1,6 +1,5 @@ /* TODO: -. lvalue using dot with pointers length of slice/arr with .len verify size of struct, align of fields @@ -957,7 +957,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (token_is_kw(t->token, KW_LPAREN)) tokr_err(t, "Direct function calling in an expression is not supported.\nYou can wrap the function in parentheses."); else - tokr_err(t, "Expected end of expression."); + tokr_err(t, "Expected end of function (did you forget a semicolon?)."); return false; } return true; @@ -4,28 +4,18 @@ puti @= fn(x: int) { }; Point @= struct { - x_coordinate, y_coordinate : int; - f : fn(); + x, y : int; }; -somefn @= fn() int { - p:Point; - x := p.({ - t @= int; - f @= fn() t { 7 as t }; - if f() as int > 3 { - "x_coordinate" - } else { - "y_coordinate" - } - }); - x +sum34 @= fn() int { + p: Point; + x := &p.x; + *x = 3; + p.y = 4; + p.x + p.y }; main @= fn() { - p: Point; - X @= somefn(); - puti(X); - puti(somefn()); - puti(p.x_coordinate); +X @= sum34(); +puti(sum34()); }; @@ -22,6 +22,14 @@ #include "tokenizer.c" #include "parse.c" #include "scope.c" + + +static Type *type_inner(Type *t) { + while (t->kind == TYPE_USER) + t = ident_typeval(t->user.name); + return t; +} + #include "eval.c" #include "types.c" static bool cgen_decls_file(CGenerator *g, ParsedFile *f); @@ -171,17 +171,18 @@ static bool expr_must_lval(Expression *e) { case EXPR_BINARY_OP: switch (e->binary.op) { case BINARY_AT_INDEX: return true; + case BINARY_DOT: return true; default: break; } - break; - case EXPR_TUPLE: { + err_print(e->where, "Cannot use operator %s as l-value", binary_op_to_str(e->binary.op)); + return false; + case EXPR_TUPLE: /* x, y is an lval, but 3, "hello" is not. */ arr_foreach(e->tuple, Expression, x) { if (!expr_must_lval(x)) return false; } return true; - } break; case EXPR_CAST: case EXPR_NEW: case EXPR_FN: @@ -1352,4 +1353,3 @@ static bool types_file(Typer *tr, ParsedFile *f) { static void typer_free(Typer *tr) { allocr_free_all(&tr->allocr); } - |