diff --git a/src/ast.rs b/src/ast.rs index 903c80a..aa0c4e4 100644 --- a/src/ast.rs +++ b/src/ast.rs @@ -5,7 +5,7 @@ use crate::{ Parse, TokenRange, TokenStream, TokenStreamError, lexer::{Keyword, Position, Token}, }, - vm::LuaNumber, + vm::{LuaFloat, LuaInteger}, }; #[derive(Debug, Clone)] @@ -465,8 +465,8 @@ impl Parse for PrimaryExpression { Expression::FunctionDefinition(function.kind.params, function.kind.block) } else if let Some(Token::DecimalValue(value)) = peeked { stream.next(); // Consume decimal value - Expression::Literal(Literal::Number(LuaNumber( - u64::from_str_radix(&value, 10).unwrap() as f64, + Expression::Literal(Literal::Integer(LuaInteger( + u64::from_str_radix(&value, 10).unwrap(), ))) } else if let Some(Token::StringLit(value)) = peeked { stream.next(); // Consume string-literal @@ -553,6 +553,7 @@ fn parse_binop_rhs( #[derive(Debug, Clone)] pub enum Literal { - Number(LuaNumber), + Float(LuaFloat), + Integer(LuaInteger), String(String), } diff --git a/src/compile.rs b/src/compile.rs index b06b674..55471db 100644 --- a/src/compile.rs +++ b/src/compile.rs @@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet}; use crate::{ ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement, UnaryOperator}, - vm::{Constant, Instruction, VMNumber}, + vm::{Constant, Instruction, VMFloat}, }; pub struct State { @@ -371,9 +371,14 @@ impl Expression { constants } Expression::Literal(literal) => match literal { - Literal::Number(value) => { + Literal::Float(value) => { let mut constants = HashSet::new(); - constants.insert(Constant::Number(value.vm_number())); + constants.insert(Constant::Float(value.vm_number())); + constants + } + Literal::Integer(value) => { + let mut constants = HashSet::new(); + constants.insert(Constant::Integer(*value)); constants } Literal::String(value) => { @@ -596,8 +601,9 @@ impl Expression { instructions.push(Instruction::LoadK( reg, state.get_constant(&match literal { - Literal::Number(value) => Constant::Number(value.vm_number()), + Literal::Float(value) => Constant::Float(value.vm_number()), Literal::String(value) => Constant::String(value.clone()), + Literal::Integer(lua_integer) => Constant::Integer(*lua_integer), }), )); (instructions, vec![reg]) diff --git a/src/main.rs b/src/main.rs index 8dd9609..7b853a1 100644 --- a/src/main.rs +++ b/src/main.rs @@ -6,7 +6,7 @@ use crate::{ TokenStream, lexer::{Token, tokenize}, }, - vm::{LuaNumber, RuntimeError, RustFunction, VirtualMachine}, + vm::{LuaFloat, RuntimeError, RustFunction, VirtualMachine}, }; mod ast; @@ -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::Number(value) => { + vm::Value::Float(value) => { let res = value.lua_number(); Ok(vec![if res.0 > 0. { rhs } else { lhs }]) } diff --git a/src/vm.rs b/src/vm.rs index 70384b3..f853d1a 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -14,30 +14,39 @@ use crate::{ }; #[derive(Clone, Hash, PartialEq, Eq, Copy)] -pub struct VMNumber(u64); +pub struct VMFloat(u64); -impl VMNumber { - pub fn lua_number(&self) -> LuaNumber { - LuaNumber(f64::from_bits(self.0)) +impl VMFloat { + pub fn lua_number(&self) -> LuaFloat { + LuaFloat(f64::from_bits(self.0)) } } -#[derive(Clone, Copy)] -pub struct LuaNumber(pub f64); - -impl LuaNumber { - pub fn vm_number(&self) -> VMNumber { - VMNumber(f64::to_bits(self.0)) - } -} - -impl Debug for VMNumber { +impl Debug for VMFloat { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.lua_number().fmt(f) } } -impl Debug for LuaNumber { +#[derive(Clone, Copy)] +pub struct LuaFloat(pub f64); + +impl LuaFloat { + pub fn vm_number(&self) -> VMFloat { + VMFloat(f64::to_bits(self.0)) + } +} + +impl Debug for LuaFloat { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + self.0.fmt(f) + } +} + +#[derive(Clone, Copy, Hash, PartialEq, Eq)] +pub struct LuaInteger(pub u64); + +impl Debug for LuaInteger { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { self.0.fmt(f) } @@ -46,14 +55,16 @@ impl Debug for LuaNumber { #[derive(Clone, Hash, PartialEq, Eq)] pub enum Constant { String(String), - Number(VMNumber), + Float(VMFloat), + Integer(LuaInteger), } impl Debug for Constant { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(), - Self::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), + Self::Float(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), + Self::Integer(arg0) => f.debug_tuple("Integer").field(arg0).finish(), } } } @@ -202,7 +213,8 @@ impl Environment { #[derive(Clone)] pub enum Value { String(String), - Number(VMNumber), + Float(VMFloat), + Integer(LuaInteger), RustFunction(Rc>), Function(Closure), Nil, @@ -213,7 +225,8 @@ impl Value { pub fn as_indexable(self) -> Result { match self { Value::String(value) => Ok(IndexableValue::String(value)), - Value::Number(value) => Ok(IndexableValue::Number(value)), + Value::Float(value) => Ok(IndexableValue::Number(value)), + Value::Integer(value) => Ok(IndexableValue::Integer(value)), Value::RustFunction(value) => { Ok(IndexableValue::RustFunction(value.borrow().as_indexable())) } @@ -227,7 +240,8 @@ impl Value { #[derive(Debug, PartialEq, Eq, Hash, Clone)] pub enum IndexableValue { String(String), - Number(VMNumber), + Number(VMFloat), + Integer(LuaInteger), RustFunction(String), Function(u32), } @@ -235,9 +249,9 @@ pub enum IndexableValue { impl Value { pub fn add(&self, other: &Value) -> Result { match (self, other) { - (Value::Number(lhs), Value::Number(rhs)) => { - let res = LuaNumber(lhs.lua_number().0 + rhs.lua_number().0); - Ok(Value::Number(res.vm_number())) + (Value::Float(lhs), Value::Float(rhs)) => { + let res = LuaFloat(lhs.lua_number().0 + rhs.lua_number().0); + Ok(Value::Float(res.vm_number())) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::Add, @@ -249,9 +263,9 @@ impl Value { pub fn eq(&self, other: &Value) -> Result { match (self, other) { - (Value::Number(lhs), Value::Number(rhs)) => { - let res = LuaNumber((lhs == rhs) as u64 as f64); - Ok(Value::Number(res.vm_number())) + (Value::Float(lhs), Value::Float(rhs)) => { + let res = LuaFloat((lhs == rhs) as u64 as f64); + Ok(Value::Float(res.vm_number())) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::Equal, @@ -263,9 +277,9 @@ impl Value { pub fn lt(&self, other: &Value) -> Result { match (self, other) { - (Value::Number(lhs), Value::Number(rhs)) => { - let res = LuaNumber((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64); - Ok(Value::Number(res.vm_number())) + (Value::Float(lhs), Value::Float(rhs)) => { + let res = LuaFloat((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64); + Ok(Value::Float(res.vm_number())) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::LessThan, @@ -277,9 +291,9 @@ impl Value { pub fn lte(&self, other: &Value) -> Result { match (self, other) { - (Value::Number(lhs), Value::Number(rhs)) => { - let res = LuaNumber((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64); - Ok(Value::Number(res.vm_number())) + (Value::Float(lhs), Value::Float(rhs)) => { + let res = LuaFloat((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64); + Ok(Value::Float(res.vm_number())) } _ => Err(RuntimeError::InvalidOperands( BinaryOperator::LessThanOrEqual, @@ -291,9 +305,9 @@ impl Value { pub fn unm(&self) -> Result { match self { - Value::Number(lhs) => { - let res = LuaNumber(-lhs.lua_number().0); - Ok(Value::Number(res.vm_number())) + Value::Float(lhs) => { + let res = LuaFloat(-lhs.lua_number().0); + Ok(Value::Float(res.vm_number())) } _ => Err(RuntimeError::InvalidOperand( UnaryOperator::Negation, @@ -305,14 +319,14 @@ impl Value { pub fn and(&self, other: &Value) -> Result { match (self, other) { (Value::Nil, _) | (_, Value::Nil) => Ok(Value::Nil), - (Value::Number(lhs), Value::Number(rhs)) => { + (Value::Float(lhs), Value::Float(rhs)) => { let res = - LuaNumber((lhs.lua_number().0 > 0. && rhs.lua_number().0 > 0.) as u64 as f64); - Ok(Value::Number(res.vm_number())) + LuaFloat((lhs.lua_number().0 > 0. && rhs.lua_number().0 > 0.) as u64 as f64); + Ok(Value::Float(res.vm_number())) } - (Value::Number(value), _) | (_, Value::Number(value)) => { - let res = LuaNumber((value.lua_number().0 > 0.) as u64 as f64); - Ok(Value::Number(res.vm_number())) + (Value::Float(value), _) | (_, Value::Float(value)) => { + let res = LuaFloat((value.lua_number().0 > 0.) as u64 as f64); + Ok(Value::Float(res.vm_number())) } _ => Ok(Value::Nil), } @@ -321,14 +335,14 @@ impl Value { pub fn or(&self, other: &Value) -> Result { match (self, other) { (Value::Nil, value) | (value, Value::Nil) => Ok(value.clone()), - (Value::Number(lhs), Value::Number(rhs)) => { + (Value::Float(lhs), Value::Float(rhs)) => { let res = - LuaNumber((lhs.lua_number().0 > 0. || rhs.lua_number().0 > 0.) as u64 as f64); - Ok(Value::Number(res.vm_number())) + LuaFloat((lhs.lua_number().0 > 0. || rhs.lua_number().0 > 0.) as u64 as f64); + Ok(Value::Float(res.vm_number())) } - (Value::Number(value), other) => { + (Value::Float(value), other) => { if value.lua_number().0 > 0. { - Ok(Value::Number(*value)) + Ok(Value::Float(*value)) } else { Ok(other.clone()) } @@ -342,7 +356,8 @@ impl Value { impl Debug for Value { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { match self { - Value::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), + Value::Float(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(), + Value::Integer(arg0) => f.debug_tuple("Integer").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 @@ -567,7 +582,8 @@ impl ClosureRunner { *reg, StackValue::Value(match constants.get(*constant as usize).unwrap() { Constant::String(value) => Value::String(value.clone()), - Constant::Number(value) => Value::Number(*value), + Constant::Float(value) => Value::Float(*value), + Constant::Integer(value) => Value::Integer(*value), }), ); } @@ -687,7 +703,7 @@ impl ClosureRunner { .map(|v| v.borrow().clone()) .unwrap_or(Value::Nil) { - Value::Number(val) => (val.lua_number().0 as u16) == *c, + Value::Float(val) => (val.lua_number().0 as u16) == *c, _ => false, }; if is_true {