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
end end
local d = add(5) local d = add(5 + 7)
global c = print(d()) global c = print(d() + 10)

View File

@ -312,15 +312,17 @@ pub struct PrimaryExpression(Node<Expression>);
#[derive(Debug, Clone, Copy)] #[derive(Debug, Clone, Copy)]
pub enum BinaryOperator { pub enum BinaryOperator {
Lt, LessThan,
Gt, Gt,
Add,
} }
impl BinaryOperator { impl BinaryOperator {
pub fn precedence(&self) -> u32 { pub fn precedence(&self) -> u32 {
match self { match self {
BinaryOperator::Lt => 100, BinaryOperator::LessThan => 10,
BinaryOperator::Gt => 100, BinaryOperator::Gt => 10,
BinaryOperator::Add => 20,
} }
} }
} }
@ -403,8 +405,9 @@ impl Parse for BinaryOperator {
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> { fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
if let Some(token) = stream.next() { if let Some(token) = stream.next() {
match token { match token {
Token::Symbol('<') => Ok(BinaryOperator::Lt), Token::Symbol('<') => Ok(BinaryOperator::LessThan),
Token::Symbol('>') => Ok(BinaryOperator::Gt), Token::Symbol('>') => Ok(BinaryOperator::Gt),
Token::Symbol('+') => Ok(BinaryOperator::Add),
_ => Err(stream.expected_err("binop")), _ => Err(stream.expected_err("binop")),
} }
} else { } else {

View File

@ -1,7 +1,7 @@
use std::collections::{HashMap, HashSet}; use std::collections::{HashMap, HashSet};
use crate::{ use crate::{
ast::{AccessModifier, Block, Expression, Literal, Statement}, ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement},
vm::{Constant, Instruction, VMNumber}, vm::{Constant, Instruction, VMNumber},
}; };
@ -164,8 +164,8 @@ impl Expression {
) -> (Vec<Instruction>, Vec<u16>) { ) -> (Vec<Instruction>, Vec<u16>) {
match self { match self {
Expression::ValueRef(name) => { Expression::ValueRef(name) => {
if let Some(local) = scope.locals.get(name) { if let Some(reg) = scope.locals.get(name) {
(Vec::new(), vec![*local]) (Vec::new(), vec![*reg])
} else if let Some(upvalue) = scope.upvalues.get(name) { } else if let Some(upvalue) = scope.upvalues.get(name) {
let local = scope.register_counter.next(); let local = scope.register_counter.next();
(vec![Instruction::GetUpVal(local, *upvalue)], vec![local]) (vec![Instruction::GetUpVal(local, *upvalue)], vec![local])
@ -179,7 +179,38 @@ impl Expression {
(instructions, vec![reg]) (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) => { Expression::FunctionDefinition(params, block) => {
let mut inner_scope = Scope::default(); let mut inner_scope = Scope::default();
for param in params { for param in params {
@ -214,12 +245,10 @@ impl Expression {
let mut original_param_regs = Vec::new(); let mut original_param_regs = Vec::new();
for param in params.kind.0.iter() { 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); instructions.extend(instr);
original_param_regs.extend(registers); original_param_regs.extend(registers);
} }
scope.register_counter.0 = *function_register + 1;
let mut param_regs = Vec::new(); let mut param_regs = Vec::new();
for param_reg in original_param_regs { for param_reg in original_param_regs {
let new_reg = scope.register_counter.next(); let new_reg = scope.register_counter.next();

View File

@ -34,6 +34,10 @@ pub enum Instruction {
GetGlobal(u16, u32), GetGlobal(u16, u32),
/// R(A) := U[B] /// R(A) := U[B]
GetUpVal(u16, u16), 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()] /// [func] [params.len()] [ret_regs.len()]
/// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1)) /// R(A), ... R(A+C-2) := R(A)(R(A+1), ... R(A+B-1))
Call(u16, u16, u16), Call(u16, u16, u16),
@ -57,6 +61,8 @@ impl Debug for Instruction {
Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0), Instruction::Close(arg0) => write!(f, "CLOSE {}", arg0),
Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1), Instruction::Closure(arg0, arg1) => write!(f, "CLOSURE {} {}", arg0, arg1),
Instruction::Return(arg0, arg1) => write!(f, "RETURN {} {}", 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(), .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) => { Value::RustFunction(func) => {
let ret_values = func.borrow_mut().execute(params); let ret_values = func.borrow_mut().execute(params);
for i in 0..=(*ret_len - 2) { for i in 0..=(*ret_len - 2) {
@ -246,7 +253,12 @@ impl ClosureRunner {
} }
self.inner = Some(Box::new(closure.run(params))); 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(_) => {} Instruction::Close(_) => {}
@ -297,6 +309,16 @@ impl ClosureRunner {
.clone(), .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; self.program_counter += 1;