diff --git a/examples/test.lua b/examples/test.lua index b343c6c..c1d677a 100644 --- a/examples/test.lua +++ b/examples/test.lua @@ -4,5 +4,5 @@ function add(x) end end -local d = add(5) -global c = print(d()) \ No newline at end of file +local d = add(5 + 7) +global c = print(d() + 10) \ No newline at end of file diff --git a/src/ast.rs b/src/ast.rs index ec8f866..03f38b5 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -312,15 +312,17 @@ pub struct PrimaryExpression(Node); #[derive(Debug, Clone, Copy)] pub enum BinaryOperator { - Lt, + LessThan, Gt, + Add, } impl BinaryOperator { pub fn precedence(&self) -> u32 { match self { - BinaryOperator::Lt => 100, - BinaryOperator::Gt => 100, + BinaryOperator::LessThan => 10, + BinaryOperator::Gt => 10, + BinaryOperator::Add => 20, } } } @@ -403,8 +405,9 @@ impl Parse for BinaryOperator { fn parse(mut stream: TokenStream) -> Result { if let Some(token) = stream.next() { match token { - Token::Symbol('<') => Ok(BinaryOperator::Lt), + Token::Symbol('<') => Ok(BinaryOperator::LessThan), Token::Symbol('>') => Ok(BinaryOperator::Gt), + Token::Symbol('+') => Ok(BinaryOperator::Add), _ => Err(stream.expected_err("binop")), } } else { diff --git a/src/compile.rs b/src/compile.rs index ca6bda1..4423d71 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -1,7 +1,7 @@ use std::collections::{HashMap, HashSet}; use crate::{ - ast::{AccessModifier, Block, Expression, Literal, Statement}, + ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement}, vm::{Constant, Instruction, VMNumber}, }; @@ -164,8 +164,8 @@ impl Expression { ) -> (Vec, Vec) { match self { Expression::ValueRef(name) => { - if let Some(local) = scope.locals.get(name) { - (Vec::new(), vec![*local]) + if let Some(reg) = scope.locals.get(name) { + (Vec::new(), vec![*reg]) } else if let Some(upvalue) = scope.upvalues.get(name) { let local = scope.register_counter.next(); (vec![Instruction::GetUpVal(local, *upvalue)], vec![local]) @@ -179,7 +179,38 @@ impl Expression { (instructions, vec![reg]) } } - Expression::BinOp(binary_operator, node, node1) => todo!(), + Expression::BinOp(binary_operator, lhs, rhs) => { + let mut instructions = Vec::new(); + let (instr, lhs) = lhs.kind.compile(state, scope, 1); + instructions.extend(instr); + let (instr, rhs) = rhs.kind.compile(state, scope, 1); + instructions.extend(instr); + let reg = scope.register_counter.next(); + match binary_operator { + BinaryOperator::LessThan => { + instructions.push(Instruction::LessThan( + reg, + *lhs.get(0).unwrap(), + *rhs.get(0).unwrap(), + )); + } + BinaryOperator::Gt => { + instructions.push(Instruction::LessThan( + reg, + *rhs.get(0).unwrap(), + *lhs.get(0).unwrap(), + )); + } + BinaryOperator::Add => { + instructions.push(Instruction::Add( + reg, + *lhs.get(0).unwrap(), + *rhs.get(0).unwrap(), + )); + } + }; + (instructions, vec![reg]) + } Expression::FunctionDefinition(params, block) => { let mut inner_scope = Scope::default(); for param in params { @@ -214,12 +245,10 @@ impl Expression { let mut original_param_regs = Vec::new(); for param in params.kind.0.iter() { - let (instr, registers) = param.kind.compile(state, scope, 1); + let (instr, registers) = param.kind.compile(state, &mut scope.clone(), 1); instructions.extend(instr); original_param_regs.extend(registers); } - scope.register_counter.0 = *function_register + 1; - let mut param_regs = Vec::new(); for param_reg in original_param_regs { let new_reg = scope.register_counter.next(); diff --git a/src/vm.rs b/src/vm.rs index a3658ae..f256563 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -34,6 +34,10 @@ pub enum Instruction { GetGlobal(u16, u32), /// R(A) := U[B] GetUpVal(u16, u16), + /// R(A) := R(B) + R(C) + Add(u16, u16, u16), + /// R(A) := R(B) < R(C) + LessThan(u16, u16, u16), /// [func] [params.len()] [ret_regs.len()] /// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1)) Call(u16, u16, u16), @@ -57,6 +61,8 @@ impl Debug for Instruction { Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0), Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1), Instruction::Return(arg0, arg1) => write!(f, "RETURN {} {}", arg0, arg1), + Instruction::LessThan(arg0, arg1, arg2) => write!(f, "LE {} {} {}", arg0, arg1, arg2), + Instruction::Add(arg0, arg1, arg2) => write!(f, "ADD {} {} {}", arg0, arg1, arg2), } } } @@ -229,7 +235,8 @@ impl ClosureRunner { .clone(), ); } - match self.stack.get(func_reg).unwrap_or(&Value::Nil) { + let value = self.stack.get(func_reg).unwrap_or(&Value::Nil); + match value { Value::RustFunction(func) => { let ret_values = func.borrow_mut().execute(params); for i in 0..=(*ret_len - 2) { @@ -246,7 +253,12 @@ impl ClosureRunner { } self.inner = Some(Box::new(closure.run(params))); } - _ => panic!(), + _ => { + dbg!(&value); + for i in 0..=(*ret_len - 2) { + self.stack.insert(*func_reg + i, Value::Nil); + } + } } } Instruction::Close(_) => {} @@ -297,6 +309,16 @@ impl ClosureRunner { .clone(), ); } + Instruction::Add(res, lhs, rhs) => { + let lhs = self.stack.get(lhs).unwrap_or(&Value::Nil); + let rhs = self.stack.get(rhs).unwrap_or(&Value::Nil); + self.stack.insert(*res, lhs.add(rhs)); + } + Instruction::LessThan(res, lhs, rhs) => { + let lhs = self.stack.get(lhs).unwrap_or(&Value::Nil); + let rhs = self.stack.get(rhs).unwrap_or(&Value::Nil); + self.stack.insert(*res, lhs.lt(rhs)); + } }; self.program_counter += 1;