Skip to content

Commit da09744

Browse files
committed
Fix some stuff, broke some other stuff
1 parent c9fa651 commit da09744

File tree

6 files changed

+222
-79
lines changed

6 files changed

+222
-79
lines changed

src/compiler.pr

Lines changed: 16 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3100,6 +3100,10 @@ def walk_Call(node: &parser::Node, state: &State) -> Value {
31003100
}
31013101
}
31023102
if not tpe {
3103+
debug::trace("Error: Could not determine type of function call `" + (
3104+
parser::identifier_to_str(left) if left.kind == parser::NodeKind::IDENTIFIER else to_str("unknown")
3105+
) + "` " + node.module.module + "@" + node.loc.line
3106+
)
31033107
return NO_VALUE
31043108
}
31053109

@@ -7171,6 +7175,10 @@ export def insert_function(module: &toolchain::Module, function: &Function, over
71717175

71727176
export def predeclare_function(fdef: typechecking::FunctionDef, module: &toolchain::Module) -> &Function {
71737177
let fun_name = fdef.name
7178+
if typechecking::is_polymorph(fdef) {
7179+
error("Cannot predeclare polymorphic function ", fun_name, "\n")
7180+
return null
7181+
}
71747182
var function = module.result.functions.get_or_default(fun_name, null)
71757183
if function {
71767184
return function
@@ -7179,6 +7187,7 @@ export def predeclare_function(fdef: typechecking::FunctionDef, module: &toolcha
71797187
fdef = fdef,
71807188
module = module
71817189
] !&Function
7190+
//print("Predeclaring function ", fun_name, " in module ", module.module, " ", function !*, "\n")
71827191
}
71837192
predeclare_function(function, module.scope)
71847193
return function
@@ -7482,17 +7491,18 @@ export def create_function(
74827491
no_cleanup: bool = false,
74837492
is_closure: bool = false,
74847493
params: &Vector(&Node) = null
7485-
) {
7494+
) -> &Function {
74867495
let function = state.module.result.functions.get_or_default(fdef.name, null)
7487-
if not function { return }
7496+
if not function { return null }
74887497
function.name = fdef.name
74897498
// TODO Return multiple values via tuple
7490-
if function.has_yield and (not function.ret or typechecking::is_tuple(function.ret)) { return }
7499+
if function.has_yield and (not function.ret or typechecking::is_tuple(function.ret)) { return null }
74917500
if not block {
74927501
block = make_block()
74937502
}
74947503

74957504
debug::trace("Compiling function " + function.name)
7505+
print(function !*, "\n")
74967506

74977507
function.forward_declare = false
74987508
function.allocas = vector::make(type &Insn)
@@ -7931,6 +7941,8 @@ export def create_function(
79317941
state.inline_start_block = previous_inline_start_block
79327942
errors::current_function = current_fun
79337943
errors::current_signature = current_signature
7944+
7945+
return function
79347946
}
79357947

79367948
def make_string(str: Str, state: &State) -> Value {
@@ -9195,6 +9207,7 @@ export def load_fun_load_types_function {
91959207
var lock = fun_load_types_rec_lock
91969208
fun_load_types_rec_lock = true
91979209
consteval::compile_function(fun_load_types, state.scope)
9210+
consteval::compile_queued_functions()
91989211
create_builtin_functions()
91999212
fun_load_types_rec_lock = lock
92009213
}

src/consteval.pr

Lines changed: 95 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -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

7473
export 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

9095
export 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
824902
export 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))

src/eval.pr

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -538,7 +538,12 @@ def eval_Alloca(insn: &compiler::Insn, state: &State) {
538538
let frame = get_stack_frame(state)
539539
let ret = insn.value.alloca.ret
540540

541-
let size = ret.tpe.resolve().size
541+
let tpe = ret.tpe.resolve()
542+
let size = tpe.size
543+
if tpe.size == 0 {
544+
errors::errorv("Error: allocating zero sized type `", debug::type_to_str(ret.tpe), "`\n")
545+
return
546+
}
542547
let mem = frame.mem.allocate(size) // TODO: We shouldn't have to initialize this
543548
ret.tpe = typechecking::pointer(ret.tpe)
544549
let ptr = [ kind = compiler::ValueKind::POINTER, tpe = ret.tpe, i = mem !int64 ] !compiler::Value
@@ -1026,6 +1031,9 @@ def eval_Call(insn: &compiler::Insn, state: &State) {
10261031
print("==========================\n")
10271032
}
10281033

1034+
if not function.block {
1035+
errors::errorv("Function `", function.name, "` has no body ")
1036+
}
10291037
eval(function.block, state)
10301038

10311039
if ret.tpe {

src/repl.pr

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -447,6 +447,8 @@ def execute(source: Str) {
447447
@mem = (*_args) !*
448448
stack_frame.locals("args.value") = mem
449449

450+
consteval::compile_queued_functions()
451+
450452
eval::push_stack_frame(stack_frame, estate)
451453
eval::eval(main_function.block, estate)
452454
eval::pop_stack_frame(estate)

0 commit comments

Comments
 (0)