From 64f3ffd2a838cc26b949d15aee5dbb8e8ce53a9c Mon Sep 17 00:00:00 2001 From: Nilstrieb <48135649+Nilstrieb@users.noreply.github.com> Date: Mon, 17 Jan 2022 15:31:23 +0100 Subject: [PATCH] f u n c t i o n --- src/compile.rs | 41 +++++++++++++++++++++++++++++++++++++---- src/vm.rs | 3 ++- test.dil | 6 ++---- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/src/compile.rs b/src/compile.rs index 622dde2..ef3989d 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -16,6 +16,8 @@ use std::rc::Rc; type CResult = Result; +const CALLCONV_OFFSET_DATA: usize = 3; + #[derive(Debug, PartialEq, Eq)] enum OuterEnvKind { Block, @@ -112,6 +114,13 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { self.current_block_idx = self.blocks.len() - 1; self.compile_fn_body(ast)?; + self.push_instr( + Instr::PushVal(Value::Null), + StackChange::Grow, + Span::dummy(), + ); + // exit the program. + self.push_instr(Instr::Return, StackChange::None, Span::dummy()); Ok(()) } @@ -198,9 +207,25 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { let inner_env = Env::new_inner(self.env.clone(), OuterEnvKind::Closure); self.env = inner_env; - // todo push params as locals + { + // insert params as locals + let mut env_mut = self.env.borrow_mut(); + for (i, param) in decl.params.iter().enumerate() { + env_mut.locals.insert(param.sym, i); + } - self.compile_fn_body(&decl.body)?; + let block = &mut self.blocks[self.current_block_idx]; + block.code.push(Instr::Nop); + block.spans.push(decl.span); + block + .stack_sizes + .push(decl.params.len() + CALLCONV_OFFSET_DATA); + } + + self.compile_stmts(&decl.body.stmts)?; + + self.push_instr(Instr::PushVal(Value::Null), StackChange::Grow, decl.span); + self.push_instr(Instr::Return, StackChange::None, decl.span); let outer = self.env.borrow().outer.clone().expect("outer env got lost"); self.env = outer; @@ -331,8 +356,16 @@ impl<'bc, 'gc> Compiler<'bc, 'gc> { Ok(()) } - fn compile_return(&mut self, _: &Option, _: Span) -> CResult { - todo!() + fn compile_return(&mut self, expr: &Option, span: Span) -> CResult { + if let Some(expr) = expr { + self.compile_expr(expr)?; + } else { + self.push_instr(Instr::PushVal(Value::Null), StackChange::Grow, span); + } + + self.push_instr(Instr::Return, StackChange::None, span); + + Ok(()) } fn compile_print(&mut self, expr: &Expr, span: Span) -> CResult { diff --git a/src/vm.rs b/src/vm.rs index 7db04b4..427bfb4 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -192,7 +192,8 @@ impl<'bc> Vm<'bc, '_> { } Instr::Jmp(pos) => self.pc = (self.pc as isize + pos) as usize, Instr::Call => self.call()?, - Instr::Return => todo!(), + // todo implement + Instr::Return => return Ok(()), Instr::ShrinkStack(size) => { assert!(self.stack.len() >= size); let new_len = self.stack.len() - size; diff --git a/test.dil b/test.dil index 4462d5f..7091b02 100644 --- a/test.dil +++ b/test.dil @@ -1,5 +1,3 @@ -let i = 0; - -while i < 100_000_000 { - i = i + 1; +fn test(uwu) { + let owo = 5; } \ No newline at end of file