diff options
-rw-r--r-- | cgen.c | 83 | ||||
-rw-r--r-- | eval.c | 4 | ||||
-rw-r--r-- | main.c | 15 | ||||
-rw-r--r-- | test.toc | 29 | ||||
-rw-r--r-- | types.c | 5 | ||||
-rw-r--r-- | types.h | 2 |
6 files changed, 82 insertions, 56 deletions
@@ -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 { @@ -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; @@ -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 @@ -1,9 +1,28 @@ -b ::= struct { - next : &a; +io ::= nms { + #include "std/io.toc"; }; -a::=struct { - next : &b; + +ll ::= struct { + head : int; + tail : ≪ }; + +slice_to_ll ::= fn(x: []int) l: ll { + if x.len == 1 { + l.head = x[0]; + l.tail = 0 as ≪ + 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); }; @@ -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); @@ -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; }; |