diff options
-rw-r--r-- | cgen.c | 36 | ||||
-rw-r--r-- | main.c | 1 | ||||
-rw-r--r-- | test.toc | 14 |
3 files changed, 33 insertions, 18 deletions
@@ -760,7 +760,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) { static bool cgen_expr(CGenerator *g, Expression *e) { switch (e->kind) { case EXPR_LITERAL_FLOAT: - cgen_write(g, "%f", e->floatl); /* TODO(eventually): better precision? */ + cgen_write(g, "%.16Lf", (long double)e->floatl); /* TODO(eventually): better precision? */ break; case EXPR_LITERAL_INT: cgen_write(g, UINTEGER_FMT, e->intl); @@ -948,19 +948,27 @@ static bool cgen_expr(CGenerator *g, Expression *e) { case DIRECT_COUNT: assert(0); break; } break; - case EXPR_CAST: - cgen_write(g, "(("); - cgen_type_pre(g, &e->cast.type, e->where); - cgen_type_post(g, &e->cast.type, e->where); - cgen_write(g, ")("); - if (!cgen_expr(g, e->cast.expr)) - return false; - cgen_write(g, ")"); - if (e->cast.expr->type.kind == TYPE_SLICE - && e->cast.type.kind != TYPE_SLICE) /* casting from a slice to a non-slice */ - cgen_write(g, ".data"); - cgen_write(g, ")"); - break; + case EXPR_CAST: { + Type *from = &e->cast.expr->type; + Type *to = &e->cast.type; + if (from->kind == TYPE_USER || to->kind == TYPE_USER) { + /* don't need to cast; they're the same type in C */ + if (!cgen_expr(g, e->cast.expr)) + return false; + } else { + cgen_write(g, "(("); + cgen_type_pre(g, to, e->where); + cgen_type_post(g, to, e->where); + cgen_write(g, ")("); + if (!cgen_expr(g, e->cast.expr)) + return false; + cgen_write(g, ")"); + if (from->kind == TYPE_SLICE /* casting from a slice to a non-slice */ + && to->kind != TYPE_SLICE) + cgen_write(g, ".data"); + cgen_write(g, ")"); + } + } break; case EXPR_TUPLE: /* the only time this should happen is if you're stating a tuple, e.g. 3, 5;, but we've errored about that before @@ -1,6 +1,5 @@ /* TODO: -don't cast in C for user types fix [4]User make sure user defined types work structs @@ -7,13 +7,21 @@ Foo @= [3]int; f @= fn() Foo { a : Foo; + (a as [3]int)[0] = 8; + (a as [3]int)[1] = 9; + (a as [3]int)[2] = 10; a }; main @= fn() { foo : Foo; foo = f(); - // Bar @= int; - // x: Bar = 18 as Bar; - // puti(x as int); + puti((foo as [3]int)[0]); + puti((foo as [3]int)[1]); + puti((foo as [3]int)[2]); + { + Foo, Bar @= int, float; + // Bar @= [3]Foo; + y: Bar = 0.342 as Bar; + } }; |