Rewriting function calls to have named parameters, default values
This commit is contained in:
@@ -269,7 +269,6 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
result.is_const = true;
|
||||
}
|
||||
else if(sym->kind == SYM_CONST || sym->kind == SYM_VAR){
|
||||
// if(sym->type == type_type) type_complete(sym->type_val);
|
||||
result.type = sym->type;
|
||||
result.is_const = sym->kind == SYM_CONST ? true : false;
|
||||
result.value = sym->value;
|
||||
@@ -305,7 +304,8 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
if(type.type != type_type) parsing_error(it[0]->pos, "Required expression of kind [type]");
|
||||
args.add(type.type_val);
|
||||
}
|
||||
lambda_type = type_lambda(ret_type, args);
|
||||
lambda_type = type_lambda(node, ret_type, args);
|
||||
|
||||
{
|
||||
assert(lambda_type);
|
||||
Value val; val.type_val = lambda_type;
|
||||
@@ -377,17 +377,71 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
resolve_type_pair(i->pos, expr.type, item_type);
|
||||
}
|
||||
}
|
||||
else if(type->kind == TYPE_STRUCT){
|
||||
not_implemented;
|
||||
}
|
||||
else if(type->kind == TYPE_LAMBDA){
|
||||
if(type->func.args.len != node->exprs.len) parsing_error(node->pos, "Invalid number of arguments");
|
||||
For(node->exprs){
|
||||
Ast_Call_Item *i = (Ast_Call_Item *)it[0];
|
||||
assert(i->kind == AST_CALL_ITEM);
|
||||
auto lambda = (Ast_Lambda *)type->ast;
|
||||
|
||||
S64 index = node->exprs.get_index(it);
|
||||
Operand expr = resolve_expr(i->item);
|
||||
if(expr.type != type->func.args[index]) parsing_error(i->pos, "Type is not matching function definition");
|
||||
Scratch scratch;
|
||||
Array<Ast_Call_Item *> items = {scratch};
|
||||
|
||||
For(lambda->args){
|
||||
S64 i = lambda->args.get_index(it);
|
||||
Ast_Resolved_Type *resolved = type->func.args[i];
|
||||
Ast_Lambda_Arg *arg = it[0];
|
||||
|
||||
// @note: match any in list of call items, if none matched then we have a problem
|
||||
// there are three kinds of possible matches: indexed, named, default
|
||||
S64 default_iter = 0;
|
||||
Ast_Call_Item *item = 0;
|
||||
For_It(node->exprs, expr){
|
||||
Ast_Atom *name = expr[0]->name;
|
||||
Ast_Expr *index = expr[0]->index;
|
||||
assert(!(name && index)); // Only one of those can be valid
|
||||
|
||||
if(name){
|
||||
assert(name->kind == AST_IDENT);
|
||||
if(name->intern_val.str == arg->name.str) item = expr[0];
|
||||
}
|
||||
else if(index){
|
||||
Operand op = resolve_expr(index);
|
||||
if(!op.is_const) parsing_error(index->pos, "Function call index is not constant");
|
||||
if(op.type != type_int) parsing_error(index->pos, "Function call index is not [Int]");
|
||||
if(op.int_val == i) item = expr[0];
|
||||
}
|
||||
else if(node->exprs.get_index(expr) == default_iter){
|
||||
// @todo might feel janky
|
||||
default_iter++;
|
||||
item = expr[0];
|
||||
}
|
||||
|
||||
if(item) break;
|
||||
}
|
||||
|
||||
if(item){
|
||||
item->flags = set_flag(item->flags, AST_ITEM_INCLUDED);
|
||||
Operand expr = resolve_expr(item->item);
|
||||
if(expr.type != resolved) parsing_error(item->pos, "Type is not matching function definition");
|
||||
items.add(item);
|
||||
}
|
||||
else{
|
||||
if(arg->default_value){
|
||||
// @todo make sure default values have valid types but in lambda definition
|
||||
Ast_Call_Item *item_default = ast_call_item(arg->default_value->pos, 0, 0, arg->default_value);
|
||||
items.add(item_default);
|
||||
}
|
||||
else parsing_error(arg->pos, "Required value in lambda call was not passed");
|
||||
}
|
||||
}
|
||||
|
||||
For(node->exprs){
|
||||
if(!is_flag_set(it[0]->flags, AST_ITEM_INCLUDED)){
|
||||
parsing_error(it[0]->pos, "Invalid argument to function call");
|
||||
}
|
||||
}
|
||||
|
||||
node->exprs = items.tight_copy(pctx->perm);
|
||||
type = type->func.ret;
|
||||
}
|
||||
else parsing_error(node->pos, "Invalid function call type");
|
||||
@@ -489,7 +543,7 @@ resolve_expr(Ast_Expr *ast, Ast_Resolved_Type *expected_type, Sym *const_sym){
|
||||
sym_new_resolved(SYM_VAR, name, op.type, {}, it[0]);
|
||||
members.add({op.type, name});
|
||||
}
|
||||
Ast_Resolved_Type *resolved = type_struct(const_sym, members);
|
||||
Ast_Resolved_Type *resolved = type_struct(node, members);
|
||||
Operand result = {type_type, true}; result.type_val = resolved;
|
||||
return result;
|
||||
BREAK();
|
||||
@@ -588,7 +642,7 @@ parse_file(){
|
||||
sym->kind = SYM_CONST;
|
||||
Ast_Struct *s = const_try_getting_struct(decl);
|
||||
if(s){
|
||||
s->type = type_incomplete(sym);
|
||||
s->type = type_incomplete(decl);
|
||||
sym->type_val = s->type;
|
||||
sym->type = type_type;
|
||||
sym->state = SYM_RESOLVED;
|
||||
|
||||
Reference in New Issue
Block a user