diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-15 14:39:55 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-10-15 14:39:55 -0400 |
commit | bfc2bb671f900eb37d57707391bf22e5ed8c07f7 (patch) | |
tree | 5a31d24f41900c2a28280f8437aa9e0c47ea6632 | |
parent | 5521461a61b55124cee90e1bfcc946b1a029570f (diff) |
started cgen tuples
-rw-r--r-- | cgen.c | 120 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | out.c | 44 | ||||
-rw-r--r-- | test.toc | 30 |
4 files changed, 112 insertions, 87 deletions
@@ -106,6 +106,10 @@ static void cgen_ident(CGenerator *g, Identifier i) { } } +static char *cgen_ident_to_str(Identifier i) { + return ident_to_str(i); +} + static void cgen_ident_id(CGenerator *g, IdentID id) { cgen_write(g, "a%lu_", (unsigned long)id); } @@ -243,13 +247,25 @@ static bool cgen_fn_header(CGenerator *g, FnExpr *f, Location where) { } } if (out_param) { - if (any_params) - cgen_write(g, ", "); - if (!cgen_type_pre(g, &f->ret_type, where)) - return false; - cgen_write(g, " (*ret__)"); - if (!cgen_type_post(g, &f->ret_type, where)) - return false; + if (f->ret_type.kind == TYPE_TUPLE) { + /* multiple return variables */ + for (size_t i = 0; i < arr_len(f->ret_type.tuple); i++) { + Type *x = &f->ret_type.tuple[i]; + 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); + if (!cgen_type_post(g, x, where)) return false; + } + } else { + if (any_params) + cgen_write(g, ", "); + if (!cgen_type_pre(g, &f->ret_type, where)) + return false; + cgen_write(g, " (*ret__)"); + if (!cgen_type_post(g, &f->ret_type, where)) + return false; + } } if (!out_param && arr_len(f->params) == 0) cgen_write(g, "void"); @@ -344,6 +360,57 @@ static bool cgen_set(CGenerator *g, Expression *set_expr, const char *set_str, E return true; } + +/* Either exprs or idents should be NULL */ +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; + Expression *e = NULL; + if (idents) + s = cgen_ident_to_str(idents[i]); + else + e = &exprs[i]; + if (!cgen_set(g, e, s, to, NULL)) return false; + free(s); + } + break; + case EXPR_CALL: { + /* e.g. a, b = fn_which_returns_tuple(); */ + if (!cgen_expr(g, to->call.fn)) return false; + cgen_write(g, "("); + bool any_args = arr_len(to->call.arg_exprs) != 0; + arr_foreach(to->call.arg_exprs, Expression, arg) { + if (arg != to->call.arg_exprs) + cgen_write(g, ", "); + if (!cgen_expr(g, arg)) + return false; + } + /* out params */ + size_t len = exprs ? arr_len(exprs) : arr_len(idents); + + for (size_t i = 0; i < len; i++) { + if (any_args || i > 0) + cgen_write(g, ", "); + cgen_write(g, "&"); + if (exprs) { + if (!cgen_expr(g, &exprs[i])) + return false; + } else { + cgen_ident(g, idents[i]); + } + } + cgen_writeln(g, ");"); + } break; + default: + assert(0); + return false; + } + return true; +} + static bool cgen_expr(CGenerator *g, Expression *e) { switch (e->kind) { case EXPR_LITERAL_FLOAT: @@ -586,26 +653,31 @@ static bool cgen_decl(CGenerator *g, Declaration *d) { cgen_write(g, "; "); } - /* TODO: tuples */ + /* TODO: global tuples */ if (g->block != NULL && (d->flags & DECL_FLAG_HAS_EXPR)) { - cgen_write(g, "{"); - cgen_nl(g); - if (!cgen_type_pre(g, &d->expr.type, d->expr.where)) return false; - cgen_write(g, " expr__"); - if (!cgen_type_post(g, &d->expr.type, d->expr.where)) return false; - cgen_write(g, "; "); - if (!cgen_set(g, NULL, "expr__", &d->expr, NULL)) - return false; - arr_foreach(d->idents, Identifier, i) { - Expression e; - e.flags = 0; - e.kind = EXPR_IDENT; - e.type = d->type; - e.ident = *i; - if (!cgen_set(g, &e, NULL, NULL, "expr__")) + if (d->expr.type.kind == TYPE_TUPLE) { + if (!cgen_set_tuple(g, NULL, d->idents, &d->expr)) return false; + } else { + cgen_write(g, "{"); + + cgen_nl(g); + if (!cgen_type_pre(g, &d->expr.type, d->expr.where)) return false; + cgen_write(g, " expr__"); + if (!cgen_type_post(g, &d->expr.type, d->expr.where)) return false; + cgen_write(g, "; "); + if (!cgen_set(g, NULL, "expr__", &d->expr, NULL)) return false; + arr_foreach(d->idents, Identifier, i) { + Expression e; + e.flags = 0; + e.kind = EXPR_IDENT; + e.type = d->type; + e.ident = *i; + if (!cgen_set(g, &e, NULL, NULL, "expr__")) + return false; + } + cgen_write(g, "}"); } - cgen_write(g, "}"); } cgen_nl(g); } @@ -1,9 +1,12 @@ /* TODO: +cgen tuples +unicode variable names re-do cgen make sure initializers for global variables are compile-time constants -allow, e.g.: x := "foo"; x[0] = 'g'; any odd number of "s for a string +modifiable strings: +s := {"sakjdfhkjh ksjdahfkjsd ahs ahdf hsdaf khsadkjfh"}; */ #include "toc.c" @@ -16,59 +16,25 @@ typedef unsigned char bool; /* declarations */ -i64 puti(i64 i); -void dbl(i64((* x)[3])); -i64 foo(void); +void puti(i64 x); +void mktup(i64 a, i64 b, i64(*ret0__), i64(*ret1__)); void main__(void); - void a0_(void); /* code */ int main() { main__(); return 0; } -i64 puti(i64 i) { +void puti(i64 x) { { - printf("%ld\n", i); + printf("%lu", x); }} -void dbl(i64((* x)[3])) { +void mktup(i64 a, i64 b, i64(*ret0__), i64(*ret1__)) { { - ((*x)[0]) = (((*x)[0])*2);; - ((*x)[1]) = (((*x)[1])*2);; - ((*x)[2]) = (((*x)[2])*2);; }} -i64 foo(void) { -i64 a = 0; - { - a = 3;; - if (true) { - a = 4;; - } else if (false) { - a = (17+(1/0));; - }; -}return a; -} - - void main__(void) { { - i64( a[3]) = {0}; - (a[0]) = 1;; - (a[0]) = 5;(a[1]) = (8+(a[0]));; - (dbl((&a))); - void (* asdfnahsdf)(void); { - void (* expr__)(void); expr__ = a0_;asdfnahsdf = expr__;} - (puti((a[0]))); - (puti((foo()))); -}} - - -void a0_(void) { - { -}} - - @@ -1,30 +1,14 @@ - -puti @= fn(i: int) int { - #C("printf(\"%ld\\n\", i)"); - i +puti @= fn(x: int) { + #C("printf(\"%lu\", x)"); }; -dbl @= fn(x: &[3]int) { - (*x)[0] = (*x)[0] * 2; - (*x)[1] = (*x)[1] * 2; - (*x)[2] = (*x)[2] * 2; +mktup @= fn(a: int, b: int) (int, int) { + a, a+b }; -foo @= fn() a: int { - a = 3; - if true { - a = 4; - } elif false { - a = 17+1/0; - } -}; + main @= fn() { - a : [3]int; - a[0] = 1; - a[0], a[1] = 5, 8+a[0]; - dbl(&a); - asdfnahsdf:=fn() {}; - puti(a[0]); - puti(foo()); + a, b := mktup(10, 20); + // x := mktup; };
\ No newline at end of file |