diff options
author | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-28 10:22:20 -0400 |
---|---|---|
committer | Leo Tenenbaum <pommicket@gmail.com> | 2019-09-28 10:22:20 -0400 |
commit | f6efc17f61ebf5c57093fdba2963898602f9281e (patch) | |
tree | 6b771f9f0f8b58f450128ab033c4349239825278 | |
parent | 991d739bb02b3506da5a0af0edd9a4fd505373a3 (diff) |
optional params
-rw-r--r-- | main.c | 3 | ||||
-rw-r--r-- | test.toc | 8 | ||||
-rw-r--r-- | types.c | 34 |
3 files changed, 25 insertions, 20 deletions
@@ -1,9 +1,8 @@ /* TODO: -named args -optional params char type string constants are []char +new/delete evaluator (simplify compile time constant expressions) re-do cgen any odd number of "s for a string @@ -1,10 +1,10 @@ main @= fn() { foo @= fn() i64 { return 3; }; - test @= fn(x : i64, y : i32, z,w: i64) ret1 : i64, ret2 : i64 { - ret1 = x; + test @= fn(x : i64, y : i32, z,w : f32 = 18, foo := false) ret1 : i64, ret2 : i64 { + ret1 = x + (z + w as i64); }; a,b : i64; - a, b = test(3,7,2,3); - a, b = test(x = 3, z = 7, w = 30, y = 20); + a, b = test(3,7,2, foo = true); + a, b = test(x = 3, y = 30); }; @@ -495,18 +495,14 @@ static bool types_expr(Typer *tr, Expression *e) { Type *param_types = ret_type + 1; Argument *args = c->args.data; size_t nparams = f->type.fn.types.len - 1; - if (nparams != c->args.len) { - err_print(e->where, "Expected %lu arguments to function, but got %lu.", (unsigned long)nparams, (unsigned long)c->args.len); - return false; - } + size_t nargs = c->args.len; bool ret = true; FnExpr *fn_decl = NULL; Array new_args_arr; - size_t nargs = c->args.len; arr_create(&new_args_arr, sizeof(Expression)); - arr_set_len(&new_args_arr, nargs); + arr_set_len(&new_args_arr, nparams); Expression *new_args = new_args_arr.data; - bool *params_set = calloc(nargs, sizeof *params_set); + bool *params_set = calloc(nparams, sizeof *params_set); if (f->kind == EXPR_IDENT) { IdentDecl *decl = ident_decl(f->ident); assert(decl); @@ -516,13 +512,18 @@ static bool types_expr(Typer *tr, Expression *e) { fn_decl = &decl->decl->expr.fn; } } + if (!fn_decl && nargs != nparams) { + err_print(e->where, "Expected %lu arguments to function call, but got %lu.", (unsigned long)nparams, (unsigned long)nargs); + return false; + } bool had_named_arg = false; - for (size_t p = 0; p < nparams; p++) { + for (size_t p = 0; p < nargs; p++) { if (args[p].name) { if (!fn_decl) { err_print(args[p].where, "You must call a function directly by its name to use named arguments."); return false; } + had_named_arg = true; long index = 0; long arg_index = -1; arr_foreach(&fn_decl->params, Declaration, param) { @@ -563,18 +564,23 @@ static bool types_expr(Typer *tr, Expression *e) { params_set[p] = true; } if (!ret) return false; - for (size_t i = 0; i < nargs; i++) { + for (size_t i = 0; i < nparams; i++) { if (!params_set[i]) { size_t index = 0; - assert(fn_decl); /* we can only miss an arg if we're using named args */ + assert(fn_decl); /* we can only miss an arg if we're using named/optional args */ arr_foreach(&fn_decl->params, Declaration, param) { + bool is_required = !(param->flags & DECL_FLAG_HAS_EXPR); arr_foreach(¶m->idents, Identifier, ident) { if (index == i) { - char *s = ident_to_str(*ident); - err_print(e->where, "Argument %lu (%s) not set in function call.", 1+(unsigned long)i, s); - free(s); - return false; + if (is_required) { + char *s = ident_to_str(*ident); + err_print(e->where, "Argument %lu (%s) not set in function call.", 1+(unsigned long)i, s); + free(s); + return false; + } else { + new_args[i] = param->expr; + } } index++; } |