Add binops, fix function call codegen
This commit is contained in:
parent
493664cafc
commit
08e9b00b5c
@ -4,5 +4,5 @@ function add(x)
|
||||
end
|
||||
end
|
||||
|
||||
local d = add(5)
|
||||
global c = print(d())
|
||||
local d = add(5 + 7)
|
||||
global c = print(d() + 10)
|
||||
11
src/ast.rs
11
src/ast.rs
@ -312,15 +312,17 @@ pub struct PrimaryExpression(Node<Expression>);
|
||||
|
||||
#[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<Self, TokenStreamError> {
|
||||
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 {
|
||||
|
||||
@ -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<Instruction>, Vec<u16>) {
|
||||
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();
|
||||
|
||||
26
src/vm.rs
26
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;
|
||||
|
||||
Loading…
Reference in New Issue
Block a user