Add booleans
This commit is contained in:
parent
c37e95e445
commit
1e2feb9c3c
@ -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]),
|
||||
}
|
||||
}
|
||||
|
||||
93
src/vm.rs
93
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<LuaBool> 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<RefCell<dyn RustFunction>>),
|
||||
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<LuaInteger, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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
|
||||
|
||||
Loading…
Reference in New Issue
Block a user