From 763d818c51056faae5280c4af9196afa71773bdc Mon Sep 17 00:00:00 2001 From: Sofia Date: Mon, 16 Mar 2026 16:16:53 +0200 Subject: [PATCH] Add equals --- src/ast.rs | 6 ++++++ src/compile.rs | 7 +++++++ src/vm.rs | 28 +++++++++++++++++++++++++++- 3 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/ast.rs b/src/ast.rs index 8db73a1..0948f67 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -324,6 +324,7 @@ pub enum BinaryOperator { LessThanOrEqual, GreaterThan, GreaterThanOrEqual, + Equal, Add, } @@ -334,6 +335,7 @@ impl BinaryOperator { BinaryOperator::LessThanOrEqual => 10, BinaryOperator::GreaterThan => 10, BinaryOperator::GreaterThanOrEqual => 10, + BinaryOperator::Equal => 10, BinaryOperator::Add => 20, } } @@ -425,6 +427,10 @@ impl Parse for BinaryOperator { stream.next(); Ok(BinaryOperator::GreaterThanOrEqual) } + (Token::Symbol('='), Some(Token::Symbol('='))) => { + stream.next(); + Ok(BinaryOperator::Equal) + } (Token::Symbol('<'), _) => Ok(BinaryOperator::LessThan), (Token::Symbol('>'), _) => Ok(BinaryOperator::GreaterThan), (Token::Symbol('+'), _) => Ok(BinaryOperator::Add), diff --git a/src/compile.rs b/src/compile.rs index 70e34fd..c565020 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -308,6 +308,13 @@ impl Expression { instructions.extend(instr); let reg = scope.register_counter.next(); match binary_operator { + BinaryOperator::Equal => { + instructions.push(Instruction::Equal( + reg, + *lhs.get(0).unwrap(), + *rhs.get(0).unwrap(), + )); + } BinaryOperator::LessThan => { instructions.push(Instruction::LessThan( reg, diff --git a/src/vm.rs b/src/vm.rs index 5621f4b..eae8c35 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -40,9 +40,11 @@ pub enum Instruction { SetUpVal(u16, u16), /// R(A) := R(B) + R(C) Add(u16, u16, u16), + /// R(A) := R(B) == R(C) + Equal(u16, u16, u16), /// R(A) := R(B) < R(C) LessThan(u16, u16, u16), - /// R(A) := R(B) < R(C) + /// R(A) := R(B) <= R(C) LessThanOrEqual(u16, u16, u16), /// PC += sAx Jmp(i32), @@ -74,6 +76,7 @@ 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::Equal(arg0, arg1, arg2) => write!(f, "EQ {} {} {}", 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) @@ -108,6 +111,16 @@ impl Value { } } + pub fn eq(&self, other: &Value) -> Value { + match (self, other) { + (Value::Number(lhs), Value::Number(rhs)) => { + let res = lhs == rhs; + Value::Number((res as u64 as f64).to_bits()) + } + _ => Value::Nil, + } + } + pub fn lt(&self, other: &Value) -> Value { match (self, other) { (Value::Number(lhs), Value::Number(rhs)) => { @@ -456,6 +469,19 @@ impl ClosureRunner { .unwrap_or(Value::Nil); self.set_stack(*res, lhs.add(&rhs)); } + Instruction::Equal(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.eq(&rhs)); + } Instruction::LessThan(res, lhs, rhs) => { let lhs = self .stack