From 1e2feb9c3c737cb510ae38f9816ec44818e2b669 Mon Sep 17 00:00:00 2001 From: Sofia Date: Tue, 17 Mar 2026 20:58:15 +0200 Subject: [PATCH] Add booleans --- src/main.rs | 2 +- src/vm.rs | 93 +++++++++++++++++++++++++++++++++++------------------ 2 files changed, 63 insertions(+), 32 deletions(-) diff --git a/src/main.rs b/src/main.rs index 849b71b..cd58060 100644 --- a/src/main.rs +++ b/src/main.rs @@ -23,7 +23,7 @@ impl RustFunction for Max { let lhs = parameters.get(0).cloned().unwrap_or(vm::Value::Nil); let rhs = parameters.get(1).cloned().unwrap_or(vm::Value::Nil); match lhs.lt(&rhs)? { - vm::Value::Integer(value) => Ok(vec![if value.0 > 0 { rhs } else { lhs }]), + vm::Value::Boolean(value) => Ok(vec![if value.0 { rhs } else { lhs }]), _ => Ok(vec![vm::Value::Nil]), } } diff --git a/src/vm.rs b/src/vm.rs index 9f0b295..33a3252 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -64,6 +64,27 @@ impl From<&LuaInteger> for LuaFloat { } } +#[derive(Clone, Copy, Hash, PartialEq, Eq)] +pub struct LuaBool(pub bool); + +impl Debug for LuaBool { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +impl From for LuaInteger { + fn from(value: LuaBool) -> Self { + LuaInteger(value.0 as i64) + } +} + +impl From<&LuaBool> for LuaInteger { + fn from(value: &LuaBool) -> Self { + LuaInteger(value.0 as i64) + } +} + #[derive(Clone, Hash, PartialEq, Eq)] pub enum Constant { String(String), @@ -229,6 +250,7 @@ pub enum Value { String(String), Float(VMFloat), Integer(LuaInteger), + Boolean(LuaBool), RustFunction(Rc>), Function(Closure), Nil, @@ -241,6 +263,7 @@ impl Value { Value::String(value) => Ok(IndexableValue::String(value)), Value::Float(value) => Ok(IndexableValue::Number(value)), Value::Integer(value) => Ok(IndexableValue::Integer(value)), + Value::Boolean(value) => Ok(IndexableValue::Bool(value)), Value::RustFunction(value) => { Ok(IndexableValue::RustFunction(value.borrow().as_indexable())) } @@ -254,6 +277,15 @@ impl Value { match self { Value::Float(vmfloat) => Ok(vmfloat.lua_number()), Value::Integer(lua_integer) => Ok(lua_integer.into()), + Value::Boolean(lua_boolean) => Ok(LuaFloat(lua_boolean.0 as u64 as f64)), + _ => Err(RuntimeError::NotFloatable(self.clone())), + } + } + + pub fn as_integer(&self) -> Result { + match self { + Value::Integer(lua_integer) => Ok(*lua_integer), + Value::Boolean(lua_boolean) => Ok(LuaInteger(lua_boolean.0 as i64)), _ => Err(RuntimeError::NotFloatable(self.clone())), } } @@ -264,6 +296,7 @@ pub enum IndexableValue { String(String), Number(VMFloat), Integer(LuaInteger), + Bool(LuaBool), RustFunction(String), Function(u32), } @@ -271,11 +304,14 @@ pub enum IndexableValue { impl Value { pub fn add(&self, other: &Value) -> Result { match (self, other) { - (Value::Integer(lhs), Value::Integer(rhs)) => { - let res = LuaInteger(lhs.0 + rhs.0); + (Value::Integer(_) | Value::Boolean(_), Value::Integer(_) | Value::Boolean(_)) => { + let res = LuaInteger(self.as_integer()?.0 + other.as_integer()?.0); Ok(Value::Integer(res)) } - (Value::Float(_) | Value::Integer(_), Value::Float(_) | Value::Integer(_)) => { + ( + Value::Float(_) | Value::Integer(_) | Value::Boolean(_), + Value::Float(_) | Value::Integer(_) | Value::Boolean(_), + ) => { let res = LuaFloat(self.as_float()?.0 + other.as_float()?.0); Ok(Value::Float(res.vm_number())) } @@ -290,12 +326,11 @@ impl Value { pub fn eq(&self, other: &Value) -> Result { match (self, other) { (Value::Integer(lhs), Value::Integer(rhs)) => { - let res = LuaInteger((lhs.0 == rhs.0) as i64); - Ok(Value::Integer(res)) + Ok(Value::Boolean(LuaBool(lhs.0 == rhs.0))) } (Value::Float(_) | Value::Integer(_), Value::Float(_) | Value::Integer(_)) => { - let res = LuaInteger((self.as_float()?.0 == other.as_float()?.0) as i64); - Ok(Value::Integer(res)) + let res = LuaBool(self.as_float()?.0 == other.as_float()?.0); + Ok(Value::Boolean(res)) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::Equal, @@ -308,12 +343,11 @@ impl Value { pub fn lt(&self, other: &Value) -> Result { match (self, other) { (Value::Integer(lhs), Value::Integer(rhs)) => { - let res = LuaInteger((lhs.0 < rhs.0) as i64); - Ok(Value::Integer(res)) + Ok(Value::Boolean(LuaBool(lhs.0 < rhs.0))) } (Value::Float(_) | Value::Integer(_), Value::Float(_) | Value::Integer(_)) => { - let res = LuaInteger((self.as_float()?.0 < other.as_float()?.0) as i64); - Ok(Value::Integer(res)) + let res = LuaBool(self.as_float()?.0 < other.as_float()?.0); + Ok(Value::Boolean(res)) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::LessThan, @@ -326,12 +360,11 @@ impl Value { pub fn lte(&self, other: &Value) -> Result { match (self, other) { (Value::Integer(lhs), Value::Integer(rhs)) => { - let res = LuaInteger((lhs.0 <= rhs.0) as i64); - Ok(Value::Integer(res)) + Ok(Value::Boolean(LuaBool(lhs.0 <= rhs.0))) } (Value::Float(_) | Value::Integer(_), Value::Float(_) | Value::Integer(_)) => { - let res = LuaInteger((self.as_float()?.0 <= other.as_float()?.0) as i64); - Ok(Value::Integer(res)) + let res = LuaBool(self.as_float()?.0 <= other.as_float()?.0); + Ok(Value::Boolean(res)) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::LessThanOrEqual, @@ -351,6 +384,10 @@ impl Value { let res = LuaFloat(-lhs.lua_number().0); Ok(Value::Float(res.vm_number())) } + Value::Boolean(val) => { + let res = LuaBool(!val.0); + Ok(Value::Boolean(res)) + } _ => Err(RuntimeError::InvalidOperand( UnaryOperator::Negation, self.clone(), @@ -359,18 +396,10 @@ impl Value { } pub fn and(&self, other: &Value) -> Result { - match (self, other) { - (Value::Float(_) | Value::Integer(_), Value::Float(_) | Value::Integer(_)) => Ok( - Value::Integer(LuaInteger((self.is_truthy() && other.is_truthy()) as i64)), - ), - (Value::Float(_) | Value::Integer(_), _) => { - Ok(Value::Integer(LuaInteger(self.is_truthy() as i64))) - } - (_, Value::Float(_) | Value::Integer(_)) => { - Ok(Value::Integer(LuaInteger(other.is_truthy() as i64))) - } - (Value::Nil, _) | (_, Value::Nil) => Ok(Value::Nil), - _ => Ok(Value::Nil), + if self.is_truthy() { + Ok(self.clone()) + } else { + Ok(other.clone()) } } @@ -384,13 +413,14 @@ impl Value { pub fn is_truthy(&self) -> bool { match self { - Value::String(value) => value.len() > 0, - Value::Float(vmfloat) => vmfloat.lua_number().0 > 0., - Value::Integer(lua_integer) => lua_integer.0 > 0, + Value::String(_) => true, + Value::Float(_) => true, + Value::Integer(_) => true, + Value::Boolean(lua_bool) => lua_bool.0, Value::RustFunction(_) => true, Value::Function(_) => true, Value::Nil => false, - Value::Table(value) => value.borrow().len() > 0, + Value::Table(_) => true, } } } @@ -400,6 +430,7 @@ impl Debug for Value { match self { Value::Float(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), Value::Integer(arg0) => f.debug_tuple("Integer").field(arg0).finish(), + Value::Boolean(arg0) => f.debug_tuple("Boolean").field(arg0).finish(), Value::String(value) => f.debug_tuple("String").field(value).finish(), Value::RustFunction(arg0) => f.debug_tuple("RustFunction").field(arg0).finish(), Value::Function(closure) => f