@@ -67,11 +67,13 @@ def set_current_function -> &compiler::Function {
6767 ] !&compiler::Function
6868 compiler_state.function_stack.push(function)
6969 compiler_state.current_block = block
70-
7170 return function
7271}
7372
7473export def expr(node: &parser::Node, state: &typechecking::State) -> compiler::Value {
74+ let prev_queue = function_queue
75+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
76+
7577 if not node { return compiler::NO_VALUE }
7678 walk(node.parent, node, state)
7779 let previous_block = compiler_state.current_block
@@ -80,7 +82,10 @@ export def expr(node: &parser::Node, state: &typechecking::State) -> compiler::V
8082 walk(node.parent, node, state)
8183 var result = compiler::walk_expression(node, compiler_state)
8284 vector::insert(function.block.insn, 0, function.allocas)
83- let estate = eval::eval(compiler_state)
85+ let estate = compile_and_eval()
86+
87+ function_queue = prev_queue
88+
8489 result = eval::get_value(result, estate)
8590 compiler_state.function_stack.pop()
8691 compiler_state.current_block = previous_block
@@ -89,6 +94,10 @@ export def expr(node: &parser::Node, state: &typechecking::State) -> compiler::V
8994
9095export def boolean_expr(node: &parser::Node, state: &typechecking::State) -> compiler::Value {
9196 if not node { return compiler::NO_VALUE }
97+
98+ let prev_queue = function_queue
99+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
100+
92101 walk(node.parent, node, state)
93102 let previous_block = compiler_state.current_block
94103 let function = set_current_function()
@@ -97,7 +106,10 @@ export def boolean_expr(node: &parser::Node, state: &typechecking::State) -> com
97106 var result = compiler::walk_expression(node, compiler_state)
98107 result = compiler::convert_to(node, result, builtins::bool_, compiler_state)
99108 vector::insert(function.block.insn, 0, function.allocas)
100- let estate = eval::eval(compiler_state)
109+ let estate = compile_and_eval()
110+
111+ function_queue = prev_queue
112+
101113 result = eval::get_value(result, estate)
102114 compiler_state.function_stack.pop()
103115 compiler_state.current_block = previous_block
@@ -205,6 +217,9 @@ export def evaluate_parameter(node: &parser::Node, param: &parser::Node, tpe: ty
205217 // Set up temporary scope
206218 let prev_scope = compiler_state.module.scope
207219 let temp_scope = scope::enter_scope(state.module.scope)
220+
221+ let prev_queue = function_queue
222+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
208223
209224 compiler_state.scope = temp_scope
210225 let previous_block = compiler_state.current_block
@@ -213,11 +228,14 @@ export def evaluate_parameter(node: &parser::Node, param: &parser::Node, tpe: ty
213228 var result = compiler::walk_expression(param.value.param.value, compiler_state)
214229 vector::insert(function.block.insn, 0, function.allocas)
215230 let gvalue = compiler::make_global_value(result.tpe, "default_param", null, compiler_state)
216- let estate = eval::eval(compiler_state)
231+
232+ let estate = compile_and_eval()
233+ function_queue = prev_queue
234+
217235 result = eval::get_value(result, estate)
218236
219237 compiler_state.scope = prev_scope
220-
238+
221239 if result.kind != compiler::ValueKind::NULL {
222240 eval::set_value(gvalue, result, estate)
223241
@@ -435,6 +453,7 @@ export def walk_Def(node: &parser::Node, state: &typechecking::State) {
435453 test = test,
436454 imported = imported
437455 ] !&compiler::Function
456+ //print("Consteval: ", fdef.name, " ", function !*, "\n")
438457 node.value.def_.function = function
439458 }
440459 function.has_yield = has_yield
@@ -646,13 +665,18 @@ export def walk_top_VarDecl(node: &parser::Node, state: &typechecking::State) {
646665 walk(node, right(i), state)
647666 }
648667
668+ let previous_queue = function_queue
669+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
670+
649671 let previous_block = compiler_state.current_block
650672 let function = set_current_function()
651673 typechecking::walk_VarDecl(node, state, true)
652674 let assign = compiler::walk_top_VarDecl(node, compiler_state, true)
653675 compiler::walk_expression(assign, compiler_state)
654676 vector::insert(function.block.insn, 0, function.allocas)
655- eval::eval(compiler_state)
677+ compile_and_eval()
678+
679+ function_queue = previous_queue
656680
657681 for var i in 0..vector::length(left) {
658682 let n = left(i)
@@ -720,6 +744,9 @@ def walk_VarDecl(node: &parser::Node, state: &typechecking::State) {
720744 walk(node, right(i), state)
721745 }
722746
747+ let previous_queue = function_queue
748+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
749+
723750 let previous_block = compiler_state.current_block
724751 let function = set_current_function()
725752 typechecking::walk_VarDecl(node, state, true)
@@ -730,7 +757,10 @@ def walk_VarDecl(node: &parser::Node, state: &typechecking::State) {
730757
731758 compiler::walk_VarDecl(node, compiler_state, true)
732759 vector::insert(function.block.insn, 0, function.allocas)
733- let estate = eval::eval(compiler_state)
760+ let estate = compile_and_eval()
761+
762+ function_queue = previous_queue
763+
734764 let locals = eval::get_stack_frame(estate).locals
735765
736766 for var i in 0..vector::length(left) {
@@ -820,6 +850,54 @@ export def load_function(value: &scope::Value) {
820850 }
821851}
822852
853+ type QueueEntry = struct {
854+ node: &parser::Node
855+ }
856+
857+ var function_queue: &Map(typechecking::FunctionDef, QueueEntry)
858+
859+ def queue_function(node: &parser::Node, fdef: typechecking::FunctionDef) {
860+ if not function_queue {
861+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
862+ }
863+
864+ let entry = [
865+ node = node
866+ ] !QueueEntry
867+ function_queue(fdef) = entry
868+ }
869+
870+ var recursion_guard = false
871+ export def compile_queued_functions {
872+ if recursion_guard { return }
873+ if not function_queue { return }
874+
875+ recursion_guard = true
876+ let debug = toolchain::debug_sym
877+ toolchain::debug_sym = false
878+
879+ for var fdef in @function_queue.keys() {
880+ let entry = function_queue(fdef)
881+ let function = compiler::create_function(entry.node, fdef, entry.node.value.def_.body, entry.node.inner_scope, null, compiler_state, params = entry.node.value.def_.params)
882+
883+ if function and function.defer_functions {
884+ for var i in 0..vector::length(function.defer_functions) {
885+ let deferf = function.defer_functions(i)
886+ const_module.result.functions(deferf.name) = deferf
887+ }
888+ }
889+ }
890+
891+ toolchain::debug_sym = debug
892+ function_queue.clear()
893+ recursion_guard = false
894+ }
895+
896+ def compile_and_eval -> &eval::State {
897+ compile_queued_functions()
898+ return eval::eval(compiler_state)
899+ }
900+
823901// This function compiles a function that is called in constant evaluation
824902export def compile_function(value: &scope::Value, context: &scope::Scope, arguments: &Vector(typechecking::NamedParameter) = null) -> &scope::Value {
825903 load_function(value)
@@ -880,7 +958,8 @@ export def compile_function(value: &scope::Value, context: &scope::Scope, argume
880958 let state = typechecking::make_state(module)
881959 if not function.is_typechecked {
882960 if arguments and is_polymorph {
883- node = typechecking::walk_Def_with_type_argument(node, arguments, context, state)
961+ let scope2 = scope::enter_scope(context)
962+ node = typechecking::walk_Def_with_type_argument(node, arguments, scope2, state)
884963 function = node.value.def_.function
885964 compiler::predeclare_function(function, context, overwrite = true)
886965 const_module.result.functions(function.name) = function
@@ -900,17 +979,7 @@ export def compile_function(value: &scope::Value, context: &scope::Scope, argume
900979 //print("Creating function ", function.name, "\n")
901980
902981 // This is a bit ugly but what can we do
903- let debug = toolchain::debug_sym
904- toolchain::debug_sym = false
905- compiler::create_function(node, function.fdef, node.value.def_.body, node.inner_scope, null, compiler_state, params = node.value.def_.params)
906- toolchain::debug_sym = debug
907-
908- if function.defer_functions {
909- for var i in 0..vector::length(function.defer_functions) {
910- let deferf = function.defer_functions(i)
911- const_module.result.functions(deferf.name) = deferf
912- }
913- }
982+ queue_function(node, function.fdef)
914983
915984 compiler::create_dyn_dispatch(state.module.dyn_dispatch_consteval, state.module.compiler_state)
916985
@@ -1080,6 +1149,10 @@ def walk_Error(node: &parser::Node, state: &typechecking::State) {
10801149 is_static = true
10811150 walk(node, expr, state)
10821151
1152+
1153+ let prev_queue = function_queue
1154+ function_queue = map::make(typechecking::FunctionDef, QueueEntry)
1155+
10831156 let previous_block = compiler_state.current_block
10841157 let function = set_current_function()
10851158 typechecking::walk(node, expr, state)
@@ -1089,7 +1162,9 @@ def walk_Error(node: &parser::Node, state: &typechecking::State) {
10891162
10901163 var result = compiler::walk_expression(expr, compiler_state)
10911164 vector::insert(function.block.insn, 0, function.allocas)
1092- let estate = eval::eval(compiler_state)
1165+ let estate = compile_and_eval()
1166+ function_queue = prev_queue
1167+
10931168 result = eval::get_value(result, estate)
10941169 if not typechecking::equals(result.tpe, builtins::string_) {
10951170 errors::errorn(node, "Error pragma expects string, got ", debug::type_to_str(result.tpe))
0 commit comments