filter_iterator.iterator = it;
filter_iterator.predicate = predicate;
- next :: ($T: type_expr, fi: ^FilterIterator(T)) -> (T, bool) {
+ next :: (fi: ^FilterIterator($T)) -> (T, bool) {
value, cont := fi.iterator.next(fi.iterator.data);
if cont {
while !fi.predicate(value) {
}
}
- close :: ($T: type_expr, fi: ^FilterIterator(T)) {
+ close :: (fi: ^FilterIterator($T)) {
if fi.iterator.close != null_proc do fi.iterator.close(fi.iterator.data);
cfree(fi);
}
map_iterator.iterator = it;
map_iterator.transform = transform;
- next :: ($T: type_expr, $R: type_expr, mi: ^MapIterator(T, R)) -> (R, bool) {
+ next :: (mi: ^MapIterator($T, $R)) -> (R, bool) {
value, cont := mi.iterator.next(mi.iterator.data);
if !cont do return __zero_value(R), false;
return mi.transform(value), true;
}
- close :: ($T: type_expr, $R: type_expr, mi: ^MapIterator(T, R)) {
+ close :: (mi: ^MapIterator($T, $R)) {
if mi.iterator.close != null_proc do mi.iterator.close(mi.iterator.data);
cfree(mi);
}
char* name;
-
// NOTE: This is NULL, unless this function was generated from a polymorphic
// procedure call. Then it is set to the token of the call node.
OnyxToken* generated_from;
if (func->flags & Ast_Flag_Has_Been_Checked) return Check_Success;
if (func->entity_header && func->entity_header->state < Entity_State_Code_Gen)
YIELD(func->token->pos, "Waiting for procedure header to pass type-checking");
-
+
expected_return_type = &func->type->Function.return_type;
if (func->body) {
CheckStatus status = check_block(func->body);
break;
case Ast_Kind_Call:
+ C(AstCall, callee);
arguments_deep_clone(a, &((AstCall *) nn)->args, &((AstCall *) node)->args);
break;
AstFunction* sf = (AstFunction *) node;
if (sf->is_foreign) return node;
+ assert(df->scope == NULL);
df->return_type = (AstType *) ast_clone(a, sf->return_type);
df->body = (AstBlock *) ast_clone(a, sf->body);
AstFunction* new_func = onyx_ast_node_new(a, sizeof(AstFunction), func->kind);
memmove(new_func, func, sizeof(AstFunction));
+ assert(new_func->scope == NULL);
new_func->return_type = (AstType *) ast_clone(a, func->return_type);
AstTyped node_that_signals_a_yield = { Ast_Kind_Function, 0 };
static void ensure_polyproc_cache_is_created(AstPolyProc* pp) {
- if (pp->concrete_funcs == NULL) {
- bh_table_init(global_heap_allocator, pp->concrete_funcs, 16);
-
- bh_imap_init(&pp->active_queries, global_heap_allocator, 31);
- }
+ if (pp->concrete_funcs == NULL) bh_table_init(global_heap_allocator, pp->concrete_funcs, 16);
+ if (pp->active_queries.hashes == NULL) bh_imap_init(&pp->active_queries, global_heap_allocator, 31);
}
void insert_poly_sln_into_scope(Scope* scope, AstPolySolution *sln) {
// NOTE: This function adds a solidified function to the entity heap for it to be processed
// later. It optionally can start the function header entity at the code generation state if
// the header has already been processed.
-static b32 add_solidified_function_entities(AstSolidifiedFunction solidified_func) {
- solidified_func.func->flags |= Ast_Flag_Function_Used;
- solidified_func.func->flags |= Ast_Flag_From_Polymorphism;
+static b32 add_solidified_function_entities(AstSolidifiedFunction *solidified_func) {
+ solidified_func->func->flags |= Ast_Flag_Function_Used;
+ solidified_func->func->flags |= Ast_Flag_From_Polymorphism;
Entity func_header_entity = {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Function_Header,
- .function = solidified_func.func,
+ .function = solidified_func->func,
.package = NULL,
- .scope = solidified_func.func->poly_scope,
+ .scope = solidified_func->func->poly_scope,
};
Entity func_entity = {
.state = Entity_State_Resolve_Symbols,
.type = Entity_Type_Function,
- .function = solidified_func.func,
+ .function = solidified_func->func,
.package = NULL,
- .scope = solidified_func.func->poly_scope,
+ .scope = solidified_func->func->poly_scope,
};
Entity* entity_header = entity_heap_insert(&context.entities, func_header_entity);
Entity* entity_body = entity_heap_insert(&context.entities, func_entity);
- solidified_func.func_header_entity = entity_header;
- solidified_func.func->entity_header = entity_header;
- solidified_func.func->entity_body = entity_body;
+ solidified_func->func_header_entity = entity_header;
+ solidified_func->func->entity_header = entity_header;
+ solidified_func->func->entity_body = entity_body;
return 1;
}
return solidified_func;
}
-static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFunction solidified_func) {
- if (solidified_func.func->flags & Ast_Flag_Incomplete_Body) {
- clone_function_body(context.ast_alloc, solidified_func.func, pp->base_func);
+static void ensure_solidified_function_has_body(AstPolyProc* pp, AstSolidifiedFunction *solidified_func) {
+ if (solidified_func->func->flags & Ast_Flag_Incomplete_Body) {
+ clone_function_body(context.ast_alloc, solidified_func->func, pp->base_func);
// HACK: I'm asserting that this function should return without an error, because
// the only case where it can return an error is if there was a problem with the
// procedure.
assert(add_solidified_function_entities(solidified_func));
- solidified_func.func->flags &= ~Ast_Flag_Incomplete_Body;
+ solidified_func->func->flags &= ~Ast_Flag_Incomplete_Body;
}
}
// solving for the polymorphic variables, in order to return an array of the solutions for all
// of the polymorphic variables.
static bh_arr(AstPolySolution) find_polymorphic_slns(AstPolyProc* pp, PolyProcLookupMethod pp_lookup, ptr actual, OnyxToken *tkn, b32 necessary) {
+ ensure_polyproc_cache_is_created(pp);
if (bh_imap_has(&pp->active_queries, (u64) actual)) {
AstPolyQuery *query = (AstPolyQuery *) bh_imap_get(&pp->active_queries, (u64) actual);
assert(query->kind == Ast_Kind_Polymorph_Query);
query->slns = slns;
query->function_header = clone_function_header(context.ast_alloc, pp->base_func);
query->function_header->flags |= Ast_Flag_Header_Check_No_Error;
+ query->function_header->scope = NULL;
query->error_on_fail = necessary;
query->successful_symres = 1;
// NOTE: If this solution was originally created from a "build_only_header" call, then the body
// will not have been or type checked, or anything. This ensures that the body is copied, the
// entities are created and entered into the pipeline.
- ensure_solidified_function_has_body(pp, solidified_func);
+ ensure_solidified_function_has_body(pp, &solidified_func);
// NOTE: Again, if this came from a "build_only_header" call, then there was no known token and
// the "generated_from" member will be null. It is best to set it here so errors reported in that
}
AstSolidifiedFunction solidified_func = generate_solidified_function(pp, slns, tkn, 0);
+ add_solidified_function_entities(&solidified_func);
// NOTE: Cache the function for later use, reducing duplicate functions.
bh_table_put(AstSolidifiedFunction, pp->concrete_funcs, unique_key, solidified_func);
- add_solidified_function_entities(solidified_func);
-
return (AstFunction *) &node_that_signals_a_yield;
}
// made it through the symbol resolution phase.
// - brendanfh 2020/12/25
AstPolyProc* new_pp = onyx_ast_node_new(context.ast_alloc, sizeof(AstPolyProc), Ast_Kind_Polymorphic_Proc);
- new_pp->token = pp->token; // TODO: Change this to be the solidify->token
+ new_pp->token = tkn;
new_pp->base_func = pp->base_func;
new_pp->flags = pp->flags;
new_pp->poly_params = pp->poly_params;
bh_arr_each(AstParam, param, func->params) {
symbol_introduce(curr_scope, param->local->token, (AstNode *) param->local);
-
+
if (param->local->type_node != NULL) {
SYMRES(type, ¶m->local->type_node);
}
}
SymresStatus symres_function(AstFunction* func) {
- if (func->scope == NULL)
- func->scope = scope_create(context.ast_alloc, curr_scope, func->token->pos);
if (func->entity_header && func->entity_header->state < Entity_State_Check_Types) return Symres_Yield_Macro;
+ assert(func->scope);
scope_enter(func->scope);
}
void symres_entity(Entity* ent) {
- Scope* old_scope = NULL;
- if (ent->scope) {
- old_scope = curr_scope;
- scope_enter(ent->scope);
- }
+ if (ent->scope) scope_enter(ent->scope);
report_unresolved_symbols = context.cycle_detected;
//(context.entities.type_count[Entity_Type_Static_If] == 0 &&
ent->state = next_state;
}
- if (ent->scope) curr_scope = old_scope;
+ curr_scope = NULL;
}
fori (idx, 0, mem_count) WIL(WI_LOCAL_GET, localidx + idx);
} else {
+ assert(localidx & LOCAL_IS_WASM);
WIL(WI_LOCAL_GET, localidx);
}
break;
}
case Param_Pass_By_Implicit_Pointer: {
+ assert(localidx & LOCAL_IS_WASM);
WIL(WI_LOCAL_GET, localidx);
emit_load_instruction(mod, &code, expr->type, 0);
break;
if (field->expr->kind == Ast_Kind_Param) {
if (type_get_param_pass(field->expr->type) == Param_Pass_By_Value && !type_is_pointer(field->expr->type)) {
u64 localidx = bh_imap_get(&mod->local_map, (u64) field->expr) + field->idx;
+ assert(localidx & LOCAL_IS_WASM);
WIL(WI_LOCAL_GET, localidx);
break;
}
Closing the count iterator...
-54
-56
-58
-60
-62
+54.0000
+56.0000
+58.0000
+60.0000
+62.0000
Starting the iteration...
54
56
use package core
-count_iterator :: (lo: i32, hi: i32, step := 1) -> Iterator(i32) {
- next :: (data: rawptr) -> (i32, bool) {
- ci := cast(^CountIterator) data;
+count_iterator :: (lo: $T, hi: T, step: T = 1) -> Iterator(T) {
+ next :: (ci: ^CountIterator($T)) -> (T, bool) {
if ci.current > ci.high do return 0, false;
defer ci.current += ci.step;
cfree(data);
}
- CountIterator :: struct {
- low, high, step: i32;
- current: i32;
+ CountIterator :: struct (T:type_expr) {
+ low, high, step: T;
+ current: T;
}
- count_iterator := new(CountIterator);
+ count_iterator := new(CountIterator(T));
count_iterator.low = lo;
count_iterator.high = hi;
count_iterator.step = step;
count_iterator.current = lo;
return .{
- data = count_iterator,
- next = next,
+ data = count_iterator,
+ next = #solidify next {T=T},
close = close,
};
}
main :: (args: [] cstr) {
// Hopefully soon, the following will be possible.
- quick_iterator :=
- count_iterator(1, 10)
- |> iter.map((x) => x * 2)
- |> iter.filter((x) => x > 10)
- |> iter.map((x) => x + 42)
- |> iter.take(5)
- |> iter.to_array();
-
- for v: quick_iterator {
- println(v);
+
+ {
+ quick_iterator :=
+ count_iterator(1.0f, 10.0f)
+ |> iter.map((x) => x * 2)
+ |> iter.filter((x) => x > 10)
+ |> iter.map((x) => x + 42)
+ |> iter.take(5)
+ |> iter.to_array();
+
+ for v: quick_iterator {
+ println(v);
+ }
}
iterator := count_iterator(1, 10)