mirror of
https://github.com/Ed94/Odin.git
synced 2026-08-06 07:38:48 +00:00
Default procedure values for proc
This commit is contained in:
+71
-3
@@ -1071,7 +1071,26 @@ Array<Entity *> check_struct_fields(Checker *c, AstNode *node, Array<AstNode *>
|
|||||||
if (is_operand_nil(o)) {
|
if (is_operand_nil(o)) {
|
||||||
default_is_nil = true;
|
default_is_nil = true;
|
||||||
} else if (o.mode != Addressing_Constant) {
|
} else if (o.mode != Addressing_Constant) {
|
||||||
error(default_value, "Default parameter must be a constant");
|
if (default_value->kind == AstNode_ProcLit) {
|
||||||
|
value = exact_value_procedure(default_value);
|
||||||
|
} else {
|
||||||
|
Entity *e = nullptr;
|
||||||
|
if (o.mode == Addressing_Value && is_type_proc(o.type)) {
|
||||||
|
Operand x = {};
|
||||||
|
if (default_value->kind == AstNode_Ident) {
|
||||||
|
e = check_ident(c, &x, default_value, nullptr, nullptr, false);
|
||||||
|
} else if (default_value->kind == AstNode_SelectorExpr) {
|
||||||
|
e = check_selector(c, &x, default_value, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != nullptr && e->kind == Entity_Procedure) {
|
||||||
|
value = exact_value_procedure(e->identifier);
|
||||||
|
add_entity_use(c, e->identifier, e);
|
||||||
|
} else {
|
||||||
|
error(default_value, "Default parameter must be a constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = o.value;
|
value = o.value;
|
||||||
}
|
}
|
||||||
@@ -2132,7 +2151,26 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
if (is_operand_nil(o)) {
|
if (is_operand_nil(o)) {
|
||||||
default_is_nil = true;
|
default_is_nil = true;
|
||||||
} else if (o.mode != Addressing_Constant) {
|
} else if (o.mode != Addressing_Constant) {
|
||||||
error(default_value, "Default parameter must be a constant");
|
if (default_value->kind == AstNode_ProcLit) {
|
||||||
|
value = exact_value_procedure(default_value);
|
||||||
|
} else {
|
||||||
|
Entity *e = nullptr;
|
||||||
|
if (o.mode == Addressing_Value && is_type_proc(o.type)) {
|
||||||
|
Operand x = {};
|
||||||
|
if (default_value->kind == AstNode_Ident) {
|
||||||
|
e = check_ident(c, &x, default_value, nullptr, nullptr, false);
|
||||||
|
} else if (default_value->kind == AstNode_SelectorExpr) {
|
||||||
|
e = check_selector(c, &x, default_value, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != nullptr && e->kind == Entity_Procedure) {
|
||||||
|
value = exact_value_procedure(e->identifier);
|
||||||
|
add_entity_use(c, e->identifier, e);
|
||||||
|
} else {
|
||||||
|
error(default_value, "Default parameter must be a constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = o.value;
|
value = o.value;
|
||||||
}
|
}
|
||||||
@@ -2201,7 +2239,26 @@ Type *check_get_params(Checker *c, Scope *scope, AstNode *_params, bool *is_vari
|
|||||||
if (is_operand_nil(o)) {
|
if (is_operand_nil(o)) {
|
||||||
default_is_nil = true;
|
default_is_nil = true;
|
||||||
} else if (o.mode != Addressing_Constant) {
|
} else if (o.mode != Addressing_Constant) {
|
||||||
error(default_value, "Default parameter must be a constant");
|
if (default_value->kind == AstNode_ProcLit) {
|
||||||
|
value = exact_value_procedure(default_value);
|
||||||
|
} else {
|
||||||
|
Entity *e = nullptr;
|
||||||
|
if (o.mode == Addressing_Value && is_type_proc(o.type)) {
|
||||||
|
Operand x = {};
|
||||||
|
if (default_value->kind == AstNode_Ident) {
|
||||||
|
e = check_ident(c, &x, default_value, nullptr, nullptr, false);
|
||||||
|
} else if (default_value->kind == AstNode_SelectorExpr) {
|
||||||
|
e = check_selector(c, &x, default_value, nullptr);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (e != nullptr && e->kind == Entity_Procedure) {
|
||||||
|
value = exact_value_procedure(e->identifier);
|
||||||
|
add_entity_use(c, e->identifier, e);
|
||||||
|
} else {
|
||||||
|
error(default_value, "Default parameter must be a constant");
|
||||||
|
}
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
value = o.value;
|
value = o.value;
|
||||||
}
|
}
|
||||||
@@ -2682,11 +2739,22 @@ bool check_procedure_type(Checker *c, Type *type, AstNode *proc_type_node, Array
|
|||||||
Type *params = check_get_params(c, c->context.scope, pt->params, &variadic, &success, &specialization_count, operands);
|
Type *params = check_get_params(c, c->context.scope, pt->params, &variadic, &success, &specialization_count, operands);
|
||||||
Type *results = check_get_results(c, c->context.scope, pt->results);
|
Type *results = check_get_results(c, c->context.scope, pt->results);
|
||||||
|
|
||||||
|
|
||||||
isize param_count = 0;
|
isize param_count = 0;
|
||||||
isize result_count = 0;
|
isize result_count = 0;
|
||||||
if (params) param_count = params ->Tuple.variables.count;
|
if (params) param_count = params ->Tuple.variables.count;
|
||||||
if (results) result_count = results->Tuple.variables.count;
|
if (results) result_count = results->Tuple.variables.count;
|
||||||
|
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
type->Proc.node = proc_type_node;
|
type->Proc.node = proc_type_node;
|
||||||
type->Proc.scope = c->context.scope;
|
type->Proc.scope = c->context.scope;
|
||||||
type->Proc.params = params;
|
type->Proc.params = params;
|
||||||
|
|||||||
+16
@@ -7422,6 +7422,22 @@ void ir_build_proc(irValue *value, irProcedure *parent) {
|
|||||||
|
|
||||||
proc->module->stmt_state_flags = prev_stmt_state_flags;
|
proc->module->stmt_state_flags = prev_stmt_state_flags;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if (proc->type->Proc.has_proc_default_values) {
|
||||||
|
auto *p = &proc->type->Proc;
|
||||||
|
for_array(i, p->params->Tuple.variables) {
|
||||||
|
Entity *f = p->params->Tuple.variables[i];
|
||||||
|
if (f->kind == Entity_Variable && f->Variable.default_value.kind == ExactValue_Procedure) {
|
||||||
|
AstNode *expr = f->Variable.default_value.value_procedure;
|
||||||
|
GB_ASSERT(expr != nullptr);
|
||||||
|
if (expr->kind == AstNode_ProcLit) {
|
||||||
|
ir_gen_anonymous_proc_lit(proc->module, proc->name, expr, proc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -139,14 +139,15 @@ struct TypeStruct {
|
|||||||
Type * results; /* Type_Tuple */ \
|
Type * results; /* Type_Tuple */ \
|
||||||
i32 param_count; \
|
i32 param_count; \
|
||||||
i32 result_count; \
|
i32 result_count; \
|
||||||
bool return_by_pointer; \
|
|
||||||
Type ** abi_compat_params; \
|
Type ** abi_compat_params; \
|
||||||
Type * abi_compat_result_type; \
|
Type * abi_compat_result_type; \
|
||||||
|
bool return_by_pointer; \
|
||||||
bool variadic; \
|
bool variadic; \
|
||||||
bool require_results; \
|
bool require_results; \
|
||||||
bool c_vararg; \
|
bool c_vararg; \
|
||||||
bool is_polymorphic; \
|
bool is_polymorphic; \
|
||||||
bool is_poly_specialized; \
|
bool is_poly_specialized; \
|
||||||
|
bool has_proc_default_values; \
|
||||||
isize specialization_count; \
|
isize specialization_count; \
|
||||||
ProcCallingConvention calling_convention; \
|
ProcCallingConvention calling_convention; \
|
||||||
}) \
|
}) \
|
||||||
|
|||||||
Reference in New Issue
Block a user