};
}
-from_array :: (arr: [..] $T) -> Iterator(^T) {
- return from_slice((#type [] T).{ arr.data, arr.count });
-}
+from_array :: #match {
+ (arr: [..] $T) -> Iterator(^T) {
+ return from_slice((#type [] T).{ arr.data, arr.count });
+ },
+
+ (arr: [] $T) -> Iterator(^T) {
+ Context :: struct (T: type_expr) {
+ data: ^T;
+ count: u32;
+ current: u32;
+ }
-from_slice :: (arr: [] $T) -> Iterator(^T) {
- Context :: struct (T: type_expr) {
- data: ^T;
- count: u32;
- current: u32;
- }
+ c := make(#type Context(T));
+ c.data = arr.data;
+ c.count = arr.count;
+ c.current = 0;
- c := make(#type Context(T));
- c.data = arr.data;
- c.count = arr.count;
- c.current = 0;
+ next :: ($T: type_expr, use _: ^Context(T)) -> (^T, bool) {
+ if current < count {
+ defer current += 1;
+ return ^data[current], true;
- next :: ($T: type_expr, use _: ^Context(T)) -> (^T, bool) {
- if current < count {
- defer current += 1;
- return ^data[current], true;
+ } else {
+ return null, false;
+ }
+ }
- } else {
- return null, false;
+ close :: (data: rawptr) {
+ cfree(data);
}
- }
- close :: (data: rawptr) {
- cfree(data);
+ return .{
+ data = c,
+ next = #solidify next { T = T },
+ close = close,
+ };
}
-
- return .{
- data = c,
- next = #solidify next { T = T },
- close = close,
- };
}
fold :: (it: Iterator($T), initial_value: R, combine: (T, $R) -> R) -> R {
};
struct AstSolidifiedFunction {
+ b32 header_complete: 1;
+ b32 body_complete: 1;
+
AstFunction* func;
Scope* poly_scope;
};
AstFunction* polymorphic_proc_build_only_header(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual);
void add_overload_option(bh_arr(OverloadOption)* poverloads, u64 precedence, AstTyped* overload);
-AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args);
+AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* args, b32* should_yield);
AstTyped* find_matching_overload_by_type(bh_arr(OverloadOption) overloads, Type* type);
void report_unable_to_match_overload(AstCall* call);
while (call->callee->kind == Ast_Kind_Alias) call->callee = ((AstAlias *) call->callee)->alias;
if (call->callee->kind == Ast_Kind_Overloaded_Function) {
- AstTyped* new_callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args);
+ b32 should_yield = 0;
+ AstTyped* new_callee = find_matching_overload_by_arguments(((AstOverloadedFunction *) call->callee)->overloads, &call->args, &should_yield);
if (new_callee == NULL) {
- if (call->callee->entity->state > Entity_State_Check_Types) {
+ if (call->callee->entity->state > Entity_State_Check_Types && !should_yield) {
report_unable_to_match_overload(call);
return Check_Error;
bh_arr_push(args.values, binop->left);
bh_arr_push(args.values, binop->right);
- AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args);
+ b32 should_yield = 0;
+ AstTyped* overload = find_matching_overload_by_arguments(operator_overloads[binop->operation], &args, &should_yield);
if (overload == NULL) {
bh_arr_free(args.values);
return NULL;
b32 header_only) {
AstSolidifiedFunction solidified_func;
+ solidified_func.header_complete = 0;
+ solidified_func.body_complete = 0;
// NOTE: Use the position of token if one was provided, otherwise just use NULL.
OnyxFilePos poly_scope_pos = { 0 };
ensure_polyproc_cache_is_created(pp);
+ AstSolidifiedFunction solidified_func;
+
char* unique_key = build_poly_slns_unique_key(slns);
if (bh_table_has(AstSolidifiedFunction, pp->concrete_funcs, unique_key)) {
- AstSolidifiedFunction solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key);
- return solidified_func.func;
+ solidified_func = bh_table_get(AstSolidifiedFunction, pp->concrete_funcs, unique_key);
+
+ } else {
+ // NOTE: This function is only going to have the header of it correctly created.
+ // Nothing should happen to this function's body or else the original will be corrupted.
+ // - brendanfh 2021/01/10
+ solidified_func = generate_solidified_function(pp, slns, NULL, 1);
}
- // NOTE: This function is only going to have the header of it correctly created.
- // Nothing should happen to this function's body or else the original will be corrupted.
- // - brendanfh 2021/01/10
- AstSolidifiedFunction solidified_func = generate_solidified_function(pp, slns, NULL, 1);
+ if (solidified_func.header_complete) return solidified_func.func;
Entity func_header_entity = {
.state = Entity_State_Resolve_Symbols,
return NULL;
}
+ solidified_func.header_complete = successful;
+
// NOTE: Cache the function for later use, only if it didn't have errors in its header.
bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func);
}
}
-AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args) {
+AstTyped* find_matching_overload_by_arguments(bh_arr(OverloadOption) overloads, Arguments* param_args, b32* should_yield) {
Arguments args;
arguments_clone(&args, param_args);
arguments_ensure_length(&args, bh_arr_length(args.values) + bh_arr_length(args.named_values));
// NOTE: Overload is not something that is known to be overloadable.
if (overload == NULL) continue;
if (overload->kind != Ast_Kind_Function) continue;
- if (overload->type == NULL) continue;
+ if (overload->type == NULL) {
+ // If it was not possible to create the type for this procedure, tell the
+ // caller that this should yield and try again later.
+ if (should_yield) *should_yield = 1;
+
+ // return and not continue because if the overload that didn't have a type will
+ // work in the future, then it has to take precedence over the other options available.
+ return NULL;
+ }
assert(overload->type->kind == Type_Kind_Function);
// NOTE: If the arguments cannot be placed successfully in the parameters list