diff options
-rw-r--r-- | cgen.c | 47 | ||||
-rw-r--r-- | eval.c | 28 | ||||
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 27 | ||||
-rw-r--r-- | types.c | 27 |
5 files changed, 86 insertions, 46 deletions
@@ -740,6 +740,8 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, " = 0"); } cgen_write(g, "; "); + bool uses_ptr; + Type *of_type; if (!(is_range && !ea->range.to)) { /* if it's finite */ if (is_range) { if (ea->value) @@ -755,12 +757,17 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { else cgen_write(g, "i_"); cgen_write(g, " < "); - switch (ea->of->type.kind) { + of_type = &ea->of->type; + uses_ptr = of_type->kind == TYPE_PTR; + if (uses_ptr) { + of_type = of_type->ptr; + } + switch (of_type->kind) { case TYPE_ARR: - cgen_write(g, "%lu", (unsigned long)ea->of->type.arr.n); + cgen_write(g, "%lu", (unsigned long)of_type->arr.n); break; case TYPE_SLICE: - cgen_write(g, "of_.n"); + cgen_write(g, "of_%sn", uses_ptr ? "->" : "."); break; default: assert(0); break; } @@ -795,22 +802,25 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { /* necessary for iterating over, e.g., an array of arrays */ if (!cgen_type_pre(g, &ea->type, e->where)) return false; - cgen_write(g, "(*p_)"); + if (uses_ptr) + cgen_write(g, "p_"); + else + cgen_write(g, "(*p_)"); if (!cgen_type_post(g, &ea->type, e->where)) return false; cgen_write(g, " = "); - if (ea->of->type.kind == TYPE_SLICE) { + if (of_type->kind == TYPE_SLICE) { cgen_write(g, "(("); if (!cgen_type_pre(g, &ea->type, e->where)) return false; - cgen_write(g, "(*)"); + if (!uses_ptr) cgen_write(g, "(*)"); if (!cgen_type_post(g, &ea->type, e->where)) return false; - cgen_write(g, ")of_.data) + "); + cgen_write(g, ")of_%sdata) + ", uses_ptr ? "->" : "."); if (ea->index) cgen_ident(g, ea->index); else cgen_write(g, "i_"); } else { - cgen_write(g, "&of_["); + cgen_write(g, "&%sof_%s[", uses_ptr ? "(*" : "", uses_ptr ? ")" : ""); if (ea->index) cgen_ident(g, ea->index); else @@ -823,13 +833,20 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_ident(g, ea->value); if (!cgen_type_post(g, &ea->type, e->where)) return false; cgen_write(g, "; "); - Expression set_expr; - set_expr.kind = EXPR_IDENT; - set_expr.ident = ea->value; - set_expr.type = ea->type; - set_expr.flags = EXPR_FLAG_FOUND_TYPE; - if (!cgen_set(g, &set_expr, NULL, NULL, "(*p_)")) - return false; + if (uses_ptr) { + cgen_ident(g, ea->value); + cgen_write(g, " = p_;"); + cgen_nl(g); + } else { + Expression set_expr; + set_expr.kind = EXPR_IDENT; + set_expr.ident = ea->value; + set_expr.type = ea->type; + set_expr.flags = EXPR_FLAG_FOUND_TYPE; + + if (!cgen_set(g, &set_expr, NULL, NULL, "(*p_)")) + return false; + } } } if (!cgen_block(g, &ea->body, ret_name, CGEN_BLOCK_NOBRACES)) @@ -1251,28 +1251,42 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } else { value_val = &val; } - index_val->i64 = 0; I64 len; - switch (ea->of->type.kind) { + bool uses_ptr = false; + Type *of_type = &ea->of->type; + if (of_type->kind == TYPE_PTR) { + uses_ptr = true; + of_type = of_type->ptr; + } + switch (of_type->kind) { case TYPE_ARR: - len = (I64)ea->of->type.arr.n; + len = (I64)of_type->arr.n; + if (uses_ptr) { + of.arr = of.ptr; + } + break; case TYPE_SLICE: + if (uses_ptr) { + of.slice = *(Slice *)of.ptr; + } len = of.slice.n; break; default: assert(0); return false; } - Type i64t; i64t.flags = TYPE_FLAG_RESOLVED; i64t.kind = TYPE_BUILTIN; i64t.builtin = BUILTIN_I64; - + index_val->i64 = 0; while (index_val->i64 < len) { void *ptr; - if (!eval_val_ptr_at_index(ev, e->where, &of, (U64)index_val->i64, &ea->of->type, &i64t, &ptr, NULL)) + if (!eval_val_ptr_at_index(ev, e->where, &of, (U64)index_val->i64, of_type, &i64t, &ptr, NULL)) return false; - eval_deref(value_val, ptr, &ea->type); + if (uses_ptr) + value_val->ptr = ptr; + else + eval_deref(value_val, ptr, &ea->type); if (!eval_block(ev, &ea->body, &e->type, v)) return false; index_val->i64++; @@ -1,8 +1,5 @@ /* TODO: -allow just each arr { ... } -each pointer -compile-time each pointer prevent each x := x +=, -=, *=, /= compile-time arguments @@ -45,22 +45,21 @@ putf @= fn(x: float) { // }; g @= fn() int { - foo : [10]int; // = new(int, 10); + foo : = new(int, 10); total := 0; - each foo { total = total + 1; } -// each _, i := foo { - // foo[i] = i; - // }; - // total := 0; - // each x := foo { - // total = total + x; - // } - // total - - each i := 1..10 { - total = total + i; - total + // each foo { total = total + 1; } + each x, i := &foo { + *x = i; + }; + each x, i := foo { + total = total + x * i; } + total + + // each i := 1..10 { + // total = total + i; + // total + // } // total := 0; // each i, j := 1..10 { // total = total + i * j; @@ -735,13 +735,19 @@ static bool types_expr(Typer *tr, Expression *e) { } else { if (!types_expr(tr, ea->of)) return false; - Type *of_type = NULL; - switch (ea->of->type.kind) { + Type *iter_type = &ea->of->type; + + bool uses_ptr = false; + if (iter_type->kind == TYPE_PTR) { + uses_ptr = true; + iter_type = iter_type->ptr; + } + switch (iter_type->kind) { case TYPE_SLICE: - of_type = ea->of->type.slice; + iter_type = iter_type->slice; break; case TYPE_ARR: - of_type = ea->of->type.arr.of; + iter_type = iter_type->arr.of; break; default: { char *s = type_to_str(&ea->of->type); @@ -750,15 +756,22 @@ static bool types_expr(Typer *tr, Expression *e) { return false; } } + Type ptr_type; + if (uses_ptr) { + ptr_type.flags = TYPE_FLAG_RESOLVED; + ptr_type.kind = TYPE_PTR; + ptr_type.ptr = iter_type; + iter_type = &ptr_type; + } if (ea->flags & EACH_ANNOTATED_TYPE) { - if (!type_eq(of_type, &ea->type)) { - char *exp = type_to_str(of_type); + if (!type_eq(iter_type, &ea->type)) { + char *exp = type_to_str(iter_type); char *got = type_to_str(&ea->type); err_print(e->where, "Expected to iterate over type %s, but it was annotated as iterating over type %s."); free(exp); free(got); return false; } - } else ea->type = *of_type; + } else ea->type = *iter_type; } if ((ea->flags & EACH_IS_RANGE) && ea->range.step) { Value *stepval = typer_malloc(tr, sizeof *ea->range.stepval); |