Add LE/GE

This commit is contained in:
Sofia 2026-03-16 16:13:11 +02:00
parent 130cb2763b
commit 22d7a323af
3 changed files with 62 additions and 8 deletions

View File

@ -321,7 +321,9 @@ pub struct PrimaryExpression(Node<Expression>);
#[derive(Debug, Clone, Copy)]
pub enum BinaryOperator {
LessThan,
Gt,
LessThanOrEqual,
GreaterThan,
GreaterThanOrEqual,
Add,
}
@ -329,7 +331,9 @@ impl BinaryOperator {
pub fn precedence(&self) -> u32 {
match self {
BinaryOperator::LessThan => 10,
BinaryOperator::Gt => 10,
BinaryOperator::LessThanOrEqual => 10,
BinaryOperator::GreaterThan => 10,
BinaryOperator::GreaterThanOrEqual => 10,
BinaryOperator::Add => 20,
}
}
@ -412,10 +416,18 @@ fn parse_binop_rhs(
impl Parse for BinaryOperator {
fn parse(mut stream: TokenStream) -> Result<Self, TokenStreamError> {
if let Some(token) = stream.next() {
match token {
Token::Symbol('<') => Ok(BinaryOperator::LessThan),
Token::Symbol('>') => Ok(BinaryOperator::Gt),
Token::Symbol('+') => Ok(BinaryOperator::Add),
match (token, stream.peek()) {
(Token::Symbol('<'), Some(Token::Symbol('='))) => {
stream.next();
Ok(BinaryOperator::LessThanOrEqual)
}
(Token::Symbol('>'), Some(Token::Symbol('='))) => {
stream.next();
Ok(BinaryOperator::GreaterThanOrEqual)
}
(Token::Symbol('<'), _) => Ok(BinaryOperator::LessThan),
(Token::Symbol('>'), _) => Ok(BinaryOperator::GreaterThan),
(Token::Symbol('+'), _) => Ok(BinaryOperator::Add),
_ => Err(stream.expected_err("binop")),
}
} else {

View File

@ -315,13 +315,27 @@ impl Expression {
*rhs.get(0).unwrap(),
));
}
BinaryOperator::Gt => {
BinaryOperator::LessThanOrEqual => {
instructions.push(Instruction::LessThanOrEqual(
reg,
*lhs.get(0).unwrap(),
*rhs.get(0).unwrap(),
));
}
BinaryOperator::GreaterThan => {
instructions.push(Instruction::LessThan(
reg,
*rhs.get(0).unwrap(),
*lhs.get(0).unwrap(),
));
}
BinaryOperator::GreaterThanOrEqual => {
instructions.push(Instruction::LessThanOrEqual(
reg,
*rhs.get(0).unwrap(),
*lhs.get(0).unwrap(),
));
}
BinaryOperator::Add => {
instructions.push(Instruction::Add(
reg,

View File

@ -42,6 +42,8 @@ pub enum Instruction {
Add(u16, u16, u16),
/// R(A) := R(B) < R(C)
LessThan(u16, u16, u16),
/// R(A) := R(B) < R(C)
LessThanOrEqual(u16, u16, u16),
/// PC += sAx
Jmp(i32),
/// if (R(B) <=> C) then R(A) := R(B) else PC++
@ -72,7 +74,10 @@ 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::LessThan(arg0, arg1, arg2) => write!(f, "LT {} {} {}", arg0, arg1, arg2),
Instruction::LessThanOrEqual(arg0, arg1, arg2) => {
write!(f, "LE {} {} {}", arg0, arg1, arg2)
}
Instruction::Add(arg0, arg1, arg2) => write!(f, "ADD {} {} {}", arg0, arg1, arg2),
Instruction::LoadNil(arg0, arg1) => write!(f, "LOADNIL {} {}", arg0, arg1),
}
@ -112,6 +117,16 @@ impl Value {
_ => Value::Nil,
}
}
pub fn lte(&self, other: &Value) -> Value {
match (self, other) {
(Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) <= LuaNumber::from_bits(*rhs);
Value::Number((res as u64 as f64).to_bits())
}
_ => Value::Nil,
}
}
}
impl Debug for Value {
@ -454,6 +469,19 @@ impl ClosureRunner {
.unwrap_or(Value::Nil);
self.set_stack(*res, lhs.lt(&rhs));
}
Instruction::LessThanOrEqual(res, lhs, rhs) => {
let lhs = self
.stack
.get(lhs)
.map(|v| v.borrow().clone())
.unwrap_or(Value::Nil);
let rhs = self
.stack
.get(rhs)
.map(|v| v.borrow().clone())
.unwrap_or(Value::Nil);
self.set_stack(*res, lhs.lte(&rhs));
}
};
self.program_counter += 1;