diff options
-rw-r--r-- | cgen.c | 152 | ||||
-rw-r--r-- | copy.c | 30 | ||||
-rw-r--r-- | eval.c | 56 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | package.c | 58 | ||||
-rw-r--r-- | parse.c | 94 | ||||
-rw-r--r-- | point.toc | 2 | ||||
-rw-r--r-- | scope.c | 36 | ||||
-rw-r--r-- | std/arr.toc | 6 | ||||
-rw-r--r-- | std/io.toc | 2 | ||||
-rw-r--r-- | tests/arr/arr.toc | 12 | ||||
-rw-r--r-- | tests/arr2/arr2.toc | 12 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | types.c | 114 | ||||
-rw-r--r-- | types.h | 20 |
15 files changed, 301 insertions, 301 deletions
@@ -105,21 +105,21 @@ static bool cgen_defs_decl(CGenerator *g, Declaration *d); if (!block_f(g, &e->while_.body)) \ return false; \ break; \ - case EXPR_EACH: { \ - EachExpr *ea = e->each; \ - if (!each_enter(e)) return false; \ - if (ea->flags & EACH_IS_RANGE) { \ - if (!f(g, ea->range.from)) \ + case EXPR_FOR: { \ + ForExpr *fo = e->for_; \ + if (!for_enter(e)) return false; \ + if (fo->flags & FOR_IS_RANGE) { \ + if (!f(g, fo->range.from)) \ return false; \ - if (ea->range.to && !f(g, ea->range.to)) \ + if (fo->range.to && !f(g, fo->range.to)) \ return false; \ /* step is a value, not an expression */ \ } else { \ - if (!f(g, ea->of)) \ + if (!f(g, fo->of)) \ return false; \ } \ - if (!block_f(g, &ea->body)) return false; \ - each_exit(e); \ + if (!block_f(g, &fo->body)) return false; \ + for_exit(e); \ } break; \ case EXPR_TUPLE: \ arr_foreach(e->tuple, Expression, x) \ @@ -730,8 +730,8 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, case EXPR_WHILE: prefix_id = to->while_.c.id; goto prefixed; - case EXPR_EACH: - prefix_id = to->each->c.id; + case EXPR_FOR: + prefix_id = to->for_->c.id; goto prefixed; prefixed: for (size_t i = 0; i < arr_len(to->type.tuple); ++i) { @@ -785,7 +785,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { switch (e->kind) { case EXPR_IF: case EXPR_WHILE: - case EXPR_EACH: + case EXPR_FOR: case EXPR_BLOCK: { id = ++g->ident_counter; @@ -848,71 +848,71 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { if (!cgen_block(g, &w->body, ret_name, 0)) return false; } break; - case EXPR_EACH: { - EachExpr *ea = e->each; - int is_range = ea->flags & EACH_IS_RANGE; + case EXPR_FOR: { + ForExpr *fo = e->for_; + int is_range = fo->flags & FOR_IS_RANGE; if (is_range) { - if (!cgen_expr_pre(g, ea->range.from)) return false; - if (ea->range.to && !cgen_expr_pre(g, ea->range.to)) return false; + if (!cgen_expr_pre(g, fo->range.from)) return false; + if (fo->range.to && !cgen_expr_pre(g, fo->range.to)) return false; } else { - if (!cgen_expr_pre(g, ea->of)) return false; + if (!cgen_expr_pre(g, fo->of)) return false; } - ea->c.id = id; - if (!each_enter(e)) return false; + fo->c.id = id; + if (!for_enter(e)) return false; cgen_write(g, "{"); if (is_range) { - if (ea->range.to) { + if (fo->range.to) { /* pre generate to */ - if (!cgen_type_pre(g, &ea->type, e->where)) return false; + if (!cgen_type_pre(g, &fo->type, e->where)) return false; cgen_write(g, " to_"); - if (!cgen_type_post(g, &ea->type, e->where)) return false; + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, " = "); - if (!cgen_expr(g, ea->range.to)) + if (!cgen_expr(g, fo->range.to)) return false; cgen_write(g, "; "); } /* set value to from */ - if (ea->value) { - if (!cgen_type_pre(g, &ea->type, e->where)) return false; + if (fo->value) { + if (!cgen_type_pre(g, &fo->type, e->where)) return false; cgen_write(g, " "); - cgen_ident(g, ea->value); - if (!cgen_type_post(g, &ea->type, e->where)) return false; + cgen_ident(g, fo->value); + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, "; "); Expression val_expr; val_expr.flags = EXPR_FOUND_TYPE; val_expr.kind = EXPR_IDENT; - val_expr.ident = ea->value; - val_expr.type = ea->type; - if (!cgen_set(g, &val_expr, NULL, ea->range.from, NULL)) + val_expr.ident = fo->value; + val_expr.type = fo->type; + if (!cgen_set(g, &val_expr, NULL, fo->range.from, NULL)) return false; } else { - if (!cgen_type_pre(g, &ea->type, e->where)) return false; + if (!cgen_type_pre(g, &fo->type, e->where)) return false; cgen_write(g, " val_"); - if (!cgen_type_post(g, &ea->type, e->where)) return false; + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, "; "); - if (!cgen_set(g, NULL, "val_", ea->range.from, NULL)) + if (!cgen_set(g, NULL, "val_", fo->range.from, NULL)) return false; } } else { /* pre-generate of */ - if (!cgen_type_pre(g, &ea->of->type, e->where)) + if (!cgen_type_pre(g, &fo->of->type, e->where)) return false; cgen_write(g, " of_"); - if (!cgen_type_post(g, &ea->of->type, e->where)) + if (!cgen_type_post(g, &fo->of->type, e->where)) return false; cgen_write(g, "; "); - if (!cgen_set(g, NULL, "of_", ea->of, NULL)) + if (!cgen_set(g, NULL, "of_", fo->of, NULL)) return false; } cgen_write(g, "for ("); - if (ea->index || !is_range) { + if (fo->index || !is_range) { cgen_write(g, "i64 "); - if (ea->index) - cgen_ident(g, ea->index); + if (fo->index) + cgen_ident(g, fo->index); else cgen_write(g, "i_"); cgen_write(g, " = 0"); @@ -920,22 +920,22 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, "; "); bool uses_ptr = false; Type *of_type = NULL; - if (!(is_range && !ea->range.to)) { /* if it's finite */ + if (!(is_range && !fo->range.to)) { /* if it's finite */ if (is_range) { - if (ea->value) - cgen_ident(g, ea->value); + if (fo->value) + cgen_ident(g, fo->value); else cgen_write(g, "val_"); bool positive_step - = ea->range.stepval == NULL || val_is_nonnegative(ea->range.stepval, &ea->type); + = fo->range.stepval == NULL || val_is_nonnegative(fo->range.stepval, &fo->type); cgen_write(g, " %c= to_", positive_step ? '<' : '>'); } else { - if (ea->index) - cgen_ident(g, ea->index); + if (fo->index) + cgen_ident(g, fo->index); else cgen_write(g, "i_"); cgen_write(g, " < "); - of_type = &ea->of->type; + of_type = &fo->of->type; uses_ptr = of_type->kind == TYPE_PTR; if (uses_ptr) { of_type = of_type->ptr; @@ -953,77 +953,77 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { } cgen_write(g, "; "); if (is_range) { - if (ea->range.stepval) { - if (!cgen_val_pre(g, *ea->range.stepval, &ea->type, e->where)) + if (fo->range.stepval) { + if (!cgen_val_pre(g, *fo->range.stepval, &fo->type, e->where)) return false; } - if (ea->value) - cgen_ident(g, ea->value); + if (fo->value) + cgen_ident(g, fo->value); else cgen_write(g, "val_"); cgen_write(g, " += "); - if (ea->range.stepval) { - if (!cgen_val(g, *ea->range.stepval, &ea->type, e->where)) + if (fo->range.stepval) { + if (!cgen_val(g, *fo->range.stepval, &fo->type, e->where)) return false; } else { cgen_write(g, "1"); } - if (ea->index) cgen_write(g, ", "); + if (fo->index) cgen_write(g, ", "); } - if (ea->index || !is_range) { - if (ea->index) - cgen_ident(g, ea->index); + if (fo->index || !is_range) { + if (fo->index) + cgen_ident(g, fo->index); else cgen_write(g, "i_"); cgen_write(g, "++"); } cgen_write(g, ") {"); cgen_nl(g); - if (ea->value) { + if (fo->value) { if (!is_range) { /* necessary for iterating over, e.g., an array of arrays */ - if (!cgen_type_pre(g, &ea->type, e->where)) + if (!cgen_type_pre(g, &fo->type, e->where)) return false; if (uses_ptr) cgen_write(g, " p_"); else cgen_write(g, "(*p_)"); - if (!cgen_type_post(g, &ea->type, e->where)) + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, " = "); if (of_type->kind == TYPE_SLICE) { cgen_write(g, "(("); - if (!cgen_type_pre(g, &ea->type, e->where)) return false; + if (!cgen_type_pre(g, &fo->type, e->where)) return false; if (!uses_ptr) cgen_write(g, "(*)"); - if (!cgen_type_post(g, &ea->type, e->where)) return false; + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, ")of_%sdata) + ", uses_ptr ? "->" : "."); - if (ea->index) - cgen_ident(g, ea->index); + if (fo->index) + cgen_ident(g, fo->index); else cgen_write(g, "i_"); } else { cgen_write(g, "&%sof_%s[", uses_ptr ? "(*" : "", uses_ptr ? ")" : ""); - if (ea->index) - cgen_ident(g, ea->index); + if (fo->index) + cgen_ident(g, fo->index); else cgen_write(g, "i_"); cgen_write(g, "]"); } cgen_write(g, "; "); - if (!cgen_type_pre(g, &ea->type, e->where)) return false; + if (!cgen_type_pre(g, &fo->type, e->where)) return false; cgen_write(g, " "); - cgen_ident(g, ea->value); - if (!cgen_type_post(g, &ea->type, e->where)) return false; + cgen_ident(g, fo->value); + if (!cgen_type_post(g, &fo->type, e->where)) return false; cgen_write(g, "; "); if (uses_ptr) { - cgen_ident(g, ea->value); + cgen_ident(g, fo->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.ident = fo->value; + set_expr.type = fo->type; set_expr.flags = EXPR_FOUND_TYPE; if (!cgen_set(g, &set_expr, NULL, NULL, "(*p_)")) @@ -1031,10 +1031,10 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { } } } - if (!cgen_block(g, &ea->body, ret_name, CGEN_BLOCK_NOBRACES)) + if (!cgen_block(g, &fo->body, ret_name, CGEN_BLOCK_NOBRACES)) return false; cgen_write(g, "}}"); - each_exit(e); + for_exit(e); } break; case EXPR_BLOCK: e->block_ret_id = id; @@ -1486,9 +1486,9 @@ static bool cgen_expr(CGenerator *g, Expression *e) { if (e->type.kind != TYPE_VOID) cgen_ident_id(g, e->block_ret_id); break; - case EXPR_EACH: + case EXPR_FOR: if (e->type.kind != TYPE_VOID) - cgen_ident_id(g, e->each->c.id); + cgen_ident_id(g, e->for_->c.id); break; case EXPR_CALL: if (e->type.kind == TYPE_TUPLE) { @@ -192,23 +192,23 @@ static void copy_expr(Copier *c, Expression *out, Expression *in) { wout->cond = copy_expr_(c, win->cond); copy_block(c, &wout->body, &win->body); } break; - case EXPR_EACH: { - EachExpr *ein = in->each; - EachExpr *eout = allocr_malloc(a, sizeof *eout); - out->each = eout; - *eout = *ein; - if (ein->flags & EACH_ANNOTATED_TYPE) - copy_type(c, &eout->type, &ein->type); - if (ein->flags & EACH_IS_RANGE) { - eout->range.from = copy_expr_(c, ein->range.from); - if (ein->range.to) - eout->range.to = copy_expr_(c, ein->range.to); - if (ein->range.step) - eout->range.step = copy_expr_(c, ein->range.step); + case EXPR_FOR: { + ForExpr *fin = in->for_; + ForExpr *fout = allocr_malloc(a, sizeof *fout); + out->for_ = fout; + *fout = *fin; + if (fin->flags & FOR_ANNOTATED_TYPE) + copy_type(c, &fout->type, &fin->type); + if (fin->flags & FOR_IS_RANGE) { + fout->range.from = copy_expr_(c, fin->range.from); + if (fin->range.to) + fout->range.to = copy_expr_(c, fin->range.to); + if (fin->range.step) + fout->range.step = copy_expr_(c, fin->range.step); } else { - eout->of = copy_expr_(c, ein->of); + fout->of = copy_expr_(c, fin->of); } - copy_block(c, &eout->body, &ein->body); + copy_block(c, &fout->body, &fin->body); } break; case EXPR_FN: copy_fn_expr(c, out->fn = allocr_malloc(a, sizeof *out->fn), in->fn, true); @@ -1270,9 +1270,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_block(ev, &w->body, &e->type, v)) return false; } } break; - case EXPR_EACH: { - EachExpr *ea = e->each; - if (ea->flags & EACH_IS_RANGE) { + case EXPR_FOR: { + ForExpr *fo = e->for_; + if (fo->flags & FOR_IS_RANGE) { Value from, to; Value stepval; stepval.i64 = 1; @@ -1280,69 +1280,69 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { i64t.flags = TYPE_IS_RESOLVED; i64t.kind = TYPE_BUILTIN; i64t.builtin = BUILTIN_I64; - if (!eval_expr(ev, ea->range.from, &from)) return false; - if (ea->range.to && !eval_expr(ev, ea->range.to, &to)) return false; - if (ea->range.stepval) - stepval = *ea->range.stepval; + if (!eval_expr(ev, fo->range.from, &from)) return false; + if (fo->range.to && !eval_expr(ev, fo->range.to, &to)) return false; + if (fo->range.stepval) + stepval = *fo->range.stepval; Value x = from; Value *index_val; Value *value_val; - if (!each_enter(e)) return false; - if (ea->index) { - IdentDecl *idecl = ident_decl(ea->index); + if (!for_enter(e)) return false; + if (fo->index) { + IdentDecl *idecl = ident_decl(fo->index); idecl->flags |= IDECL_HAS_VAL; index_val = &idecl->val; } else { index_val = NULL; } - if (ea->value) { - IdentDecl *idecl = ident_decl(ea->value); + if (fo->value) { + IdentDecl *idecl = ident_decl(fo->value); idecl->flags |= IDECL_HAS_VAL; value_val = &idecl->val; } else { value_val = NULL; } - bool step_is_negative = ea->range.stepval && !val_is_nonnegative(&stepval, &ea->type); + bool step_is_negative = fo->range.stepval && !val_is_nonnegative(&stepval, &fo->type); if (index_val) index_val->i64 = 0; while (1) { - if (ea->range.to) { + if (fo->range.to) { /* check if loop has ended */ Value lhs = x; Value rhs = to; - assert(ea->type.kind == TYPE_BUILTIN); + assert(fo->type.kind == TYPE_BUILTIN); Type boolt = {0}; boolt.flags = TYPE_IS_RESOLVED; boolt.kind = TYPE_BUILTIN; boolt.builtin = BUILTIN_BOOL; Value cont; - eval_numerical_bin_op(lhs, &ea->type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &ea->range.to->type, &cont, &boolt); + eval_numerical_bin_op(lhs, &fo->type, step_is_negative ? BINARY_GE : BINARY_LE, rhs, &fo->range.to->type, &cont, &boolt); if (!cont.boolv) break; } if (value_val) *value_val = x; - if (!eval_block(ev, &ea->body, &e->type, v)) return false; + if (!eval_block(ev, &fo->body, &e->type, v)) return false; if (index_val) { ++index_val->i64; } - eval_numerical_bin_op(x, &ea->type, BINARY_ADD, stepval, ea->range.stepval ? &ea->type : &i64t, &x, &ea->type); + eval_numerical_bin_op(x, &fo->type, BINARY_ADD, stepval, fo->range.stepval ? &fo->type : &i64t, &x, &fo->type); } } else { Value of; - if (!eval_expr(ev, ea->of, &of)) return false; + if (!eval_expr(ev, fo->of, &of)) return false; Value *index_val, *value_val; Value i, val; - if (!each_enter(e)) return false; - if (ea->index) { - IdentDecl *idecl = ident_decl(ea->index); + if (!for_enter(e)) return false; + if (fo->index) { + IdentDecl *idecl = ident_decl(fo->index); idecl->flags |= IDECL_HAS_VAL; index_val = &idecl->val; } else { index_val = &i; } - if (ea->value) { - IdentDecl *idecl = ident_decl(ea->value); + if (fo->value) { + IdentDecl *idecl = ident_decl(fo->value); idecl->flags |= IDECL_HAS_VAL; value_val = &idecl->val; } else { @@ -1350,7 +1350,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } I64 len; bool uses_ptr = false; - Type *of_type = &ea->of->type; + Type *of_type = &fo->of->type; if (of_type->kind == TYPE_PTR) { uses_ptr = true; of_type = of_type->ptr; @@ -1380,13 +1380,13 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (uses_ptr) value_val->ptr = ptr; else - eval_deref(value_val, ptr, &ea->type); - if (!eval_block(ev, &ea->body, &e->type, v)) + eval_deref(value_val, ptr, &fo->type); + if (!eval_block(ev, &fo->body, &e->type, v)) return false; ++index_val->i64; } } - each_exit(e); + for_exit(e); } break; case EXPR_BLOCK: if (!eval_block(ev, &e->block, &e->type, v)) return false; @@ -18,9 +18,9 @@ /* TODO: -each=>for - -#builtin("sizeof(int)") etc. +#builtin("sizeof int") +#builtin("target sizeof int") +etc. #include constants in structs @@ -771,32 +771,32 @@ static bool export_expr(Exporter *ex, Expression *e) { if (!export_optional_expr(ex, s->to)) return false; } break; - case EXPR_EACH: { - EachExpr *ea = e->each; - possibly_static_assert(sizeof ea->flags == 1); - export_u8(ex, ea->flags); - if ((ea->flags & EACH_ANNOTATED_TYPE) || found_type) - if (!export_type(ex, &ea->type, e->where)) + case EXPR_FOR: { + ForExpr *fo = e->for_; + possibly_static_assert(sizeof fo->flags == 1); + export_u8(ex, fo->flags); + if ((fo->flags & FOR_ANNOTATED_TYPE) || found_type) + if (!export_type(ex, &fo->type, e->where)) return false; - export_ident(ex, ea->index); - export_ident(ex, ea->value); - if (ea->flags & EACH_IS_RANGE) { - if (!export_expr(ex, ea->range.from)) + export_ident(ex, fo->index); + export_ident(ex, fo->value); + if (fo->flags & FOR_IS_RANGE) { + if (!export_expr(ex, fo->range.from)) return false; - if (!export_optional_expr(ex, ea->range.to)) + if (!export_optional_expr(ex, fo->range.to)) return false; if (found_type) { - if (!export_optional_val(ex, ea->range.stepval, &ea->type, e->where)) + if (!export_optional_val(ex, fo->range.stepval, &fo->type, e->where)) return false; } else { - if (!export_optional_expr(ex, ea->range.step)) + if (!export_optional_expr(ex, fo->range.step)) return false; } } else { - if (!export_expr(ex, ea->of)) + if (!export_expr(ex, fo->of)) return false; } - if (!export_block(ex, &ea->body)) + if (!export_block(ex, &fo->body)) return false; } break; } @@ -923,25 +923,25 @@ static void import_expr(Importer *im, Expression *e) { s->from = import_optional_expr(im); s->to = import_optional_expr(im); } break; - case EXPR_EACH: { - EachExpr *ea = e->each = imptr_calloc(im, 1, sizeof *ea); - ea->flags = import_u8(im); - if ((ea->flags & EACH_ANNOTATED_TYPE) || found_type) - import_type(im, &ea->type); - ea->index = import_ident(im); - ea->value = import_ident(im); - if (ea->flags & EACH_IS_RANGE) { - ea->range.from = import_expr_(im); - ea->range.to = import_optional_expr(im); + case EXPR_FOR: { + ForExpr *fo = e->for_ = imptr_calloc(im, 1, sizeof *fo); + fo->flags = import_u8(im); + if ((fo->flags & FOR_ANNOTATED_TYPE) || found_type) + import_type(im, &fo->type); + fo->index = import_ident(im); + fo->value = import_ident(im); + if (fo->flags & FOR_IS_RANGE) { + fo->range.from = import_expr_(im); + fo->range.to = import_optional_expr(im); if (found_type) { - ea->range.stepval = import_optional_val(im, &ea->type); + fo->range.stepval = import_optional_val(im, &fo->type); } else { - ea->range.step = import_optional_expr(im); + fo->range.step = import_optional_expr(im); } } else { - ea->of = import_expr_(im); + fo->of = import_expr_(im); } - import_block(im, &ea->body); + import_block(im, &fo->body); } break; } } @@ -33,7 +33,7 @@ static const char *expr_kind_to_str(ExprKind k) { case EXPR_LITERAL_CHAR: return "character literal"; case EXPR_IF: return "if expression"; case EXPR_WHILE: return "while expression"; - case EXPR_EACH: return "each expression"; + case EXPR_FOR: return "for expression"; case EXPR_CALL: return "function call"; case EXPR_C: return "C code"; case EXPR_BUILTIN: return "#builtin value"; @@ -1143,12 +1143,12 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_block(p, &w->body)) return false; goto success; } - case KW_EACH: { - e->kind = EXPR_EACH; - EachExpr *ea = e->each = parser_malloc(p, sizeof *ea); - ea->flags = 0; - ea->value = NULL; - ea->index = NULL; + case KW_FOR: { + e->kind = EXPR_FOR; + ForExpr *fo = e->for_ = parser_malloc(p, sizeof *fo); + fo->flags = 0; + fo->value = NULL; + fo->index = NULL; ++t->token; if (token_is_kw(t->token, KW_COLON) || (t->token->kind == TOKEN_IDENT @@ -1157,25 +1157,25 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { && t->token[2].kind == TOKEN_IDENT && token_is_kw(t->token + 3, KW_COLON))))) { if (t->token->kind == TOKEN_IDENT) { - ea->value = t->token->ident; - if (ident_eq_str(ea->value, "_")) /* ignore value */ - ea->value = NULL; + fo->value = t->token->ident; + if (ident_eq_str(fo->value, "_")) /* ignore value */ + fo->value = NULL; ++t->token; if (token_is_kw(t->token, KW_COMMA)) { ++t->token; if (t->token->kind == TOKEN_IDENT) { - ea->index = t->token->ident; - if (ident_eq_str(ea->index, "_")) /* ignore index */ - ea->index = NULL; + fo->index = t->token->ident; + if (ident_eq_str(fo->index, "_")) /* ignore index */ + fo->index = NULL; ++t->token; } else { - tokr_err(t, "Expected identifier after , in each statement."); + tokr_err(t, "Expected identifier after , in for loop."); return false; } } } if (!token_is_kw(t->token, KW_COLON)) { - tokr_err(t, "Expected : following identifiers in for statement."); + tokr_err(t, "Expected : following identifiers in for loop."); return false; } ++t->token; @@ -1184,8 +1184,8 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { return false; } if (!token_is_kw(t->token, KW_EQ)) { - ea->flags |= EACH_ANNOTATED_TYPE; - if (!parse_type(p, &ea->type)) + fo->flags |= FOR_ANNOTATED_TYPE; + if (!parse_type(p, &fo->type)) return false; if (!token_is_kw(t->token, KW_EQ)) { tokr_err(t, "Expected = in for statement."); @@ -1199,31 +1199,31 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { if (!parse_expr(p, first, first_end)) return false; if (token_is_kw(first_end, KW_LBRACE)) { - ea->of = first; + fo->of = first; } else if (token_is_kw(first_end, KW_DOTDOT) || token_is_kw(first_end, KW_COMMA)) { - ea->flags |= EACH_IS_RANGE; - ea->range.from = first; + fo->flags |= FOR_IS_RANGE; + fo->range.from = first; if (token_is_kw(first_end, KW_COMMA)) { /* step */ ++t->token; - ea->range.step = parser_new_expr(p); + fo->range.step = parser_new_expr(p); Token *step_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE|EXPR_CAN_END_WITH_DOTDOT); - if (!parse_expr(p, ea->range.step, step_end)) + if (!parse_expr(p, fo->range.step, step_end)) return false; if (!token_is_kw(step_end, KW_DOTDOT)) { err_print(token_location(p->file, step_end), "Expected .. to follow step in for statement."); return false; } } else { - ea->range.step = NULL; + fo->range.step = NULL; } ++t->token; /* move past .. */ if (token_is_kw(t->token, KW_LBRACE)) { - ea->range.to = NULL; /* infinite loop! */ + fo->range.to = NULL; /* infinite loop! */ } else { - ea->range.to = parser_new_expr(p); + fo->range.to = parser_new_expr(p); Token *to_end = expr_find_end(p, EXPR_CAN_END_WITH_LBRACE); - if (!parse_expr(p, ea->range.to, to_end)) + if (!parse_expr(p, fo->range.to, to_end)) return false; if (!token_is_kw(t->token, KW_LBRACE)) { tokr_err(t, "Expected { to open body of for statement."); @@ -1235,7 +1235,7 @@ static bool parse_expr(Parser *p, Expression *e, Token *end) { return false; } - if (!parse_block(p, &ea->body)) + if (!parse_block(p, &fo->body)) return false; goto success; } @@ -2249,42 +2249,42 @@ static void fprint_expr(FILE *out, Expression *e) { if (e->while_.cond) fprint_expr(out, e->while_.cond); fprint_block(out, &e->while_.body); break; - case EXPR_EACH: { - EachExpr *ea = e->each; - fprintf(out, "each "); - if (ea->index) { - fprint_ident_debug(out, ea->index); + case EXPR_FOR: { + ForExpr *fo = e->for_; + fprintf(out, "for "); + if (fo->index) { + fprint_ident_debug(out, fo->index); } else fprintf(out, "_"); fprintf(out, ", "); - if (ea->value) { - fprint_ident_debug(out, ea->value); + if (fo->value) { + fprint_ident_debug(out, fo->value); } else fprintf(out, "_"); fprintf(out, " :"); - if (ea->flags & EACH_ANNOTATED_TYPE) - fprint_type(out, &ea->type); + if (fo->flags & FOR_ANNOTATED_TYPE) + fprint_type(out, &fo->type); fprintf(out, "= "); - if (ea->flags & EACH_IS_RANGE) { - fprint_expr(out, ea->range.from); + if (fo->flags & FOR_IS_RANGE) { + fprint_expr(out, fo->range.from); if (found_type) { - if (ea->range.stepval) { + if (fo->range.stepval) { fprintf(out, ","); - fprint_val(out, *ea->range.stepval, &ea->type); + fprint_val(out, *fo->range.stepval, &fo->type); } } else { - if (ea->range.step) { + if (fo->range.step) { fprintf(out, ","); - fprint_expr(out, ea->range.step); + fprint_expr(out, fo->range.step); } } fprintf(out, ".."); - if (ea->range.to) { - fprint_expr(out, ea->range.to); + if (fo->range.to) { + fprint_expr(out, fo->range.to); } fprintf(out, " "); } else { - fprint_expr(out, ea->of); + fprint_expr(out, fo->of); } - fprint_block(out, &ea->body); + fprint_block(out, &fo->body); } break; case EXPR_CALL: fprint_expr(out, e->call.fn); @@ -2462,7 +2462,7 @@ static bool expr_is_definitely_const(Expression *e) { case EXPR_CALL: case EXPR_BLOCK: case EXPR_TUPLE: - case EXPR_EACH: + case EXPR_FOR: case EXPR_FN: return false; case EXPR_UNARY_OP: @@ -6,7 +6,7 @@ pkg "point"; }; bar ::= fn() []int { x:[]int = new(int,20); - each p, i := &x { + for p, i := &x { *p = i; } x @@ -97,37 +97,37 @@ static void fn_exit(FnExpr *f) { remove_ident_decls(&f->body, decl); } -static bool each_enter(Expression *e) { - assert(e->kind == EXPR_EACH); - EachExpr *ea = e->each; - if (ea->index && ea->index == ea->value) { - err_print(e->where, "The identifier for the index of an each loop must be different from the identifier for the value."); +static bool for_enter(Expression *e) { + assert(e->kind == EXPR_FOR); + ForExpr *fo = e->for_; + if (fo->index && fo->index == fo->value) { + err_print(e->where, "The identifier for the index of a for loop must be different from the identifier for the value."); return false; } - if (ea->index) { - IdentDecl *id = arr_add(&ea->index->decls); + if (fo->index) { + IdentDecl *id = arr_add(&fo->index->decls); id->flags = 0; id->kind = IDECL_EXPR; - id->scope = &ea->body; + id->scope = &fo->body; id->expr = e; } - if (ea->value) { - IdentDecl *id = arr_add(&ea->value->decls); + if (fo->value) { + IdentDecl *id = arr_add(&fo->value->decls); id->flags = 0; id->kind = IDECL_EXPR; - id->scope = &ea->body; + id->scope = &fo->body; id->expr = e; } return true; } -static void each_exit(Expression *e) { - assert(e->kind == EXPR_EACH); - EachExpr *ea = e->each; - if (ea->index) { - arr_remove_last(&ea->index->decls); +static void for_exit(Expression *e) { + assert(e->kind == EXPR_FOR); + ForExpr *fo = e->for_; + if (fo->index) { + arr_remove_last(&fo->index->decls); } - if (ea->value) { - arr_remove_last(&ea->value->decls); + if (fo->value) { + arr_remove_last(&fo->value->decls); } } diff --git a/std/arr.toc b/std/arr.toc index fcf6a45..af89ecb 100644 --- a/std/arr.toc +++ b/std/arr.toc @@ -11,7 +11,7 @@ pkg "arr"; if a.len >= a.cap { a.cap = a.cap * 2 + 2; new_data := new(t, a.cap); - each i := 0..a.len-1 { + for i := 0..a.len-1 { new_data[i] = a.data[i]; } a.data = new_data; @@ -20,8 +20,8 @@ pkg "arr"; a.len += 1; }; -#export arr_foreach ::= fn(t ::=, a : Arr(t), f : fn(&t)) { - each i := 0..a.len-1 { +#export arr_forfor ::= fn(t ::=, a : Arr(t), f : fn(&t)) { + for i := 0..a.len-1 { f(&a.data[i]); } }; @@ -3,7 +3,7 @@ pkg "io"; c_putchar :: fn(i32) i32 = #foreign "putchar", "libc.so.6"; #export puts ::= fn(x: []char) { - each c := x { + for c := x { c_putchar(c as i32); }; c_putchar('\n' as i32); diff --git a/tests/arr/arr.toc b/tests/arr/arr.toc index d18e8ea..f7c6707 100644 --- a/tests/arr/arr.toc +++ b/tests/arr/arr.toc @@ -19,7 +19,7 @@ arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { if a.len >= a.cap { a.cap = a.cap * 2 + 2; new_data := new(t, a.cap); - each i := 0..a.len-1 { + for i := 0..a.len-1 { new_data[i] = a.data[i]; } a.data = new_data; @@ -30,11 +30,11 @@ arr_add ::= fn(t :: Type, a : &Arr(t), x : t) { square ::= fn(t :: Type, x : t) t { a : Arr(t); - each i := 1,2..2*x-1 { + for i := 1,2..2*x-1 { arr_add(t, &a, i); }; sum := 0 as t; - each i := 0..a.len-1 { + for i := 0..a.len-1 { sum += a.data[i]; }; sum @@ -50,14 +50,14 @@ inc ::= fn(t :: Type, x : t) t { main ::= fn() { arr : ArrInt; farr : Arr(float); - each i := 1..100 { + for i := 1..100 { arr_add(int, &arr, inc(int, square(int, i))); arr_add(float, &farr, inc(float, square(float, i as float))); } - each i := 0..arr.len - 1 { + for i := 0..arr.len - 1 { puti(arr.data[i]); } - each i := 0..farr.len - 1 { + for i := 0..farr.len - 1 { putf(farr.data[i]); } }; diff --git a/tests/arr2/arr2.toc b/tests/arr2/arr2.toc index 7056416..e28d355 100644 --- a/tests/arr2/arr2.toc +++ b/tests/arr2/arr2.toc @@ -21,7 +21,7 @@ arr_add ::= fn(t ::=, a : &Arr(t), x : t) { if a.len >= a.cap { a.cap = a.cap * 2 + 2; new_data := new(t, a.cap); - each i := 0..a.len-1 { + for i := 0..a.len-1 { new_data[i] = a.data[i]; } a.data = new_data; @@ -32,11 +32,11 @@ arr_add ::= fn(t ::=, a : &Arr(t), x : t) { square ::= fn(t ::=, x : t) t { a : Arr(t); - each i := 1,2..2*x-1 { + for i := 1,2..2*x-1 { arr_add(&a, i); }; sum := 0 as t; - each i := 0..a.len-1 { + for i := 0..a.len-1 { sum += a.data[i]; }; sum @@ -52,14 +52,14 @@ inc ::= fn(t ::=, x : t) t { main ::= fn() { arr : Arr(int); farr : Arr(float); - each i := 1..100 { + for i := 1..100 { arr_add(&arr, inc(square(i))); arr_add(&farr, inc(square(i as float))); } - each i := 0..arr.len - 1 { + for i := 0..arr.len - 1 { puti(arr.data[i]); } - each i := 0..farr.len - 1 { + for i := 0..farr.len - 1 { putf(farr.data[i]); } }; diff --git a/tokenizer.c b/tokenizer.c index 39b7f06..98c0d13 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -9,7 +9,7 @@ static const char *const keywords[KW_COUNT] = "!=", "<=", "<", ">=", ">", "+", "-", "*", "!", "&", "/", "..", ".", "=", - "if", "elif", "else", "while", "each", "return", "fn", "as", + "if", "elif", "else", "while", "for", "return", "fn", "as", "new", "del", "struct", "int", "i8", "i16", "i32", "i64", "u8", "u16", "u32", "u64", "float", "f32", "f64", "Type", @@ -165,7 +165,7 @@ static bool expr_must_lval(Expression *e) { case EXPR_LITERAL_BOOL: case EXPR_IF: case EXPR_WHILE: - case EXPR_EACH: + case EXPR_FOR: case EXPR_CALL: case EXPR_C: case EXPR_BUILTIN: @@ -480,13 +480,13 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { } switch (e->kind) { - case EXPR_EACH: - if (i == e->each->index) { + case EXPR_FOR: + if (i == e->for_->index) { t->kind = TYPE_BUILTIN; t->builtin = BUILTIN_I64; } else { - assert(i == e->each->value); - *t = e->each->type; + assert(i == e->for_->value); + *t = e->for_->type; } break; default: assert(0); return false; @@ -1071,78 +1071,78 @@ static bool types_expr(Typer *tr, Expression *e) { e->val.pkg = pkg; fclose(fp); } break; - case EXPR_EACH: { - EachExpr *ea = e->each; + case EXPR_FOR: { + ForExpr *fo = e->for_; *(Expression **)typer_arr_add(tr, &tr->in_expr_decls) = e; - if (!each_enter(e)) return false; - if (ea->flags & EACH_IS_RANGE) { + if (!for_enter(e)) return false; + if (fo->flags & FOR_IS_RANGE) { /* TODO: allow user-defined numerical types */ - if (!types_expr(tr, ea->range.from)) return false; + if (!types_expr(tr, fo->range.from)) return false; { - Type *ft = &ea->range.from->type; + Type *ft = &fo->range.from->type; if (ft->kind != TYPE_BUILTIN || !type_builtin_is_numerical(ft->builtin)) { char *s = type_to_str(ft); - err_print(e->where, "from expression of each must be a builtin numerical type, not %s", s); + err_print(e->where, "from expression of for loop must be a builtin numerical type, not %s", s); free(s); } } - if (ea->range.step) { - if (!types_expr(tr, ea->range.step)) return false; - Type *st = &ea->range.step->type; + if (fo->range.step) { + if (!types_expr(tr, fo->range.step)) return false; + Type *st = &fo->range.step->type; if (st->kind != TYPE_BUILTIN || !type_builtin_is_numerical(st->builtin)) { char *s = type_to_str(st); - err_print(e->where, "step expression of each must be a builtin numerical type, not %s", s); + err_print(e->where, "step expression of for loop must be a builtin numerical type, not %s", s); free(s); } } - if (ea->range.to) { - if (!types_expr(tr, ea->range.to)) return false; - Type *tt = &ea->range.to->type; + if (fo->range.to) { + if (!types_expr(tr, fo->range.to)) return false; + Type *tt = &fo->range.to->type; if (tt->kind != TYPE_BUILTIN || !type_builtin_is_numerical(tt->builtin)) { char *s = type_to_str(tt); - err_print(e->where, "to expression of each must be a builtin numerical type, not %s", s); + err_print(e->where, "to expression of for loop must be a builtin numerical type, not %s", s); free(s); } } - if (!(ea->flags & EACH_ANNOTATED_TYPE)) { - ea->type = ea->range.from->type; + if (!(fo->flags & FOR_ANNOTATED_TYPE)) { + fo->type = fo->range.from->type; } - if (!type_eq(&ea->type, &ea->range.from->type)) { - char *exp = type_to_str(&ea->type); - char *got = type_to_str(&ea->range.from->type); - err_print(e->where, "Type of each does not match the type of the from expression. Expected %s, but got %s.", exp, got); + if (!type_eq(&fo->type, &fo->range.from->type)) { + char *exp = type_to_str(&fo->type); + char *got = type_to_str(&fo->range.from->type); + err_print(e->where, "Type of for loop does not match the type of the from expression. Expected %s, but got %s.", exp, got); free(exp); free(got); return false; } - if (ea->range.step && !type_eq(&ea->type, &ea->range.step->type)) { - char *exp = type_to_str(&ea->type); - char *got = type_to_str(&ea->range.step->type); - err_print(e->where, "Type of each does not match the type of the step expression. Expected %s, but got %s.", exp, got); + if (fo->range.step && !type_eq(&fo->type, &fo->range.step->type)) { + char *exp = type_to_str(&fo->type); + char *got = type_to_str(&fo->range.step->type); + err_print(e->where, "Type of for loop does not match the type of the step expression. Expected %s, but got %s.", exp, got); free(exp); free(got); return false; } - if ((ea->type.flags & TYPE_IS_FLEXIBLE) && ea->range.step) - ea->type = ea->range.step->type; + if ((fo->type.flags & TYPE_IS_FLEXIBLE) && fo->range.step) + fo->type = fo->range.step->type; - if (ea->range.to && !type_eq(&ea->type, &ea->range.to->type)) { - char *exp = type_to_str(&ea->type); - char *got = type_to_str(&ea->range.to->type); - err_print(e->where, "Type of each does not match the type of the to expression. Expected %s, but got %s.", exp, got); + if (fo->range.to && !type_eq(&fo->type, &fo->range.to->type)) { + char *exp = type_to_str(&fo->type); + char *got = type_to_str(&fo->range.to->type); + err_print(e->where, "Type of for loop does not match the type of the to expression. Expected %s, but got %s.", exp, got); free(exp); free(got); return false; } - if ((ea->type.flags & TYPE_IS_FLEXIBLE) && ea->range.to) - ea->type = ea->range.to->type; - ea->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; + if ((fo->type.flags & TYPE_IS_FLEXIBLE) && fo->range.to) + fo->type = fo->range.to->type; + fo->type.flags &= (TypeFlags)~(TypeFlags)TYPE_IS_FLEXIBLE; } else { - if (!types_expr(tr, ea->of)) + if (!types_expr(tr, fo->of)) return false; - Type *iter_type = &ea->of->type; + Type *iter_type = &fo->of->type; bool uses_ptr = false; if (iter_type->kind == TYPE_PTR) { @@ -1157,7 +1157,7 @@ static bool types_expr(Typer *tr, Expression *e) { iter_type = iter_type->arr.of; break; default: { - char *s = type_to_str(&ea->of->type); + char *s = type_to_str(&fo->of->type); err_print(e->where, "Cannot iterate over non-array non-slice type %s.", s); free(s); return false; @@ -1170,33 +1170,33 @@ static bool types_expr(Typer *tr, Expression *e) { ptr_type.ptr = iter_type; iter_type = &ptr_type; } - if (ea->flags & EACH_ANNOTATED_TYPE) { - if (!type_eq(iter_type, &ea->type)) { + if (fo->flags & FOR_ANNOTATED_TYPE) { + if (!type_eq(iter_type, &fo->type)) { char *exp = type_to_str(iter_type); - char *got = type_to_str(&ea->type); + char *got = type_to_str(&fo->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 = *iter_type; + } else fo->type = *iter_type; } - if ((ea->flags & EACH_IS_RANGE) && ea->range.step) { - Value *stepval = typer_malloc(tr, sizeof *ea->range.stepval); - if (!eval_expr(tr->evalr, ea->range.step, stepval)) { - info_print(ea->range.step->where, "Note that the step of an each loop must be a compile-time constant."); + if ((fo->flags & FOR_IS_RANGE) && fo->range.step) { + Value *stepval = typer_malloc(tr, sizeof *fo->range.stepval); + if (!eval_expr(tr->evalr, fo->range.step, stepval)) { + info_print(fo->range.step->where, "Note that the step of a for loop must be a compile-time constant."); return false; } - val_cast(stepval, &ea->range.step->type, stepval, &ea->type); - ea->range.stepval = stepval; + val_cast(stepval, &fo->range.step->type, stepval, &fo->type); + fo->range.stepval = stepval; } arr_remove_lasta(&tr->in_expr_decls, tr->allocr); - if (!types_block(tr, &ea->body)) return false; - each_exit(e); + if (!types_block(tr, &fo->body)) return false; + for_exit(e); - if (ea->body.ret_expr) { - *t = ea->body.ret_expr->type; + if (fo->body.ret_expr) { + *t = fo->body.ret_expr->type; } else { t->kind = TYPE_VOID; t->flags |= TYPE_IS_RESOLVED; @@ -2189,7 +2189,7 @@ static bool types_block(Typer *tr, Block *b) { if (!(e->kind == EXPR_BLOCK || e->kind == EXPR_IF || e->kind == EXPR_WHILE - || e->kind == EXPR_EACH)) { + || e->kind == EXPR_FOR)) { err_print(e->where, "void expression must be followed by ;"); success = false; goto ret; @@ -178,7 +178,7 @@ typedef enum { typedef struct IdentDecl { union { struct Declaration *decl; - struct Expression *expr; /* for example, this identifier is declared in an each expression */ + struct Expression *expr; /* for example, this identifier is declared in a for expression */ }; struct Block *scope; /* NULL for file scope */ Value val; @@ -277,7 +277,7 @@ typedef enum { KW_ELIF, KW_ELSE, KW_WHILE, - KW_EACH, + KW_FOR, KW_RETURN, KW_FN, KW_AS, @@ -501,7 +501,7 @@ typedef enum { EXPR_UNARY_OP, EXPR_IF, EXPR_WHILE, - EXPR_EACH, + EXPR_FOR, EXPR_FN, EXPR_CAST, EXPR_NEW, @@ -583,16 +583,16 @@ typedef struct WhileExpr { enum { - EACH_IS_RANGE = 0x01, - EACH_ANNOTATED_TYPE = 0x02, + FOR_IS_RANGE = 0x01, + FOR_ANNOTATED_TYPE = 0x02, }; -typedef struct EachExpr { +typedef struct ForExpr { U8 flags; struct { IdentID id; } c; - Type type; /* uninitialized unless typed or flags & EACH_ANNOTATED_TYPE */ + Type type; /* uninitialized unless typed or flags & FOR_ANNOTATED_TYPE */ Identifier index; /* NULL = no index */ Identifier value; /* NULL = no value */ Block body; @@ -608,7 +608,7 @@ typedef struct EachExpr { } range; struct Expression *of; }; -} EachExpr; +} ForExpr; enum { @@ -734,7 +734,7 @@ typedef struct Expression { } pkg; /* only can exist before typing */ IfExpr if_; WhileExpr while_; - EachExpr *each; + ForExpr *for_; FnExpr *fn; CastExpr cast; SliceExpr slice; @@ -879,7 +879,7 @@ typedef struct Typer { Evaluator *evalr; Identifiers *idents; struct Exporter *exptr; - Expression **in_expr_decls; /* an array of expressions whose declarations (e.g. each **x := foo**) we are currently inside */ + Expression **in_expr_decls; /* an array of expressions whose declarations (e.g. for **x := foo**) we are currently inside */ Declaration **in_decls; /* array of declarations we are currently inside */ Block *block; Block **blocks; /* dyn array of all the block's we're in ([0] = NULL for global scope) */ |