summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cgen.c83
-rw-r--r--eval.c4
-rw-r--r--main.c15
-rw-r--r--test.toc29
-rw-r--r--types.c5
-rw-r--r--types.h2
6 files changed, 82 insertions, 56 deletions
diff --git a/cgen.c b/cgen.c
index 9f4ba16..7628bd2 100644
--- a/cgen.c
+++ b/cgen.c
@@ -1125,7 +1125,7 @@ static bool cgen_expr_pre(CGenerator *g, Expression *e) {
}
cgen_write(g, ");");
} else if (cgen_uses_ptr(&e->type)) {
- e->cgen.id = ++g->ident_counter;
+ e->cgen.id = id = ++g->ident_counter;
if (!cgen_type_pre(g, &e->type, e->where)) return false;
cgen_write(g, " ");
cgen_ident_id(g, id);
@@ -1750,36 +1750,8 @@ static bool cgen_fn(CGenerator *g, FnExpr *f, U64 instance, Value *compile_time_
if (!cgen_block(g, &f->body, NULL, CGEN_BLOCK_NOBRACES))
return false;
if (f->ret_decls) {
- /* OPTIM */
-
- /* long-winded code to generate a return expression using the ret_decls. */
- Expression ret_expr;
- ret_expr.flags = EXPR_FOUND_TYPE;
- ret_expr.type = f->ret_type;
- if (arr_len(f->ret_decls) == 1
- && arr_len(f->ret_decls[0].idents) == 1) {
- ret_expr.kind = EXPR_IDENT;
- ret_expr.ident = f->ret_decls[0].idents[0];
- } else {
- ret_expr.kind = EXPR_TUPLE;
- ret_expr.tuple = NULL;
- size_t i = 0;
- arr_foreach(f->ret_decls, Declaration, d) {
- arr_foreach(d->idents, Identifier, ident) {
- Expression *element = arr_add(&ret_expr.tuple);
- element->flags = EXPR_FOUND_TYPE;
- element->kind = EXPR_IDENT;
- element->type = f->ret_type.tuple[i];
- element->ident = *ident;
- ++i;
- }
- }
- }
-
- if (!cgen_ret(g, &ret_expr))
+ if (!cgen_ret(g, NULL))
return false;
- if (ret_expr.kind == EXPR_TUPLE)
- arr_clear(&ret_expr.tuple);
} else if (f->body.ret_expr) {
if (!cgen_ret(g, f->body.ret_expr)) return false;
}
@@ -2004,16 +1976,59 @@ static bool cgen_decl(CGenerator *g, Declaration *d) {
}
static bool cgen_ret(CGenerator *g, Expression *ret) {
- assert((g->fn->ret_type.kind == TYPE_VOID) == (ret == NULL));
+ FnExpr *f = g->fn;
+ if (f->ret_decls) {
+ assert(!ret);
+ if (f->ret_type.kind == TYPE_TUPLE) {
+ /* TODO TODO */
+ Expression ret_expr = {0};
+ ret_expr.flags = EXPR_FOUND_TYPE;
+ ret_expr.type = f->ret_type;
+ ret_expr.kind = EXPR_TUPLE;
+ ret_expr.tuple = NULL;
+ arr_set_len(&ret_expr.tuple, arr_len(f->ret_type.tuple));
+ int idx = 0;
+ arr_foreach(f->ret_decls, Declaration, d) {
+ arr_foreach(d->idents, Identifier, ident) {
+ Expression *e = &ret_expr.tuple[idx];
+ e->flags = EXPR_FOUND_TYPE;
+ e->type = f->ret_type.tuple[idx];
+ e->kind = EXPR_IDENT;
+ e->ident = *ident;
+ ++idx;
+ }
+ }
+ bool success = cgen_set_tuple(g, NULL, NULL, "*ret", &ret_expr);
+ arr_clear(&ret_expr.tuple);
+ if (!success)
+ return false;
+ } else if (cgen_uses_ptr(&f->ret_type)) {
+ Expression ret_expr = {0};
+ ret_expr.flags = EXPR_FOUND_TYPE;
+ ret_expr.type = f->ret_type;
+ ret_expr.kind = EXPR_IDENT;
+ ret_expr.ident = f->ret_decls[0].idents[0];
+ if (!cgen_set(g, NULL, "*ret_", &ret_expr, NULL)) {
+ return false;
+ }
+ cgen_writeln(g, ";");
+ cgen_writeln(g, "return;");
+ } else {
+ cgen_write(g, "return ");
+ cgen_ident(g, f->ret_decls[0].idents[0]);
+ cgen_writeln(g, ";");
+ }
+ return true;
+ }
if (ret) {
- assert(type_eq(&g->fn->ret_type, &ret->type));
+ assert(type_eq(&f->ret_type, &ret->type));
if (!cgen_expr_pre(g, ret))
return false;
}
if (!ret) {
cgen_write(g, "return");
- } else if (cgen_uses_ptr(&g->fn->ret_type)) {
- if (g->fn->ret_type.kind == TYPE_TUPLE) {
+ } else if (cgen_uses_ptr(&f->ret_type)) {
+ if (f->ret_type.kind == TYPE_TUPLE) {
if (!cgen_set_tuple(g, NULL, NULL, "*ret", ret))
return false;
} else {
diff --git a/eval.c b/eval.c
index 83e2648..865d16e 100644
--- a/eval.c
+++ b/eval.c
@@ -1113,11 +1113,11 @@ static bool eval_ident(Evaluator *ev, Identifier ident, Value *v, Location where
v->fn = d->val.fn;
return true;
}
- if ((d->flags & DECL_FOUND_VAL) && type_is_builtin(&d->type, BUILTIN_TYPE) && d->val.type->kind == TYPE_STRUCT) {
+ if ((d->flags & DECL_HAS_EXPR) && d->expr.kind == EXPR_TYPE && d->expr.typeval.kind == TYPE_STRUCT) {
v->type = allocr_malloc(ev->allocr, sizeof *v->type);
v->type->flags = TYPE_IS_RESOLVED;
v->type->kind = TYPE_STRUCT;
- v->type->struc = d->val.type->struc;
+ v->type->struc = d->expr.typeval.struc;
return true;
} else {
if (!types_decl(ev->typer, d)) return false;
diff --git a/main.c b/main.c
index b5e4c6d..80e1db1 100644
--- a/main.c
+++ b/main.c
@@ -18,7 +18,6 @@
/*
TODO:
-fix circular dependencies in types
struct parameters
fix struct copying
replace is_reference in type_resolve_ with system for checking if type is
@@ -67,17 +66,13 @@ static void signal_handler(int num) {
static void *addrs[30];
int naddrs = (int)(sizeof addrs / sizeof *addrs);
naddrs = backtrace(addrs, naddrs);
- char **syms = backtrace_symbols(addrs, naddrs);
-
-
+ /* char **syms = backtrace_symbols(addrs, naddrs); */
+ char command[2048] = "addr2line -p -f -a -e toc ";
for (int i = 4; i < naddrs; ++i) {
- fprintf(stderr,"\t%s - ",syms[i]);
- char buf[256];
- snprintf(buf, sizeof buf, "addr2line -e toc %p", addrs[i]);
- system(buf);
+ snprintf(command + strlen(command), sizeof command - strlen(command), "%p ", addrs[i]);
}
-
- free(syms);
+ system(command);
+ /* free(syms); */
}
#endif
diff --git a/test.toc b/test.toc
index 9eddb80..75bdad5 100644
--- a/test.toc
+++ b/test.toc
@@ -1,9 +1,28 @@
-b ::= struct {
- next : &a;
+io ::= nms {
+ #include "std/io.toc";
};
-a::=struct {
- next : &b;
+
+ll ::= struct {
+ head : int;
+ tail : &ll;
};
+
+slice_to_ll ::= fn(x: []int) l: ll {
+ if x.len == 1 {
+ l.head = x[0];
+ l.tail = 0 as &ll;
+ return;
+ }
+ l.head = x[0];
+ l.tail = new(ll);
+ *l.tail = slice_to_ll(x[1:]);
+};
+
main ::= fn() {
- l : ll;
+ a : []int = new(int,3);
+ a[0] = 1;
+ a[1] = 2;
+ a[2] = 3;
+ l : ll = slice_to_ll(a);
+ io.puti(l.tail.tail.head);
};
diff --git a/types.c b/types.c
index abe6795..bf03f88 100644
--- a/types.c
+++ b/types.c
@@ -204,10 +204,7 @@ static bool type_is_compileonly(Type *t) {
return true;
return false;
case TYPE_STRUCT:
- arr_foreach(t->struc->fields, Field, f)
- if (type_is_compileonly(&f->type))
- return true;
- return false;
+ return false; /* structs can only have non-compileonly members */
case TYPE_EXPR: break;
}
assert(0);
diff --git a/types.h b/types.h
index 9034f38..9f85f0b 100644
--- a/types.h
+++ b/types.h
@@ -748,7 +748,7 @@ typedef struct Expression {
CastExpr cast;
SliceExpr slice;
Block block;
- struct Expression *tuple;
+ struct Expression *tuple; /* dynamic array, even after typing */
Type typeval;
Value val;
};