summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLeo Tenenbaum <pommicket@gmail.com>2019-11-08 13:02:54 -0500
committerLeo Tenenbaum <pommicket@gmail.com>2019-11-08 13:02:54 -0500
commit6800a6691602aa3b38fc8fea182bf4d1cef092ef (patch)
tree39ff92fe777dd19c8f2e44869e7025a572831189
parent15d0f9a50bcd19e4d1efdd3574bc48bc712d4471 (diff)
fixed, e.g. each x := x
-rwxr-xr-xbuild.sh2
-rw-r--r--cgen.c27
-rw-r--r--eval.c6
-rw-r--r--main.c6
-rw-r--r--test.toc67
-rw-r--r--tokenizer.c2
-rw-r--r--typedefs_cgen.c2
-rw-r--r--types.c21
-rw-r--r--types.h1
9 files changed, 53 insertions, 81 deletions
diff --git a/build.sh b/build.sh
index 865313a..f523a64 100755
--- a/build.sh
+++ b/build.sh
@@ -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
diff --git a/cgen.c b/cgen.c
index fa1aa3a..daeac3f 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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;
diff --git a/eval.c b/eval.c
index e2beb26..90f29c6 100644
--- a/eval.c
+++ b/eval.c
@@ -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) {
diff --git a/main.c b/main.c
index c3b544c..889b9e4 100644
--- a/main.c
+++ b/main.c
@@ -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;
}
diff --git a/test.toc b/test.toc
index 347eb5a..689b4fe 100644
--- a/test.toc
+++ b/test.toc
@@ -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 ");
diff --git a/types.c b/types.c
index 19fa057..0cc7772 100644
--- a/types.c
+++ b/types.c
@@ -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);
}
diff --git a/types.h b/types.h
index cc79b87..5222f85 100644
--- a/types.h
+++ b/types.h
@@ -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;