diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-16 11:42:59 -0500 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-11-16 11:42:59 -0500 |
commit | 54f1d5bc80117063a1b67f834b65dbb488ddf1c8 (patch) | |
tree | 4078ce41fbf09c8c320b3ad87d9c55981d577a95 | |
parent | e631bb0147147caf36a2b4ef63c7561f8221da02 (diff) |
bug fixes, return declaration initializers
-rw-r--r-- | eval.c | 3 | ||||
-rw-r--r-- | main.c | 5 | ||||
-rw-r--r-- | parse.c | 18 | ||||
-rw-r--r-- | test.toc | 25 | ||||
-rw-r--r-- | types.c | 27 |
5 files changed, 47 insertions, 31 deletions
@@ -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++; } } @@ -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;}) @@ -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; } @@ -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); }; @@ -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; |