diff options
-rw-r--r-- | infer.c | 22 | ||||
-rw-r--r-- | types.c | 298 |
2 files changed, 174 insertions, 146 deletions
@@ -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; @@ -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, ¶m_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, ¶m_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)) |