summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--infer.c22
-rw-r--r--types.c298
2 files changed, 174 insertions, 146 deletions
diff --git a/infer.c b/infer.c
index b813fe5..46c2df1 100644
--- a/infer.c
+++ b/infer.c
@@ -19,18 +19,18 @@ static bool infer_from_expr(Typer *tr, Expression *match, Expression *to, Identi
}
}
break;
- /* case EXPR_CALL: { */
- /* if (to->kind != EXPR_CALL) return true; /\* give up *\/ */
- /* Argument *m_args = match->call.args; */
- /* Expression *t_args = to->call.arg_exprs; */
- /* size_t nargs = arr_len(m_args); */
+ case EXPR_CALL: {
+ if (to->kind != EXPR_CALL) return true; /* give up */
+ Argument *m_args = match->call.args;
+ Expression *t_args = to->call.arg_exprs;
+ size_t nargs = arr_len(m_args);
- /* if (nargs != arr_len(t_args)) return true; */
- /* for (size_t i = 0; i < nargs; ++i) { */
- /* Argument *m_arg = &m_args[i]; */
- /* Expression *t_arg = &t_args[i]; */
- /* } */
- /* } break; */
+ if (nargs != arr_len(t_args)) return true;
+ for (size_t i = 0; i < nargs; ++i) {
+ Argument *m_arg = &m_args[i];
+ Expression *t_arg = &t_args[i];
+ }
+ } break;
default: break;
}
return true;
diff --git a/types.c b/types.c
index 63e386a..2f2c03a 100644
--- a/types.c
+++ b/types.c
@@ -708,6 +708,75 @@ static bool types_fn(Typer *tr, FnExpr *f, Type *t, Location where,
return success;
}
+/* returns a dynamic array of the parameter indices of the arguments. */
+static U16 *call_arg_param_order(Allocator *allocr, FnExpr *fn, Location fn_where, Type *fn_type, Argument *args, Location where) {
+ size_t nparams = arr_len(fn_type->fn.types)-1;
+ size_t nargs = arr_len(args);
+ if (nargs > nparams) {
+ err_print(where, "Expected at most %lu arguments to function, but got %lu.",
+ nparams, nargs);
+ return false;
+ }
+ int p = 0; /* counter for sequential parameters */
+
+ Declaration *last_param_without_default_value = NULL;
+ arr_foreach(fn->params, Declaration, param) {
+ if (!(param->flags & DECL_HAS_EXPR)) {
+ last_param_without_default_value = param;
+ }
+ }
+ Declaration *param = fn->params;
+ size_t ident_idx = 0;
+ U16 *order = NULL;
+ arr_foreach(args, Argument, arg) {
+ bool named = arg->name != NULL;
+ int param_idx = -1;
+ if (named) {
+ /* named argument */
+ int index = 0;
+ bool found = false;
+ arr_foreach(fn->params, Declaration, pa) {
+ arr_foreach(pa->idents, Identifier, id) {
+ if (*id == arg->name) {
+ found = true;
+ break;
+ }
+ ++index;
+ }
+ if (found) break;
+ }
+ if (!found) {
+ char *s = ident_to_str(arg->name);
+ err_print(arg->where, "Argument '%s' does not appear in declaration of function.", s);
+ free(s);
+ info_print(fn_where, "Declaration is here.");
+ return false;
+ }
+ param_idx = index;
+ } else if ((param->flags & (DECL_HAS_EXPR | DECL_INFER)) && param < last_param_without_default_value) {
+ /* this param must be named; so this is referring to a later parameter */
+ --arg;
+ } else {
+ param_idx = p;
+ }
+
+ if (param_idx != -1) {
+ *(U16 *)arr_adda(&order, allocr) = (U16)param_idx;
+ }
+
+ if (!named) {
+ /* sequential order of parameters */
+ ++p;
+ ++ident_idx;
+ if (ident_idx == arr_len(param->idents)) {
+ ++param;
+ ident_idx = 0;
+ }
+ }
+ }
+ return order;
+}
+
static bool types_expr(Typer *tr, Expression *e) {
if (e->flags & EXPR_FOUND_TYPE) return true;
Type *t = &e->type;
@@ -1046,75 +1115,33 @@ static bool types_expr(Typer *tr, Expression *e) {
}
if (fn_decl) {
- if (nargs > nparams) {
- err_print(e->where, "Expected at most %lu arguments to function, but got %lu.",
- nparams, nargs);
- return false;
- }
- int p = 0; /* counter for sequential parameters */
-
- Declaration *last_param_without_default_value = NULL;
- arr_foreach(fn_decl->params, Declaration, param) {
- if (!(param->flags & DECL_HAS_EXPR)) {
- last_param_without_default_value = param;
- }
- }
- Declaration *param = fn_decl->params;
- size_t ident_idx = 0;
-
- arr_foreach(args, Argument, arg) {
- bool named = arg->name != NULL;
- int param_idx = -1;
- if (named) {
- /* named argument */
- int index = 0;
- bool found = false;
- arr_foreach(fn_decl->params, Declaration, pa) {
- arr_foreach(pa->idents, Identifier, id) {
- if (*id == arg->name) {
- found = true;
- break;
- }
- ++index;
+ U16 *order = call_arg_param_order(tr->allocr, fn_decl, ident_decl(f->ident)->decl->where, &f->type, c->args, e->where);
+ size_t arg;
+ for (arg = 0; arg < nargs; ++arg) {
+ U16 idx = order[arg];
+ Expression expr = args[arg].val;
+ arg_exprs[idx] = expr;
+ if (params_set[idx]) {
+ Declaration *param = fn_decl->params;
+ Identifier *ident;
+ for (Declaration *end = arr_end(fn_decl->params); param < end; ++param) {
+ ident = param->idents;
+ for (Identifier *iend = arr_end(param->idents); ident != iend; ++ident) {
+ if (idx == 0)
+ goto dblbreak;
+ --idx;
}
- if (found) break;
- }
- if (!found) {
- char *s = ident_to_str(arg->name);
- err_print(arg->where, "Argument '%s' does not appear in declaration of function.", s);
- free(s);
- info_print(idecl_where(ident_decl(f->ident)), "Declaration is here.");
- return false;
- }
- param_idx = index;
- } else if ((param->flags & (DECL_HAS_EXPR | DECL_INFER)) && param < last_param_without_default_value) {
- /* this param must be named; so this is referring to a later parameter */
- --arg;
- } else {
- param_idx = p;
- }
-
- if (param_idx != -1) {
- if (params_set[param_idx]) {
- char *s = ident_to_str(param->idents[ident_idx]);
- err_print(arg->where, "Argument #%lu (%s) set twice in function call.", param_idx+1, s);
- free(s);
- return false;
- }
- params_set[param_idx] = true;
- arg_exprs[param_idx] = arg->val;
- }
-
- if (!named) {
- /* sequential order of parameters */
- ++p;
- ++ident_idx;
- if (ident_idx == arr_len(param->idents)) {
- ++param;
- ident_idx = 0;
}
+ assert(0);
+ dblbreak:;
+ char *s = ident_to_str(*ident);
+ err_print(args[arg].where, "Argument #%lu (%s) set twice in function call.", idx+1, s);
+ free(s);
+ return false;
}
+ params_set[idx] = true;
}
+ arr_cleara(&order, tr->allocr);
} else {
if (nargs != nparams) {
err_print(e->where, "Expected %lu arguments to function call, but got %lu.", (unsigned long)nparams, (unsigned long)nargs);
@@ -1163,6 +1190,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
}
+ c->arg_exprs = arg_exprs;
FnExpr *original_fn = NULL;
Type table_index_type = {0};
Value table_index = {0};
@@ -1187,73 +1215,7 @@ static bool types_expr(Typer *tr, Expression *e) {
Declaration *param_decl = fn->params;
size_t ident_idx = 0;
size_t i = 0;
-
-
- table_index_type.flags = TYPE_IS_RESOLVED;
- table_index_type.kind = TYPE_TUPLE;
- table_index_type.tuple = NULL;
- Type *u64t = typer_arr_add(tr, &table_index_type.tuple);
- u64t->was_expr = NULL;
- u64t->flags = TYPE_IS_RESOLVED;
- u64t->kind = TYPE_BUILTIN;
- u64t->builtin = BUILTIN_U64;
- table_index.tuple = NULL;
- /* we need to keep table_index's memory around because instance_table_add makes a copy of it to compare against. */
- Value *which_are_const_val = typer_arr_add(tr, &table_index.tuple);
- U64 *which_are_const = &which_are_const_val->u64;
- *which_are_const = 0;
- int semi_const_index = 0;
- /* eval compile time arguments */
- for (i = 0; i < nparams; ++i) {
- bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]);
- if (should_be_evald) {
- if (params_set[i]) {
- Expression *expr = &arg_exprs[i];
- Value *arg_val = typer_arr_add(tr, &table_index.tuple);
- if (!eval_expr(tr->evalr, expr, arg_val)) {
- if (tr->evalr->enabled) {
- info_print(arg_exprs[i].where, "(error occured while trying to evaluate compile-time argument, argument #%lu)", 1+(unsigned long)i);
- }
- return false;
- }
-
- Type *type = &expr->type;
- *(Type *)typer_arr_add(tr, &table_index_type.tuple) = *type;
-
- arg_exprs[i].kind = EXPR_VAL;
- arg_exprs[i].flags = EXPR_FOUND_TYPE;
- copy_val(tr->allocr, &arg_exprs[i].val, arg_val, type);
- arg_exprs[i].val = *arg_val;
- copy_val(tr->allocr, &param_decl->val, arg_val, type);
- param_decl->flags |= DECL_FOUND_VAL;
- if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) {
- param_decl->type = *type;
- }
- } else {
- /* leave gap for this (default argument) */
- typer_arr_add(tr, &table_index.tuple);
- typer_arr_add(tr, &table_index_type.tuple);
- }
- }
-
- if (fn_type->constness[i] == CONSTNESS_SEMI) {
- if (semi_const_index >= 64) {
- err_print(f->where, "You can't have more than 64 semi-constant arguments to a function at the moment (sorry).");
- return false;
- }
- *which_are_const |= ((U64)1) << semi_const_index;
- }
- if (fn_type->constness[i] == CONSTNESS_SEMI) {
- ++semi_const_index;
- }
- ++ident_idx;
- if (ident_idx >= arr_len(param_decl->idents)) {
- ident_idx = 0;
- ++param_decl;
- }
- }
- i = 0;
Type **arg_types = NULL;
Type **decl_types = NULL;
Identifier *inferred_idents = NULL;
@@ -1318,7 +1280,75 @@ static bool types_expr(Typer *tr, Expression *e) {
}
}
- /* type return declarations, etc */
+
+
+ i = 0;
+
+
+ table_index_type.flags = TYPE_IS_RESOLVED;
+ table_index_type.kind = TYPE_TUPLE;
+ table_index_type.tuple = NULL;
+ Type *u64t = typer_arr_add(tr, &table_index_type.tuple);
+ u64t->was_expr = NULL;
+ u64t->flags = TYPE_IS_RESOLVED;
+ u64t->kind = TYPE_BUILTIN;
+ u64t->builtin = BUILTIN_U64;
+ table_index.tuple = NULL;
+ /* we need to keep table_index's memory around because instance_table_add makes a copy of it to compare against. */
+ Value *which_are_const_val = typer_arr_add(tr, &table_index.tuple);
+ U64 *which_are_const = &which_are_const_val->u64;
+ *which_are_const = 0;
+ int semi_const_index = 0;
+ /* eval compile time arguments */
+ for (i = 0; i < nparams; ++i) {
+ bool should_be_evald = arg_is_const(&arg_exprs[i], fn_type->constness[i]);
+ if (should_be_evald) {
+ if (params_set[i]) {
+ Expression *expr = &arg_exprs[i];
+ Value *arg_val = typer_arr_add(tr, &table_index.tuple);
+ if (!eval_expr(tr->evalr, expr, arg_val)) {
+ if (tr->evalr->enabled) {
+ info_print(arg_exprs[i].where, "(error occured while trying to evaluate compile-time argument, argument #%lu)", 1+(unsigned long)i);
+ }
+ return false;
+ }
+
+ Type *type = &expr->type;
+ *(Type *)typer_arr_add(tr, &table_index_type.tuple) = *type;
+
+ arg_exprs[i].kind = EXPR_VAL;
+ arg_exprs[i].flags = EXPR_FOUND_TYPE;
+ copy_val(tr->allocr, &arg_exprs[i].val, arg_val, type);
+ arg_exprs[i].val = *arg_val;
+ copy_val(tr->allocr, &param_decl->val, arg_val, type);
+ param_decl->flags |= DECL_FOUND_VAL;
+ if (!(param_decl->flags & DECL_ANNOTATES_TYPE)) {
+ param_decl->type = *type;
+ }
+ } else {
+ /* leave gap for this (default argument) */
+ typer_arr_add(tr, &table_index.tuple);
+ typer_arr_add(tr, &table_index_type.tuple);
+ }
+ }
+
+ if (fn_type->constness[i] == CONSTNESS_SEMI) {
+ if (semi_const_index >= 64) {
+ err_print(f->where, "You can't have more than 64 semi-constant arguments to a function at the moment (sorry).");
+ return false;
+ }
+ *which_are_const |= ((U64)1) << semi_const_index;
+ }
+ if (fn_type->constness[i] == CONSTNESS_SEMI) {
+ ++semi_const_index;
+ }
+ ++ident_idx;
+ if (ident_idx >= arr_len(param_decl->idents)) {
+ ident_idx = 0;
+ ++param_decl;
+ }
+ }
+ /* type params, return declarations, etc */
if (!type_of_fn(tr, &fn_copy, e->where, &f->type, TYPE_OF_FN_IS_INSTANCE))
return false;
@@ -1392,9 +1422,7 @@ static bool types_expr(Typer *tr, Expression *e) {
}
*t = *ret_type;
- c->arg_exprs = arg_exprs;
- break;
- }
+ } break;
case EXPR_BLOCK: {
Block *b = &e->block;
if (!types_block(tr, b))