From 6092b753c5ba6d5b458c38b283b0f3bc50e5393b Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Thu, 17 Oct 2019 12:33:19 -0400 Subject: tuples are mostly working --- cgen.c | 67 +++++++++++++++++++++++++++++++++++++++++++--------------------- out.c | 19 ++++++++++++++---- test.toc | 8 ++++++-- 3 files changed, 66 insertions(+), 28 deletions(-) diff --git a/cgen.c b/cgen.c index 04c7317..82fac70 100644 --- a/cgen.c +++ b/cgen.c @@ -5,6 +5,7 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, static bool cgen_type_pre(CGenerator *g, Type *t, Location where); static bool cgen_type_post(CGenerator *g, Type *t, Location where); static bool cgen_decl(CGenerator *g, Declaration *d); +static bool cgen_ret(CGenerator *g, Expression *ret); static void cgen_create(CGenerator *g, FILE *out, Identifiers *ids, Evaluator *ev) { g->outc = out; @@ -255,7 +256,7 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { if (any_params || i > 0) cgen_write(g, ", "); if (!cgen_type_pre(g, x, where)) return false; - cgen_write(g, "(*ret%lu__)", (unsigned long)i); + cgen_write(g, "(*ret%lu_)", (unsigned long)i); if (!cgen_type_post(g, x, where)) return false; } } else { @@ -263,7 +264,7 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { cgen_write(g, ", "); if (!cgen_type_pre(g, &f->ret_type, where)) return false; - cgen_write(g, " (*ret__)"); + cgen_write(g, " (*ret_)"); if (!cgen_type_post(g, &f->ret_type, where)) return false; } @@ -353,20 +354,24 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E } -/* Either exprs or idents should be NULL */ +/* exprs and/or idents should be NULL. if both are NULL, *retN_ will be used. */ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, Expression *to) { switch (to->kind) { case EXPR_TUPLE: /* e.g. a, b = 3, 5; */ for (size_t i = 0; i < arr_len(to->tuple); i++) { - char *s = NULL; + char *s = NULL, buf[32]; Expression *e = NULL; if (idents) s = cgen_ident_to_str(idents[i]); - else + else if (exprs) e = &exprs[i]; - if (!cgen_set(g, e, s, to, NULL)) return false; - free(s); + else { + snprintf(buf, sizeof buf, "(*ret%lu_)", i); + s = buf; + } + if (!cgen_set(g, e, s, &to->tuple[i], NULL)) return false; + if (s != buf) free(s); } break; case EXPR_CALL: { @@ -386,12 +391,15 @@ static bool cgen_set_tuple(CGenerator *g, Expression *exprs, Identifier *idents, for (size_t i = 0; i < len; i++) { if (any_args || i > 0) cgen_write(g, ", "); - cgen_write(g, "&"); if (exprs) { + cgen_write(g, "&"); if (!cgen_expr(g, &exprs[i])) return false; - } else { + } else if (idents) { + cgen_write(g, "&"); cgen_ident(g, idents[i]); + } else { + cgen_write(g, "ret%lu_", i); } } cgen_writeln(g, ");"); @@ -613,7 +621,10 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, Location where) { cgen_ident(g, f->ret_decls[0].idents[0]); cgen_writeln(g, ";"); } + } else if (f->body.ret_expr) { + if (!cgen_ret(g, f->body.ret_expr)) return false; } + cgen_write(g, "}"); cgen_nl(g); g->fn = prev_fn; @@ -626,7 +637,7 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { if (cgen_fn_is_direct(g, d)) { cgen_fn(g, &d->expr.fn, d->where); } else if (d->flags & DECL_FLAG_CONST) { - /* TODO */ + /* TODO? */ } else { for (size_t idx = 0; idx < arr_len(d->idents); idx++) { Identifier *i = &d->idents[idx]; @@ -678,6 +689,28 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { return true; } +static bool cgen_ret(CGenerator *g, Expression *ret) { + assert((g->fn->ret_type.kind == TYPE_VOID) == (ret == NULL)); + if (!ret) { + cgen_write(g, "return"); + } else if (cgen_uses_ptr(&g->fn->ret_type)) { + if (g->fn->ret_type.kind == TYPE_TUPLE) { + if (!cgen_set_tuple(g, NULL, NULL, ret)) + return false; + } else { + if (!cgen_set(g, NULL, "*ret_", ret, NULL)) return false; + } + cgen_write(g, "return"); + } else { + cgen_write(g, "return "); + + if (!cgen_expr(g, ret)) return false; + } + cgen_write(g, ";"); + cgen_nl(g); + return true; + +} static bool cgen_stmt(CGenerator *g, Statement *s) { switch (s->kind) { @@ -690,18 +723,8 @@ static bool cgen_stmt(CGenerator *g, Statement *s) { cgen_nl(g); break; case STMT_RET: - if (g->fn->ret_type.kind == TYPE_VOID) { - cgen_write(g, "return"); - } else if (cgen_uses_ptr(&g->fn->ret_type)) { - if (!cgen_set(g, NULL, "*ret__", &s->ret.expr, NULL)) return false; - cgen_write(g, "return"); - } else { - cgen_write(g, "return "); - - if (!cgen_expr(g, &s->ret.expr)) return false; - } - cgen_write(g, ";"); - cgen_nl(g); + if (!cgen_ret(g, s->ret.flags & RET_FLAG_EXPR ? &s->ret.expr : NULL)) + return false; break; } return true; diff --git a/out.c b/out.c index 5a91b99..4b7dfc7 100644 --- a/out.c +++ b/out.c @@ -17,7 +17,8 @@ typedef unsigned char bool; /* declarations */ void puti(i64 x); -void mktup(i64 a, i64 b, i64(*ret0__), i64(*ret1__)); +void mktup(i64 a, i64 b, i64(*ret0_), i64(*ret1_)); +i64 asdf(void); void main__(void); /* code */ int main() { @@ -27,19 +28,29 @@ int main() { void puti(i64 x) { { - printf("%lu", x); + printf("%lu\n", x); }} -void mktup(i64 a, i64 b, i64(*ret0__), i64(*ret1__)) { +void mktup(i64 a, i64 b, i64(*ret0_), i64(*ret1_)) { { -}} +}(*ret0_) = a;(*ret1_) = (a+b);return; +} + + +i64 asdf(void) { + { +}return 7; +} void main__(void) { { i64 a; i64 b; mktup(10, 20, &a, &b); + (puti((asdf()))); + (puti(a)); + (puti(b)); }} diff --git a/test.toc b/test.toc index 18ecd42..0b402b4 100644 --- a/test.toc +++ b/test.toc @@ -1,14 +1,18 @@ puti @= fn(x: int) { - #C("printf(\"%lu\", x)"); + #C("printf(\"%lu\\n\", x)"); }; mktup @= fn(a: int, b: int) (int, int) { a, a+b }; - +asdf @= fn() int { + 7 +}; main @= fn() { a, b := mktup(10, 20); // x := mktup; + puti(asdf()); + puti(a); puti(b); }; \ No newline at end of file -- cgit v1.2.3