Add binops, fix function call codegen

This commit is contained in:
Sofia 2026-03-15 00:25:06 +02:00
parent 493664cafc
commit 08e9b00b5c
4 changed files with 69 additions and 15 deletions

View File

@ -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)

View File

@ -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 {

View File

@ -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();

View File

@ -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;