From 215ffb298ef0b4675f9feb136f5ca95553a6825d Mon Sep 17 00:00:00 2001 From: Shautvast Date: Mon, 20 Oct 2025 21:14:22 +0200 Subject: [PATCH] comparisons --- src/chunk.rs | 8 +++++++- src/compiler.rs | 17 +++++++++++------ src/main.rs | 2 +- src/value.rs | 2 +- src/vm.rs | 7 ++++++- 5 files changed, 26 insertions(+), 10 deletions(-) diff --git a/src/chunk.rs b/src/chunk.rs index 8b4bf06..9b1e7e0 100644 --- a/src/chunk.rs +++ b/src/chunk.rs @@ -2,7 +2,8 @@ use tracing::debug; use crate::value::Value; use crate::vm::{ OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, - OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE, OP_NOT, OP_SHL, OP_SHR + OP_NEGATE, OP_RETURN, OP_SUBTRACT, OP_TRUE, OP_NOT, OP_SHL, OP_SHR, OP_LESS, OP_LESS_EQUAL, + OP_GREATER, OP_GREATER_EQUAL, OP_EQUAL }; pub struct Chunk { @@ -65,6 +66,11 @@ impl Chunk { OP_RETURN => self.simple_inst("RET", offset), OP_SHL => self.simple_inst("SHL", offset), OP_SHR => self.simple_inst("SHR", offset), + OP_LESS => self.simple_inst("LT", offset), + OP_LESS_EQUAL => self.simple_inst("LTE", offset), + OP_GREATER => self.simple_inst("GT", offset), + OP_GREATER_EQUAL => self.simple_inst("GTE", offset), + OP_EQUAL => self.simple_inst("EQ", offset), _ => { println!("Unknown instruction"); offset + 1 diff --git a/src/compiler.rs b/src/compiler.rs index 3e5582d..5f1f49d 100644 --- a/src/compiler.rs +++ b/src/compiler.rs @@ -2,7 +2,7 @@ use crate::chunk::Chunk; use crate::scanner::scan; use crate::tokens::{Token, TokenType}; use crate::value::Value; -use crate::vm::{OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_RETURN, OP_SHR, OP_SHL, OP_SUBTRACT, OP_TRUE}; +use crate::vm::{OP_ADD, OP_BITAND, OP_BITOR, OP_BITXOR, OP_CONSTANT, OP_DIVIDE, OP_FALSE, OP_MULTIPLY, OP_NEGATE, OP_NOT, OP_RETURN, OP_SHR, OP_SHL, OP_SUBTRACT, OP_TRUE, OP_EQUAL, OP_GREATER, OP_GREATER_EQUAL, OP_LESS, OP_LESS_EQUAL}; use anyhow::anyhow; use std::collections::HashMap; use std::sync::LazyLock; @@ -184,6 +184,11 @@ fn binary(s: &mut Compiler) -> anyhow::Result<()> { TokenType::BitXor => s.emit_byte(OP_BITXOR), TokenType::GreaterGreater => s.emit_byte(OP_SHR), TokenType::LessLess => s.emit_byte(OP_SHL), + TokenType::EqualEqual => s.emit_byte(OP_EQUAL), + TokenType::Greater => s.emit_byte(OP_GREATER), + TokenType::GreaterEqual => s.emit_byte(OP_GREATER_EQUAL), + TokenType::Less => s.emit_byte(OP_LESS), + TokenType::LessEqual => s.emit_byte(OP_LESS_EQUAL), _ => unimplemented!("binary other than plus, minus, star, slash"), } Ok(()) @@ -218,12 +223,12 @@ static RULES: LazyLock> = LazyLock::new(|| { rules.insert(TokenType::Bang, Rule::new(Some(unary), None, PREC_UNARY)); rules.insert(TokenType::BangEqual, Rule::new(None, None, PREC_NONE)); rules.insert(TokenType::Equal, Rule::new(None, None, PREC_NONE)); - rules.insert(TokenType::EqualEqual, Rule::new(None, None, PREC_NONE)); - rules.insert(TokenType::Greater, Rule::new(None, None, PREC_NONE)); - rules.insert(TokenType::GreaterEqual, Rule::new(None, None, PREC_NONE)); + rules.insert(TokenType::EqualEqual, Rule::new(None, Some(binary), PREC_COMPARISON)); + rules.insert(TokenType::Greater, Rule::new(None, Some(binary), PREC_COMPARISON)); + rules.insert(TokenType::GreaterEqual, Rule::new(None, Some(binary), PREC_COMPARISON)); rules.insert(TokenType::GreaterGreater, Rule::new(None, Some(binary), PREC_BITSHIFT)); - rules.insert(TokenType::Less, Rule::new(None, None, PREC_NONE)); - rules.insert(TokenType::LessEqual, Rule::new(None, None, PREC_NONE)); + rules.insert(TokenType::Less, Rule::new(None, Some(binary), PREC_COMPARISON)); + rules.insert(TokenType::LessEqual, Rule::new(None, Some(binary), PREC_COMPARISON)); rules.insert(TokenType::LessLess, Rule::new(None, Some(binary), PREC_BITSHIFT)); rules.insert(TokenType::Identifier, Rule::new(None, None, PREC_NONE)); rules.insert(TokenType::String, Rule::new(Some(literal), None, PREC_NONE)); diff --git a/src/main.rs b/src/main.rs index 81e860e..fd17330 100644 --- a/src/main.rs +++ b/src/main.rs @@ -2,7 +2,7 @@ fn main() -> anyhow::Result<()> { tracing_subscriber::fmt::init(); - let chunk = crudlang::compiler::compile("\"a\"+\"b\"")?; + let chunk = crudlang::compiler::compile("\"1\"+\"2\"")?; chunk.disassemble(); let result = crudlang::vm::interpret(chunk); diff --git a/src/value.rs b/src/value.rs index 85ab4b2..0b56c67 100644 --- a/src/value.rs +++ b/src/value.rs @@ -128,7 +128,7 @@ impl Add<&Value> for &Value { (Value::String(s), Value::F64(f)) => Ok(Value::String(format!("{}{}", s, f))), (Value::String(s), Value::Bool(b)) => Ok(Value::String(format!("{}{}", s, b))), (Value::String(s), Value::Char(c)) => Ok(Value::String(format!("{}{}", s, c))), - (Value::String(s1), Value::String(s2)) => Ok(Value::String(format!("{}{}", s2, s1))), + (Value::String(s1), Value::String(s2)) => Ok(Value::String(format!("{}{}", s1, s2))), (Value::String(s1), Value::List(l)) => Ok(Value::String(format!("{}{:?}", s1, l))), (Value::String(s1), Value::Map(m)) => Ok(Value::String(format!("{}{:?}", s1, m))), //enum? diff --git a/src/vm.rs b/src/vm.rs index 354dd13..99ab180 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -65,6 +65,11 @@ impl Vm { } OP_SHL => binary_op(self, |a, b| a << b), OP_SHR => binary_op(self, |a, b| a >> b), + OP_EQUAL => binary_op(self, |a, b| Ok(Value::Bool(a == b))), + OP_GREATER => binary_op(self, |a, b| Ok(Value::Bool(a > b))), + OP_GREATER_EQUAL => binary_op(self, |a, b| Ok(Value::Bool(a >= b))), + OP_LESS => binary_op(self, |a, b| Ok(Value::Bool(a < b))), + OP_LESS_EQUAL => binary_op(self, |a, b| Ok(Value::Bool(a <= b))), _ => {} } } @@ -86,8 +91,8 @@ impl Vm { } fn binary_op(vm: &mut Vm, op: impl Fn(&Value, &Value) -> anyhow::Result + Copy) { - let a = vm.pop(); let b = vm.pop(); + let a = vm.pop(); let result = op(&a, &b); match result {