diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-28 15:52:21 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2020-04-28 15:52:21 -0400 |
commit | 58a57d7d4602833e8bfd5af61b3707587a7a5cb8 (patch) | |
tree | a687158923233ed56010b8f1dd6f6da0c08f54bd | |
parent | 8491c14cdd1c493ccc70189e6c7bc83c0257f6dc (diff) |
#ifs cant return values
-rw-r--r-- | cgen.c | 19 | ||||
-rw-r--r-- | main.c | 4 | ||||
-rw-r--r-- | test.toc | 83 | ||||
-rw-r--r-- | types.c | 5 |
4 files changed, 30 insertions, 81 deletions
@@ -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; } @@ -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: @@ -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); } @@ -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; |