summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c120
-rw-r--r--main.c5
-rw-r--r--out.c44
-rw-r--r--test.toc30
4 files changed, 112 insertions, 87 deletions
diff --git a/cgen.c b/cgen.c
index 4b4b3c7..384cff9 100644
--- a/cgen.c
+++ b/cgen.c
@@ -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);
}
diff --git a/main.c b/main.c
index 8fe25d6..7d79be4 100644
--- a/main.c
+++ b/main.c
@@ -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"
diff --git a/out.c b/out.c
index 1c14262..1612526 100644
--- a/out.c
+++ b/out.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) {
- {
-}}
-
-
diff --git a/test.toc b/test.toc
index ffe245d..18ecd42 100644
--- a/test.toc
+++ b/test.toc
@@ -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