summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c19
-rw-r--r--main.c4
-rw-r--r--test.toc83
-rw-r--r--types.c5
4 files changed, 30 insertions, 81 deletions
diff --git a/cgen.c b/cgen.c
index c6e5c6f..f962e4c 100644
--- a/cgen.c
+++ b/cgen.c
@@ -981,6 +981,18 @@ static void cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents,
}
}
+static void cgen_truthiness(CGenerator *g, Expression *e) {
+ switch (e->type.kind) {
+ case TYPE_SLICE:
+ cgen_expr(g, e);
+ cgen_write(g, ".n");
+ break;
+ default:
+ cgen_expr(g, e);
+ break;
+ }
+}
+
static void cgen_expr_pre(CGenerator *g, Expression *e) {
IdentID id = 0;
char ret_name[CGEN_IDENT_ID_STR_SIZE+20];
@@ -1022,7 +1034,7 @@ static void cgen_expr_pre(CGenerator *g, Expression *e) {
while (1) {
if (curr->cond) {
cgen_write(g, "if (");
- cgen_expr(g, curr->cond);
+ cgen_truthiness(g, curr->cond);
cgen_write(g, ") ");
}
cgen_block(g, &curr->body, ret_name, 0);
@@ -1785,11 +1797,13 @@ static void cgen_block(CGenerator *g, Block *b, const char *ret_name, U16 flags)
Block *prev_block = g->block;
g->block = b;
b->deferred = NULL;
- ++g->indent_lvl;
if (!(flags & CGEN_BLOCK_NOBRACES)) {
cgen_writeln(g, "{");
}
+
+ ++g->indent_lvl;
+
arr_foreach(b->stmts, Statement, s)
cgen_stmt(g, s);
if (b->ret_expr && ret_name) {
@@ -1814,6 +1828,7 @@ static void cgen_block(CGenerator *g, Block *b, const char *ret_name, U16 flags)
cgen_lbl(g, b->c.break_lbl);
cgen_writeln(g, ":;");
}
+ cgen_nl(g);
}
g->block = prev_block;
}
diff --git a/main.c b/main.c
index 9460af3..b002d8c 100644
--- a/main.c
+++ b/main.c
@@ -8,10 +8,10 @@
/*
@TODO:
-fix including something twice - just use the non-namespacey version if it exists or pick one namespace to use everywhere otherwise
+#if should not create a block
&void
null
-#if should not create a block if it's an EXPR_STMT
+fix including something twice - just use the non-namespacey version if it exists or pick one namespace to use everywhere otherwise
&&, ||
start making a standard library... (printf; stringbuilder would be nice to have)
improve type_to_str:
diff --git a/test.toc b/test.toc
index ec062c2..f489e67 100644
--- a/test.toc
+++ b/test.toc
@@ -1,81 +1,10 @@
-#include "std/io.toc", io;
-#include "std/mem.toc", mem;
-
-use mem;
-
-Point ::= struct {
- x: int;
- y: int;
- a ::= 3;
-}
-
-Point3D ::= struct {
- use point: Point;
- z: int;
-
-}
-
-Point4D ::= struct {
- use p3: Point3D;
- w: int;
-}
-
-Foo ::= struct {
- f: f32;
-}
-
-Bar ::= struct {
- use foo: Foo;
- use p4: Point4D;
-}
-
-
-
-make_point ::= fn (x_: int, y_: int) use p: Point {
- x = x_+a;
- y = y_+a;
-}
-
-make_bar ::= fn (x_ := 0, y_ := 0, z_ := 0, w_ := 0, f_ := 0.0) use b: Bar {
- x = x_;
- y = y_;
- z = z_;
- b.p4.w = w_;
- b.f = f_;
-}
+#include "std/io.toc";
main ::= fn() {
-
- use io;
-
- {
- use p: Point;
- use io;
- x = 5;
- puti(x);
+ #if "hello" {
+ x := 5;
+ } else {
+ x := 6;
}
-
-
-
- ps := news(Point, 5);
- for p := &ps {
- *p = make_point(3, 5);
- }
- for use p, i := &ps {
- x += i;
- y += 2*i;
- }
- for use p := ps {
- writei(x);
- writes(" ");
- writei(y);
- puts("");
- }
- dels(ps);
- b := make_bar(5, 8, 13, 12);
- puti(b.x);
- puti(b.y);
- puti(b.z);
- puti(b.w);
-
+ puti(x);
}
diff --git a/types.c b/types.c
index 7f6da1f..112573a 100644
--- a/types.c
+++ b/types.c
@@ -2174,6 +2174,11 @@ static Status types_expr(Typer *tr, Expression *e) {
}
if (!cond || val_truthiness(v, &cond->type)) {
Block *true_block = &curr->body;
+ Statement *last = arr_last_ptr(true_block->stmts);
+ if (last && last->kind == STMT_EXPR && (last->flags & STMT_EXPR_NO_SEMICOLON)) {
+ err_print(last->where, "#ifs can't return values.");
+ return false;
+ }
e->kind = EXPR_BLOCK;
e->block = true_block;
break;