From d10b3681ae848ce61521edee2726f0721969afcc Mon Sep 17 00:00:00 2001 From: Vic Nightfall Date: Wed, 20 Mar 2024 18:28:33 +0100 Subject: [PATCH] Fix #4 --- src/codegen.pr | 2 +- src/compiler.pr | 1 + src/consteval.pr | 1 + src/eval.pr | 19 ++++++++++++------- src/main.pr | 3 +++ src/repl.pr | 6 ++++++ src/toolchain.pr | 5 +++++ src/typechecking.pr | 7 +++++++ 8 files changed, 36 insertions(+), 8 deletions(-) diff --git a/src/codegen.pr b/src/codegen.pr index aadd1f18..14f7742d 100644 --- a/src/codegen.pr +++ b/src/codegen.pr @@ -490,7 +490,7 @@ def emit_switch(fp: File, insn: &compiler::Insn) { fprint(fp, "\t]") } -def emit(fp: File, insn: &compiler::Insn) { +export def emit(fp: File, insn: &compiler::Insn) { fprint(fp, "\t") switch (@insn).kind !int { case compiler::InsnKind::FNEG diff --git a/src/compiler.pr b/src/compiler.pr index ed017c3b..76bcd8e1 100644 --- a/src/compiler.pr +++ b/src/compiler.pr @@ -808,6 +808,7 @@ def push_alloca(insn: &Insn, state: &State, no_yield_capture: bool = false) { let ret = insn.value.alloca.ret let index = current_function.all_locals.size !int + 1 push_local_var(ret.name, ret.tpe, current_function) + ret.tpe = pointer(ret.tpe) let gep = make_insn(InsnKind::GETELEMENTPTR) gep.value.gep = [ diff --git a/src/consteval.pr b/src/consteval.pr index a56ba500..7fd8fadd 100644 --- a/src/consteval.pr +++ b/src/consteval.pr @@ -21,6 +21,7 @@ export let const_module = toolchain::make_module( node = null, scpe = scope::enter_function_scope(builtins::builtins, null), ) +const_module.delayed_compile = vector::make(type &parser::Node) export var is_static = false // This is for compiling expressions diff --git a/src/eval.pr b/src/eval.pr index 51bdc66a..ae8f6f5c 100644 --- a/src/eval.pr +++ b/src/eval.pr @@ -991,14 +991,16 @@ def eval_Call(insn: &compiler::Insn, state: &State) { push_stack_frame(stack_frame, state) - /*print(function.name, "\n") - print("==========================\n") - var block = function.block - while block { - codegen::emit_block(std::stdout(), block) - block = block.next + /*if toolchain::trace_consteval { + print(function.name, "\n") + print("==========================\n") + var block = function.block + while block { + codegen::emit_block(std::stdout(), block) + block = block.next + } }*/ - + eval(function.block, state) if ret.tpe { @@ -1101,6 +1103,9 @@ def eval_Inttoptr(insn: &compiler::Insn, state: &State) { } def eval_insn(insn: &compiler::Insn, state: &State) { + if toolchain::trace_consteval { + codegen::emit(std::stdout(), insn) + } switch insn.kind !int { case compiler::InsnKind::INSERTVALUE eval_InsertValue(insn, state) diff --git a/src/main.pr b/src/main.pr index ba4fd198..9788ede7 100644 --- a/src/main.pr +++ b/src/main.pr @@ -88,6 +88,8 @@ let options = [ .set_metavar("NAME")), (option(*toolchain::no_stdlib, "--no-stdlib") .set_help("Compile without importing std")), + (option(*toolchain::trace_consteval, "--trace-consteval") + .set_help("Trace code generated for consteval")), (option(*filename, "compile") .set_help("File to compile") .set_metavar("FILE")) @@ -111,6 +113,7 @@ if language_server { } if not filename { + toolchain::is_in_repl = true repl::run() exit(0) } diff --git a/src/repl.pr b/src/repl.pr index 9580ee99..d9c9f186 100644 --- a/src/repl.pr +++ b/src/repl.pr @@ -409,6 +409,12 @@ def execute(source: Str) { map::remove(module.result.functions, "const::__main__::([[char]])") compiler::compile(cstate, true, true) + // Compile delayed functions + for var n in consteval::const_module.delayed_compile { + compiler::create_function(n, n.tpe, n.value.def_.body, n.inner_scope, null, consteval::const_module.compiler_state) + } + consteval::const_module.delayed_compile = vector::make(type &parser::Node) + var estate = [ cstate = toolchain::types_state, stack = vector::make(type &eval::StackFrame) diff --git a/src/toolchain.pr b/src/toolchain.pr index 031f362b..ee117c48 100644 --- a/src/toolchain.pr +++ b/src/toolchain.pr @@ -81,12 +81,14 @@ export var link_libraries = vector::make(Str) export var link_flags = vector::make(Str) export var rdynamic = false +export var trace_consteval = false export var dependency_graph = false export var no_incremental = false // This is so that new entries don't depend on modules that are already collected export var no_dependency_tracking = false export var is_shared = false export var no_stdlib = false +export var is_in_repl = false let include: Str = util::exe_folder() + "/../include" let stdlib: Str = util::exe_folder() + "/../std" @@ -240,6 +242,9 @@ export type Module = struct { // We keep track of interface implementations for this module interfaces: &Map(&typechecking::Type, &Map(&typechecking::Type, &typechecking::Type)) + // Only used by const_module, this contains nodes of functions which still need to be compiled + // This is needed for the repl because we only compile the current module multiple times + delayed_compile: &Vector(&parser::Node) } export def get_impl(module: &Module, intf: &typechecking::Type, wrap: &typechecking::Type) -> &typechecking::Type { diff --git a/src/typechecking.pr b/src/typechecking.pr index 735b3129..e7f9d40d 100644 --- a/src/typechecking.pr +++ b/src/typechecking.pr @@ -6309,6 +6309,13 @@ export def walk_Def_with_type_argument(node: &parser::Node, parameter_t: &Vector // This makes sure that the function is walked by the compiler state.module.node.body.push(node) + + // Extra state for the repl + if toolchain::is_in_repl { + compiler::predeclare_function(function) + consteval::const_module.result.functions(node.tpe.type_name) = function + consteval::const_module.delayed_compile.push(node) + } if not in_context { super_scope.parent = builtins::builtins