diff --git a/.gitignore b/.gitignore index 3602419..4571716 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,6 @@ /target .idea -*.iml \ No newline at end of file +*.iml + +*.snap.new \ No newline at end of file diff --git a/src/compile.rs b/src/compile.rs index 88c9423..e470d8b 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -109,6 +109,7 @@ pub fn compile<'ast, 'bc, 'gc>( impl<'bc, 'gc> Compiler<'bc, 'gc> { fn compile(&mut self, ast: &Program) -> CResult { let global_block = FnBlock { + name: self.rt.intern_string("
"), code: Vec::new_in(self.bump), stack_sizes: Vec::new_in(self.bump), spans: Vec::new_in(self.bump), @@ -188,6 +189,7 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { fn compile_fn_decl(&mut self, decl: &FnDecl) -> CResult { let block = FnBlock { + name: decl.name.sym, code: Vec::new_in(self.bump), stack_sizes: Vec::new_in(self.bump), spans: Vec::new_in(self.bump), @@ -480,7 +482,14 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { } self.push_instr(Instr::Load(offset), StackChange::Grow, call.span); - self.push_instr(Instr::Call, StackChange::None, call.span); + // The callee gets rid of the params. We also pushed the load for the function above, + // but the callee also leaves behind a return value. + let expected_stack_shrink = params.len(); + self.push_instr( + Instr::Call, + StackChange::ShrinkN(expected_stack_shrink), + call.span, + ); Ok(()) } diff --git a/src/runtime/bytecode.rs b/src/runtime/bytecode.rs index 4043aa7..b583ef6 100644 --- a/src/runtime/bytecode.rs +++ b/src/runtime/bytecode.rs @@ -29,10 +29,14 @@ use std::fmt::{Debug, Formatter}; use bumpalo::collections::Vec; -use crate::{errors::Span, runtime::vm::Value}; +use crate::{ + errors::Span, + runtime::{gc::Symbol, vm::Value}, +}; /// This struct contains all data for a function. pub struct FnBlock<'bc> { + pub name: Symbol, /// The bytecode of the function pub code: Vec<'bc, Instr>, /// The sizes of the stack required by the function after the instruction at the same index. @@ -111,6 +115,7 @@ pub enum Instr { impl dbg_pls::DebugPls for FnBlock<'_> { fn fmt(&self, f: dbg_pls::Formatter<'_>) { f.debug_struct("FnBlock") + .field("name", &self.name) .field("arity", &self.arity) .field("code", &self.code.as_slice()) .field("stack_sizes", &self.stack_sizes.as_slice()) diff --git a/src/runtime/stack_frame.rs b/src/runtime/stack_frame.rs index 68b7b43..535164e 100644 --- a/src/runtime/stack_frame.rs +++ b/src/runtime/stack_frame.rs @@ -58,7 +58,7 @@ impl<'s> Frame<'s> { vm_state.stack.push(Value::NativeU(old_pc)); vm_state.stack.push(Value::Function(old_fn_block)); - let frame_slice = &vm_state.stack[new_frame_offset..]; + // let frame_slice = &vm_state.stack[new_frame_offset..]; new_frame_offset } diff --git a/test.dil b/test.dil index b6e6c52..002519d 100644 --- a/test.dil +++ b/test.dil @@ -1,12 +1,15 @@ -fn test() { - let a = 5; +fn cooler_add(a, b) { + return a + b; } -test(); -test(); - -let i = 0; -while i < 100_000 { - test(); - i = i + 1; +fn add(a, b) { + return cooler_add(a, b); } + +let added = add(1, 5); + +if added == 6 { + print "correct"; +} else { + print "FAILED"; +} \ No newline at end of file diff --git a/tests/functions.rs b/tests/functions.rs index 29d2ddc..ab7a6a5 100644 --- a/tests/functions.rs +++ b/tests/functions.rs @@ -43,7 +43,6 @@ print "correct3"; ); run_test!( - #[ignore] parameters, r#" fn fancy_print(str) { @@ -67,7 +66,6 @@ print x; ); run_test!( - #[ignore] parameters_and_return, r#" fn add(a, b) { @@ -84,6 +82,28 @@ if added == 6 { "# ); +run_test!( + #[ignore] + nested_calls, + r#" +fn cooler_add(a, b) { + return a + b; +} + +fn add(a, b) { + return cooler_add(a, b); +} + +let added = add(1, 5); + +if added == 6 { + print "correct"; +} else { + print "FAILED"; +} +"# +); + run_test!( #[ignore] fib5, diff --git a/tests/snapshots/functions__parameters.snap b/tests/snapshots/functions__parameters.snap new file mode 100644 index 0000000..ebc0dc2 --- /dev/null +++ b/tests/snapshots/functions__parameters.snap @@ -0,0 +1,5 @@ +--- +source: tests/functions.rs +expression: output +--- +"correct\n" diff --git a/tests/snapshots/functions__parameters_and_return.snap b/tests/snapshots/functions__parameters_and_return.snap new file mode 100644 index 0000000..ebc0dc2 --- /dev/null +++ b/tests/snapshots/functions__parameters_and_return.snap @@ -0,0 +1,5 @@ +--- +source: tests/functions.rs +expression: output +--- +"correct\n"