mirror of
https://github.com/Ed94/Odin.git
synced 2026-06-24 06:35:00 -07:00
Refactor default parameter values
This commit is contained in:
+6
-17
@@ -4168,9 +4168,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
||||
}
|
||||
|
||||
if (e->kind == Entity_Variable) {
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid ||
|
||||
e->Variable.default_is_nil ||
|
||||
e->Variable.default_is_location) {
|
||||
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
|
||||
param_count--;
|
||||
continue;
|
||||
}
|
||||
@@ -4190,9 +4188,7 @@ CALL_ARGUMENT_CHECKER(check_call_arguments_internal) {
|
||||
}
|
||||
|
||||
if (e->kind == Entity_Variable) {
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid ||
|
||||
e->Variable.default_is_nil ||
|
||||
e->Variable.default_is_location) {
|
||||
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
|
||||
param_count_excluding_defaults--;
|
||||
continue;
|
||||
}
|
||||
@@ -4442,10 +4438,7 @@ CALL_ARGUMENT_CHECKER(check_named_call_arguments) {
|
||||
continue;
|
||||
}
|
||||
if (e->kind == Entity_Variable) {
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
score += assign_score_function(1);
|
||||
continue;
|
||||
} else if (e->Variable.default_is_nil) {
|
||||
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
|
||||
score += assign_score_function(1);
|
||||
continue;
|
||||
}
|
||||
@@ -5218,8 +5211,8 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
case_ast_node(i, Implicit, node)
|
||||
switch (i->kind) {
|
||||
case Token_context:
|
||||
if (c->proc_name.len == 0) {
|
||||
error(node, "'context' is only allowed within procedures");
|
||||
if (c->proc_name.len == 0 && c->curr_proc_sig == nullptr) {
|
||||
error(node, "'context' is only allowed within procedures %p", c->curr_proc_decl);
|
||||
return kind;
|
||||
}
|
||||
|
||||
@@ -5500,11 +5493,7 @@ ExprKind check_expr_base_internal(CheckerContext *c, Operand *o, Ast *node, Type
|
||||
for (isize i = min_field_count-1; i >= 0; i--) {
|
||||
Entity *e = t->Struct.fields[i];
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
if (e->Variable.default_is_nil) {
|
||||
min_field_count--;
|
||||
} else if (e->Variable.default_is_undef) {
|
||||
min_field_count--;
|
||||
} else if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
if (e->Variable.param_value.kind != ParameterValue_Invalid) {
|
||||
min_field_count--;
|
||||
} else {
|
||||
break;
|
||||
|
||||
+27
-10
@@ -1065,9 +1065,14 @@ Type *check_get_params(CheckerContext *ctx, Scope *scope, Ast *_params, bool *is
|
||||
}
|
||||
|
||||
param = alloc_entity_param(scope, name->Ident.token, type, is_using, is_in);
|
||||
param->Variable.default_value = value;
|
||||
param->Variable.default_is_nil = default_is_nil;
|
||||
param->Variable.default_is_location = default_is_location;
|
||||
if (default_is_nil) {
|
||||
param->Variable.param_value.kind = ParameterValue_Nil;
|
||||
} else if (default_is_location) {
|
||||
param->Variable.param_value.kind = ParameterValue_Location;
|
||||
} else if (value.kind != ExactValue_Invalid) {
|
||||
param->Variable.param_value.kind = ParameterValue_Constant;
|
||||
param->Variable.param_value.value = value;
|
||||
}
|
||||
}
|
||||
if (p->flags&FieldFlag_no_alias) {
|
||||
param->flags |= EntityFlag_NoAlias;
|
||||
@@ -1194,8 +1199,12 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
|
||||
Token token = ast_token(field->type);
|
||||
token.string = str_lit("");
|
||||
Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
param->Variable.default_value = value;
|
||||
param->Variable.default_is_nil = default_is_nil;
|
||||
if (default_is_nil) {
|
||||
param->Variable.param_value.kind = ParameterValue_Nil;
|
||||
} else if (value.kind != ExactValue_Invalid) {
|
||||
param->Variable.param_value.kind = ParameterValue_Constant;
|
||||
param->Variable.param_value.value = value;
|
||||
}
|
||||
array_add(&variables, param);
|
||||
} else {
|
||||
for_array(j, field->names) {
|
||||
@@ -1218,8 +1227,12 @@ Type *check_get_results(CheckerContext *ctx, Scope *scope, Ast *_results) {
|
||||
|
||||
Entity *param = alloc_entity_param(scope, token, type, false, false);
|
||||
param->flags |= EntityFlag_Result;
|
||||
param->Variable.default_value = value;
|
||||
param->Variable.default_is_nil = default_is_nil;
|
||||
if (default_is_nil) {
|
||||
param->Variable.param_value.kind = ParameterValue_Nil;
|
||||
} else if (value.kind != ExactValue_Invalid) {
|
||||
param->Variable.param_value.kind = ParameterValue_Constant;
|
||||
param->Variable.param_value.value = value;
|
||||
}
|
||||
array_add(&variables, param);
|
||||
add_entity(ctx->checker, scope, name, param);
|
||||
}
|
||||
@@ -1465,9 +1478,13 @@ bool check_procedure_type(CheckerContext *ctx, Type *type, Ast *proc_type_node,
|
||||
if (param_count > 0) {
|
||||
for_array(i, params->Tuple.variables) {
|
||||
Entity *param = params->Tuple.variables[i];
|
||||
if (param->kind == Entity_Variable && param->Variable.default_value.kind == ExactValue_Procedure) {
|
||||
type->Proc.has_proc_default_values = true;
|
||||
break;
|
||||
if (param->kind == Entity_Variable) {
|
||||
ParameterValue pv = param->Variable.param_value;
|
||||
if (pv.kind == ParameterValue_Constant &&
|
||||
pv.value.kind == ExactValue_Procedure) {
|
||||
type->Proc.has_proc_default_values = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+18
-4
@@ -56,6 +56,19 @@ enum EntityState {
|
||||
};
|
||||
|
||||
|
||||
enum ParameterValueKind {
|
||||
ParameterValue_Invalid,
|
||||
ParameterValue_Constant,
|
||||
ParameterValue_Nil,
|
||||
ParameterValue_Location,
|
||||
};
|
||||
|
||||
struct ParameterValue {
|
||||
ParameterValueKind kind;
|
||||
ExactValue value;
|
||||
};
|
||||
|
||||
|
||||
// An Entity is a named "thing" in the language
|
||||
struct Entity {
|
||||
EntityKind kind;
|
||||
@@ -84,7 +97,9 @@ struct Entity {
|
||||
struct {
|
||||
i32 field_index;
|
||||
i32 field_src_index;
|
||||
ExactValue default_value;
|
||||
|
||||
ParameterValue param_value;
|
||||
|
||||
String thread_local_model;
|
||||
Entity * foreign_library;
|
||||
Ast * foreign_library_ident;
|
||||
@@ -93,9 +108,8 @@ struct Entity {
|
||||
bool is_foreign;
|
||||
bool is_export;
|
||||
|
||||
bool default_is_nil;
|
||||
bool default_is_undef;
|
||||
bool default_is_location;
|
||||
// bool default_is_nil;
|
||||
// bool default_is_location;
|
||||
bool is_immutable;
|
||||
} Variable;
|
||||
struct {
|
||||
|
||||
+59
-17
@@ -5348,10 +5348,17 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
||||
} else {
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
if (args[i] == nullptr) {
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
args[i] = ir_value_constant(e->type, e->Variable.default_value);
|
||||
} else {
|
||||
switch (e->Variable.param_value.kind) {
|
||||
case ParameterValue_Constant:
|
||||
args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
|
||||
break;
|
||||
case ParameterValue_Nil:
|
||||
args[i] = ir_value_nil(e->type);
|
||||
break;
|
||||
case ParameterValue_Location:
|
||||
// args[i] =
|
||||
GB_PANIC("TODO ParameterValue_Location");
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
args[i] = ir_emit_conv(proc, args[i], e->type);
|
||||
@@ -5434,12 +5441,17 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
||||
while (arg_index < end) {
|
||||
Entity *e = param_tuple->variables[arg_index];
|
||||
GB_ASSERT(e->kind == Entity_Variable);
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
args[arg_index++] = ir_value_constant(e->type, e->Variable.default_value);
|
||||
} else if (e->Variable.default_is_location) {
|
||||
args[arg_index++] = ir_emit_source_code_location(proc, proc_name, pos);
|
||||
} else {
|
||||
|
||||
switch (e->Variable.param_value.kind) {
|
||||
case ParameterValue_Constant:
|
||||
args[arg_index++] = ir_value_constant(e->type, e->Variable.param_value.value);
|
||||
break;
|
||||
case ParameterValue_Nil:
|
||||
args[arg_index++] = ir_value_nil(e->type);
|
||||
break;
|
||||
case ParameterValue_Location:
|
||||
args[arg_index++] = ir_emit_source_code_location(proc, proc_name, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -5521,12 +5533,16 @@ irValue *ir_build_expr_internal(irProcedure *proc, Ast *expr) {
|
||||
if (variadic && variadic_index+1 < param_count) {
|
||||
for (isize i = variadic_index+1; i < param_count; i++) {
|
||||
Entity *e = param_tuple->variables[i];
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
args[i] = ir_value_constant(e->type, e->Variable.default_value);
|
||||
} else if (e->Variable.default_is_location) {
|
||||
args[i] = ir_emit_source_code_location(proc, proc_name, pos);
|
||||
} else {
|
||||
switch (e->Variable.param_value.kind) {
|
||||
case ParameterValue_Constant:
|
||||
args[i] = ir_value_constant(e->type, e->Variable.param_value.value);
|
||||
break;
|
||||
case ParameterValue_Nil:
|
||||
args[i] = ir_value_nil(e->type);
|
||||
break;
|
||||
case ParameterValue_Location:
|
||||
args[i] = ir_emit_source_code_location(proc, proc_name, pos);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -7602,8 +7618,20 @@ void ir_begin_procedure_body(irProcedure *proc) {
|
||||
if (e->token.string != "") {
|
||||
GB_ASSERT(!is_blank_ident(e->token));
|
||||
irValue *res = ir_add_local(proc, e, e->identifier, true);
|
||||
if (e->Variable.default_value.kind != ExactValue_Invalid) {
|
||||
irValue *c = ir_value_constant(e->type, e->Variable.default_value);
|
||||
|
||||
irValue *c = nullptr;
|
||||
switch (e->Variable.param_value.kind) {
|
||||
case ParameterValue_Constant:
|
||||
c = ir_value_constant(e->type, e->Variable.param_value.value);
|
||||
break;
|
||||
case ParameterValue_Nil:
|
||||
c = ir_value_nil(e->type);
|
||||
break;
|
||||
case ParameterValue_Location:
|
||||
GB_PANIC("ParameterValue_Location");
|
||||
break;
|
||||
}
|
||||
if (c != nullptr) {
|
||||
ir_emit_store(proc, res, c);
|
||||
}
|
||||
}
|
||||
@@ -7704,8 +7732,22 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
|
||||
for_array(i, p->params->Tuple.variables) {
|
||||
Entity *f = p->params->Tuple.variables[i];
|
||||
if (f->kind == Entity_Variable) {
|
||||
if (f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||
Ast *expr = f->Variable.default_value.value_procedure;
|
||||
ParameterValue pv = f->Variable.param_value;
|
||||
if (pv.kind == ParameterValue_Constant && pv.value.kind == ExactValue_Procedure) {
|
||||
Ast *expr = f->Variable.param_value.value.value_procedure;
|
||||
GB_ASSERT(expr != nullptr);
|
||||
if (expr->kind == Ast_ProcLit) {
|
||||
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
for_array(i, p->results->Tuple.variables) {
|
||||
Entity *f = p->results->Tuple.variables[i];
|
||||
if (f->kind == Entity_Variable) {
|
||||
ParameterValue pv = f->Variable.param_value;
|
||||
if (pv.kind == ParameterValue_Constant && pv.value.kind == ExactValue_Procedure) {
|
||||
Ast *expr = f->Variable.param_value.value.value_procedure;
|
||||
GB_ASSERT(expr != nullptr);
|
||||
if (expr->kind == Ast_ProcLit) {
|
||||
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||
|
||||
Reference in New Issue
Block a user