diff --git a/src/compile.rs b/src/compile.rs index fa203b5..db50398 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -170,13 +170,19 @@ impl Expression { Expression::BinOp(binary_operator, node, node1) => todo!(), Expression::FunctionDefinition(nodes, block) => todo!(), Expression::FunctionCall(expr, params) => { - let function_register = scope.register_counter.next(); + let mut instructions = Vec::new(); + let (instr, registers) = expr.kind.compile(state, scope, 1); + instructions.extend(instr); + + let function_register = registers.first().unwrap(); let mut param_regs = Vec::new(); - for _ in 0..params.kind.0.len() { - param_regs.push(scope.register_counter.next()); + for param in params.kind.0.iter() { + let (instr, registers) = param.kind.compile(state, scope, 1); + instructions.extend(instr); + param_regs.extend(registers); } - let first_param_reg = param_regs.first().unwrap(); + let last_param_reg = param_regs.last().unwrap(); let mut return_regs = Vec::new(); @@ -189,26 +195,12 @@ impl Expression { } } - let mut instructions = Vec::new(); - let (instr, registers) = expr.kind.compile(state, scope, 1); - instructions.extend(instr); - instructions.push(Instruction::Move( - function_register, - *registers.first().unwrap(), - )); - - for (i, param) in params.kind.0.iter().enumerate() { - let (instr, registers) = param.kind.compile(state, scope, 1); - instructions.extend(instr); - instructions.push(Instruction::Move( - *first_param_reg + i as u16, - *registers.first().unwrap(), - )); - } + let last_return_reg = return_regs.last().unwrap(); + scope.register_counter.0 = *last_return_reg + 1; instructions.push(Instruction::Call( - function_register, - params.kind.0.len() as u16, + *function_register, + param_regs.len() as u16, return_regs.len() as u16 + 1, )); diff --git a/src/vm.rs b/src/vm.rs index f242f48..4439ab5 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -1,4 +1,4 @@ -use std::fmt::Debug; +use std::{cell::RefCell, collections::HashMap, fmt::Debug, rc::Rc}; use crate::ast::LuaNumber; @@ -48,3 +48,23 @@ impl Debug for Instruction { } } } + +#[derive(Debug, Clone)] +pub struct Environment { + pub globals: HashMap, +} + +#[derive(Debug, Clone)] +pub enum Value { + Number(VMNumber), + RustFunction(Rc>), +} + +pub trait RustFunction: Debug { + fn execute(&self, parameters: Vec) -> Vec; +} + +pub struct ClosureRunner { + pub environment: Rc>, + pub constants: Vec, +}