summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--main.c3
-rw-r--r--test.toc8
-rw-r--r--types.c34
3 files changed, 25 insertions, 20 deletions
diff --git a/main.c b/main.c
index 6dc7f4d..a072ade 100644
--- a/main.c
+++ b/main.c
@@ -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
diff --git a/test.toc b/test.toc
index a925583..155b62b 100644
--- a/test.toc
+++ b/test.toc
@@ -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);
};
diff --git a/types.c b/types.c
index 7cb48e7..8f54b8e 100644
--- a/types.c
+++ b/types.c
@@ -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(&param->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++;
}