diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-08 13:02:54 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-08 13:02:54 -0500 |
commit | 6800a6691602aa3b38fc8fea182bf4d1cef092ef (patch) | |
tree | 39ff92fe777dd19c8f2e44869e7025a572831189 | |
parent | 15d0f9a50bcd19e4d1efdd3574bc48bc712d4471 (diff) |
fixed, e.g. each x := x
-rwxr-xr-x | build.sh | 2 | ||||
-rw-r--r-- | cgen.c | 27 | ||||
-rw-r--r-- | eval.c | 6 | ||||
-rw-r--r-- | main.c | 6 | ||||
-rw-r--r-- | test.toc | 67 | ||||
-rw-r--r-- | tokenizer.c | 2 | ||||
-rw-r--r-- | typedefs_cgen.c | 2 | ||||
-rw-r--r-- | types.c | 21 | ||||
-rw-r--r-- | types.h | 1 |
9 files changed, 53 insertions, 81 deletions
@@ -22,7 +22,7 @@ else WARNINGS='-Wall -Wextra -Wpedantic -Wshadow -Wconversion -Wno-pointer-to-int-cast -Wno-unused-parameter' fi -DEBUG_FLAGS="-O0 -g3 $WARNINGS -std=c11 -DTOC_DEBUG" +DEBUG_FLAGS="-Og -g3 $WARNINGS -std=c11 -DTOC_DEBUG" RELEASE_FLAGS="-O3 -s -DNDEBUG $WARNINGS -std=c11" if [ "$1" = "release" ]; then @@ -685,6 +685,17 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { if (!each_enter(e, 0)) return false; cgen_write(g, "{"); if (is_range) { + if (ea->range.to) { + /* pre generate to */ + if (!cgen_type_pre(g, &ea->type, e->where)) return false; + cgen_write(g, " to_"); + if (!cgen_type_post(g, &ea->type, e->where)) return false; + cgen_write(g, " = "); + if (!cgen_expr(g, ea->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; @@ -707,16 +718,6 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { if (!cgen_set(g, NULL, "val_", ea->range.from, NULL)) return false; } - if (ea->range.to) { - /* pre generate to */ - if (!cgen_type_pre(g, &ea->type, e->where)) return false; - cgen_write(g, " to_"); - if (!cgen_type_post(g, &ea->type, e->where)) return false; - cgen_write(g, " = "); - if (!cgen_expr(g, ea->range.to)) - return false; - cgen_write(g, "; "); - } } else { /* pre-generate of */ if (!cgen_type_pre(g, &ea->of->type, e->where)) @@ -740,8 +741,8 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { cgen_write(g, " = 0"); } cgen_write(g, "; "); - bool uses_ptr; - Type *of_type; + bool uses_ptr = false; + Type *of_type = NULL; if (!(is_range && !ea->range.to)) { /* if it's finite */ if (is_range) { if (ea->value) @@ -1427,7 +1428,7 @@ static bool cgen_val_ptr(CGenerator *g, void *v, Type *t, Location where) { case BUILTIN_U32: cgen_write(g, "%"PRIu32, *(U32 *)v); break; case BUILTIN_I64: cgen_write(g, "%"PRId64, *(I64 *)v); break; case BUILTIN_U64: cgen_write(g, "%"PRIu64, *(U64 *)v); break; - case BUILTIN_F32: cgen_write(g, F32_FMT, *(F32 *)v); break; + case BUILTIN_F32: cgen_write(g, F32_FMT"f", *(F32 *)v); break; case BUILTIN_F64: cgen_write(g, F64_FMT, *(F64 *)v); break; case BUILTIN_CHAR: cgen_write(g, "\\x%02x", *(char *)v); break; case BUILTIN_BOOL: cgen_write(g, "%s", *(bool *)v ? "true" : "false"); break; @@ -1176,7 +1176,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { } break; case EXPR_EACH: { EachExpr *ea = &e->each; - if (!each_enter(e, 0)) return false; if (ea->flags & EACH_IS_RANGE) { Value from, to; Value stepval; @@ -1192,6 +1191,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Value x = from; Value *index_val; Value *value_val; + if (!each_enter(e, 0)) return false; if (ea->index) { IdentDecl *idecl = ident_decl(ea->index); idecl->flags |= IDECL_HAS_VAL; @@ -1237,6 +1237,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, ea->of, &of)) return false; Value *index_val, *value_val; Value i, val; + if (!each_enter(e, 0)) return false; if (ea->index) { IdentDecl *idecl = ident_decl(ea->index); idecl->flags |= IDECL_HAS_VAL; @@ -1318,7 +1319,7 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { case EXPR_IDENT: { IdentDecl *idecl = ident_decl(e->ident); bool is_decl = idecl->kind == IDECL_DECL; - Declaration *d; + Declaration *d = NULL; if (is_decl) { d = idecl->decl; if (!types_decl(ev->typer, d)) return false; @@ -1331,7 +1332,6 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { if (!eval_expr(ev, &d->expr, &d->val)) return false; d->flags |= DECL_FLAG_FOUND_VAL; } - int index = ident_index_in_decl(e->ident, d); assert(index != -1); if (e->type.kind == TYPE_TYPE) { @@ -1,6 +1,5 @@ /* TODO: -prevent each x := x +=, -=, *=, /= compile-time arguments don't allow while {3; 5} (once break is added) @@ -61,6 +60,7 @@ int main(int argc, char **argv) { err_ctx.enabled = true; tokr_create(&t, &file_idents, &err_ctx); if (!tokenize_string(&t, contents)) { + err_fprint(TEXT_IMPORTANT("Errors occured while preprocessing.\n")); return EXIT_FAILURE; } @@ -75,6 +75,7 @@ int main(int argc, char **argv) { parser_from_tokenizer(&p, &t); ParsedFile f; if (!parse_file(&p, &f)) { + err_fprint(TEXT_IMPORTANT("Errors occured while parsing.\n")); return EXIT_FAILURE; } @@ -92,7 +93,7 @@ int main(int argc, char **argv) { return false; if (!types_file(&tr, &f)) { - err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n")); + err_fprint(TEXT_IMPORTANT("Errors occured while determining types.\n")); return EXIT_FAILURE; } parse_printing_after_types = true; @@ -106,6 +107,7 @@ int main(int argc, char **argv) { CGenerator g; cgen_create(&g, out, &file_idents, &ev); if (!cgen_file(&g, &f)) { + fclose(out); err_fprint(TEXT_IMPORTANT("Errors occured while generating C code.\n")); return EXIT_FAILURE; } @@ -9,69 +9,20 @@ putf @= fn(x: float) { "); }; -// f @= fn() { -// each i := 1..4 { -// puti(i); -// } -// each i := 4,-1..1 { -// puti(i); -// } -// each i := 1.0..4.0 { -// putf(i); -// } -// each i := 7.0,-1..4.0 { -// putf(i); -// } -// // each i := 0.0,-3.0.. { putf(i); } -// foo := new(int, 3); -// each _, i := foo { -// foo[i] = i; -// }; -// each x := foo { -// puti(x); -// } -// each _ := foo { -// #C("puts(\"Hello!\")"); -// } -// bar : [3]int; -// each _, i := bar { -// bar[i] = i*i*i; -// }; -// each x := bar { -// puti(x); -// } +sum @= fn() int { -// }; +x := 3; +total := 0; +each x := 1..10{ + total = total + x; + total +} -g @= fn() int { - foo : = new(int, 10); - total := 0; - // 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; - // } - // total }; main @= fn() { - puti(g()); - X @= g(); + puti(sum()); + X @= sum(); puti(X); - each i, j := 1..10 { - puti(i + j); - } }; diff --git a/tokenizer.c b/tokenizer.c index 828b3d4..ab668fc 100644 --- a/tokenizer.c +++ b/tokenizer.c @@ -276,7 +276,7 @@ static bool tokenize_string(Tokenizer *t, char *str) { if (isdigit(*t->s)) { /* it's a numeric literal */ int base = 10; - Floating decimal_pow10; + Floating decimal_pow10 = 0; NumLiteral n; n.kind = NUM_LITERAL_INT; n.intval = 0; diff --git a/typedefs_cgen.c b/typedefs_cgen.c index 937be4a..b193e9a 100644 --- a/typedefs_cgen.c +++ b/typedefs_cgen.c @@ -115,7 +115,7 @@ static bool typedefs_decl(CGenerator *g, Declaration *d) { if (d->c.ids == NULL) d->c.ids = calloc(arr_len(d->idents), sizeof *d->c.ids); /* generate typedef */ - IdentID id; + IdentID id = 0; if (g->block != NULL) id = d->c.ids[idx] = g->ident_counter++; if (val->type->kind == TYPE_STRUCT) continue; /* we don't need to typedef this; we can just use its tag */ cgen_write(g, "typedef "); @@ -284,7 +284,7 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { /* if we've complained about it before when we were figuring out the type, don't complain again */ if (!(d->flags & DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE)) { char *s = ident_to_str(i); - err_print(where, "Use of identifier %s within its own declaration.", s); + err_print(where, "Use of identifier %s in its own declaration.", s); free(s); info_print(d->where, "Declaration was here."); d->flags |= DECL_FLAG_ERRORED_ABOUT_SELF_REFERENCE; @@ -332,6 +332,17 @@ static bool type_of_ident(Typer *tr, Location where, Identifier i, Type *t) { } break; case IDECL_EXPR: { Expression *e = decl->expr; + /* are we inside this expression? */ + typedef Expression *ExpressionPtr; + arr_foreach(tr->in_expr_decls, ExpressionPtr, in_e) { + if (*in_e == e) { + char *s = ident_to_str(i); + err_print(where, "Use of identifier %s in its own declaration.", s); + free(s); + return false; + } + } + switch (e->kind) { case EXPR_EACH: if (i == e->each.index) { @@ -668,6 +679,8 @@ static bool types_expr(Typer *tr, Expression *e) { break; case EXPR_EACH: { EachExpr *ea = &e->each; + *(Expression **)arr_add(&tr->in_expr_decls) = e; + if (!each_enter(e, SCOPE_FLAG_CHECK_REDECL)) return false; if (ea->flags & EACH_IS_RANGE) { /* TODO: allow user-defined numerical types */ if (!types_expr(tr, ea->range.from)) return false; @@ -782,9 +795,12 @@ static bool types_expr(Typer *tr, Expression *e) { val_cast(stepval, &ea->range.step->type, stepval, &ea->type); ea->range.stepval = stepval; } - if (!each_enter(e, SCOPE_FLAG_CHECK_REDECL)) return false; + + arr_remove_last(&tr->in_expr_decls); + if (!types_block(tr, &ea->body)) return false; each_exit(e); + if (ea->body.ret_expr) *t = ea->body.ret_expr->type; else @@ -1573,6 +1589,7 @@ static void typer_create(Typer *tr, Evaluator *ev) { tr->can_ret = false; tr->evalr = ev; tr->in_decls = NULL; + tr->in_expr_decls = NULL; allocr_create(&tr->allocr); } @@ -610,6 +610,7 @@ typedef struct { typedef struct Typer { Allocator allocr; Evaluator *evalr; + Expression **in_expr_decls; /* an array of expressions whose declarations (e.g. each **x := foo**) we are currently inside */ Declaration **in_decls; /* array of declarations we are currently inside */ Block *block; bool can_ret; |