From 54f1d5bc80117063a1b67f834b65dbb488ddf1c8 Mon Sep 17 00:00:00 2001 From: Leo Tenenbaum Date: Sat, 16 Nov 2019 11:42:59 -0500 Subject: bug fixes, return declaration initializers --- eval.c | 3 +++ main.c | 5 +---- parse.c | 18 +++++------------- test.toc | 25 +++++++++++-------------- types.c | 27 +++++++++++++++++++++++++++ 5 files changed, 47 insertions(+), 31 deletions(-) diff --git a/eval.c b/eval.c index 2c750a3..023f858 100644 --- a/eval.c +++ b/eval.c @@ -1508,6 +1508,9 @@ static bool eval_expr(Evaluator *ev, Expression *e, Value *v) { Value *element = arr_add(&tuple); Type *type = decl_type_at_index(d, i); val_copy(NULL, element, &this_one, type); + void *to_free = val_ptr_to_free(element, type); + if (to_free) + *(void **)arr_add(&ev->to_free) = to_free; i++; } } diff --git a/main.c b/main.c index f510b34..e2ec9e4 100644 --- a/main.c +++ b/main.c @@ -1,9 +1,6 @@ /* TODO: -ah need to be consistent about whether eval_expr returns a value which should be copied or not!!! -check for leaks -make sure return declarations with initializers work (also, eval initializers) -deal with x, y @= fn(x: int, y @ int){} +:@ don't allow pointers to functions with compile-time arguments type parameters (e.g. fn(foo @ type) {x: foo;}) diff --git a/parse.c b/parse.c index 9112a0a..9db0ffb 100644 --- a/parse.c +++ b/parse.c @@ -814,19 +814,8 @@ static bool parse_fn_expr(Parser *p, FnExpr *f) { } } t->token--; /* move back to { */ - if (arr_len(f->ret_decls) > 1 || arr_len(f->ret_decls[0].idents) > 1) { - f->ret_type.kind = TYPE_TUPLE; - f->ret_type.flags = 0; - f->ret_type.tuple = NULL; - arr_foreach(f->ret_decls, Declaration, decl) { - for (size_t i = 0, len = arr_len(decl->idents); i < len; i++) { - Type *tuple_type = parser_arr_add(p, &f->ret_type.tuple); - *tuple_type = decl->type; - } - } - } else { - f->ret_type = f->ret_decls[0].type; - } + /* just set return type to void. the actual return type will be set by types.c:type_of_fn */ + f->ret_type.kind = TYPE_VOID; } else { if (!parse_type(p, &f->ret_type)) { ret = false; @@ -1765,8 +1754,11 @@ static bool parse_decl(Parser *p, Declaration *d, DeclEndKind ends_with, uint16_ uint16_t expr_flags = 0; if (ends_with == DECL_END_RPAREN_COMMA) expr_flags |= EXPR_CAN_END_WITH_COMMA; + if (ends_with == DECL_END_LBRACE_COMMA) + expr_flags |= EXPR_CAN_END_WITH_LBRACE; Token *end = expr_find_end(p, expr_flags, NULL); if (!end || !ends_decl(end, ends_with)) { + t->token = end; tokr_err(t, "Expected %s at end of declaration.", end_str); goto ret_false; } diff --git a/test.toc b/test.toc index b2499df..98e1063 100644 --- a/test.toc +++ b/test.toc @@ -2,22 +2,19 @@ puti @= fn(x: int) { #C("printf(\"%ld\\n\", (long)x); "); }; - - -Foo @= struct { - x, y: int; - z: float; +putf @= fn(x: float) { + #C("printf(\"%f\\n\", (double)x); +"); }; - -mkfoo @= fn() f: Foo { - f.x = 12; - f.y = -983; - f.z = 21.34-1.2; +x,z @= fn(x: int, y @ int) int { + x+y }; - main @= fn() { - f @= mkfoo(); - puti(f.x); - puti(f.y); + puti(x(10, 30)); + a @= x(20, 40); + puti(a); + puti(z(10, 30)); + b @= z(20, 40); + puti(b); }; diff --git a/types.c b/types.c index 2fd0755..c90c2d8 100644 --- a/types.c +++ b/types.c @@ -180,6 +180,33 @@ static bool type_of_fn(Typer *tr, Expression *e, Type *t) { t->fn.constant = NULL; /* OPTIM: constant doesn't need to be a dynamic array */ bool has_constant_params = false; Type *ret_type = typer_arr_add(tr, &t->fn.types); + if (f->ret_decls && f->ret_type.kind == TYPE_VOID /* haven't found return type yet */) { + /* find return type */ + arr_foreach(f->ret_decls, Declaration, d) { + if (!types_decl(tr, d)) + return false; + /* evaluate ret decl initializer */ + if (d->flags & DECL_HAS_EXPR) { + Value val; + if (!eval_expr(tr->evalr, &d->expr, &val)) + return false; + d->expr.kind = EXPR_VAL; + d->expr.val = val; + } + } + if (arr_len(f->ret_decls) == 1 && arr_len(f->ret_decls[0].idents) == 1) { + f->ret_type = f->ret_decls[0].type; + } else { + f->ret_type.kind = TYPE_TUPLE; + f->ret_type.flags = 0; + f->ret_type.tuple = NULL; + arr_foreach(f->ret_decls, Declaration, d) { + arr_foreach(d->idents, Identifier, i) { + *(Type *)arr_add(&f->ret_type.tuple) = d->type; + } + } + } + } if (!type_resolve(tr, &f->ret_type, e->where)) return false; *ret_type = f->ret_type; -- cgit v1.2.3