Make VMNumber and LuaNumber into structs

This commit is contained in:
Sofia 2026-03-17 20:19:58 +02:00
parent 4c8f52de1a
commit 3b18b6c71e
4 changed files with 67 additions and 42 deletions

View File

@ -1,12 +1,13 @@
use std::{fmt::Debug, hash::Hash, ops::Add, path::PathBuf}; use std::{fmt::Debug, hash::Hash, ops::Add, path::PathBuf};
use crate::token_stream::{ use crate::{
Parse, TokenRange, TokenStream, TokenStreamError, token_stream::{
lexer::{Keyword, Position, Token}, Parse, TokenRange, TokenStream, TokenStreamError,
lexer::{Keyword, Position, Token},
},
vm::LuaNumber,
}; };
pub type LuaNumber = f64;
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub struct Node<T: Clone + Debug> { pub struct Node<T: Clone + Debug> {
pub kind: T, pub kind: T,
@ -464,9 +465,9 @@ impl Parse for PrimaryExpression {
Expression::FunctionDefinition(function.kind.params, function.kind.block) Expression::FunctionDefinition(function.kind.params, function.kind.block)
} else if let Some(Token::DecimalValue(value)) = peeked { } else if let Some(Token::DecimalValue(value)) = peeked {
stream.next(); // Consume decimal value stream.next(); // Consume decimal value
Expression::Literal(Literal::Number( Expression::Literal(Literal::Number(LuaNumber(
u64::from_str_radix(&value, 10).unwrap() as f64 u64::from_str_radix(&value, 10).unwrap() as f64,
)) )))
} else if let Some(Token::StringLit(value)) = peeked { } else if let Some(Token::StringLit(value)) = peeked {
stream.next(); // Consume string-literal stream.next(); // Consume string-literal
Expression::Literal(Literal::String(value)) Expression::Literal(Literal::String(value))

View File

@ -373,7 +373,7 @@ impl Expression {
Expression::Literal(literal) => match literal { Expression::Literal(literal) => match literal {
Literal::Number(value) => { Literal::Number(value) => {
let mut constants = HashSet::new(); let mut constants = HashSet::new();
constants.insert(Constant::Number(value.to_bits())); constants.insert(Constant::Number(value.vm_number()));
constants constants
} }
Literal::String(value) => { Literal::String(value) => {
@ -596,7 +596,7 @@ impl Expression {
instructions.push(Instruction::LoadK( instructions.push(Instruction::LoadK(
reg, reg,
state.get_constant(&match literal { state.get_constant(&match literal {
Literal::Number(value) => Constant::Number(value.to_bits()), Literal::Number(value) => Constant::Number(value.vm_number()),
Literal::String(value) => Constant::String(value.clone()), Literal::String(value) => Constant::String(value.clone()),
}), }),
)); ));

View File

@ -1,12 +1,12 @@
use std::{cell::RefCell, path::PathBuf, rc::Rc}; use std::{cell::RefCell, path::PathBuf, rc::Rc};
use crate::{ use crate::{
ast::{Block, Function, LuaNumber}, ast::{Block, Function},
token_stream::{ token_stream::{
TokenStream, TokenStream,
lexer::{Token, tokenize}, lexer::{Token, tokenize},
}, },
vm::{RuntimeError, RustFunction, VirtualMachine}, vm::{LuaNumber, RuntimeError, RustFunction, VirtualMachine},
}; };
mod ast; mod ast;
@ -24,8 +24,8 @@ impl RustFunction for Max {
let rhs = parameters.get(1).cloned().unwrap_or(vm::Value::Nil); let rhs = parameters.get(1).cloned().unwrap_or(vm::Value::Nil);
match lhs.lt(&rhs)? { match lhs.lt(&rhs)? {
vm::Value::Number(value) => { vm::Value::Number(value) => {
let res = LuaNumber::from_bits(value); let res = value.lua_number();
Ok(vec![if res > 0. { rhs } else { lhs }]) Ok(vec![if res.0 > 0. { rhs } else { lhs }])
} }
_ => Ok(vec![vm::Value::Nil]), _ => Ok(vec![vm::Value::Nil]),
} }

View File

@ -9,11 +9,39 @@ use std::{
}; };
use crate::{ use crate::{
ast::{BinaryOperator, LuaNumber, UnaryOperator}, ast::{BinaryOperator, UnaryOperator},
compile, compile,
}; };
pub type VMNumber = u64; #[derive(Clone, Hash, PartialEq, Eq, Copy)]
pub struct VMNumber(u64);
impl VMNumber {
pub fn lua_number(&self) -> LuaNumber {
LuaNumber(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 {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.lua_number().fmt(f)
}
}
impl Debug for LuaNumber {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
self.0.fmt(f)
}
}
#[derive(Clone, Hash, PartialEq, Eq)] #[derive(Clone, Hash, PartialEq, Eq)]
pub enum Constant { pub enum Constant {
@ -25,10 +53,7 @@ impl Debug for Constant {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(), Self::String(arg0) => f.debug_tuple("String").field(arg0).finish(),
Self::Number(arg0) => f Self::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(),
.debug_tuple("Number")
.field(&LuaNumber::from_bits(*arg0))
.finish(),
} }
} }
} }
@ -211,8 +236,8 @@ impl Value {
pub fn add(&self, other: &Value) -> Result<Value, RuntimeError> { pub fn add(&self, other: &Value) -> Result<Value, RuntimeError> {
match (self, other) { match (self, other) {
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) + LuaNumber::from_bits(*rhs); let res = LuaNumber(lhs.lua_number().0 + rhs.lua_number().0);
Ok(Value::Number(res.to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Err(RuntimeError::InvalidOperands( _ => Err(RuntimeError::InvalidOperands(
BinaryOperator::Add, BinaryOperator::Add,
@ -225,8 +250,8 @@ impl Value {
pub fn eq(&self, other: &Value) -> Result<Value, RuntimeError> { pub fn eq(&self, other: &Value) -> Result<Value, RuntimeError> {
match (self, other) { match (self, other) {
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = lhs == rhs; let res = LuaNumber((lhs == rhs) as u64 as f64);
Ok(Value::Number((res as u64 as f64).to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Err(RuntimeError::InvalidOperands( _ => Err(RuntimeError::InvalidOperands(
BinaryOperator::Equal, BinaryOperator::Equal,
@ -239,8 +264,8 @@ impl Value {
pub fn lt(&self, other: &Value) -> Result<Value, RuntimeError> { pub fn lt(&self, other: &Value) -> Result<Value, RuntimeError> {
match (self, other) { match (self, other) {
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) < LuaNumber::from_bits(*rhs); let res = LuaNumber((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64);
Ok(Value::Number((res as u64 as f64).to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Err(RuntimeError::InvalidOperands( _ => Err(RuntimeError::InvalidOperands(
BinaryOperator::LessThan, BinaryOperator::LessThan,
@ -253,8 +278,8 @@ impl Value {
pub fn lte(&self, other: &Value) -> Result<Value, RuntimeError> { pub fn lte(&self, other: &Value) -> Result<Value, RuntimeError> {
match (self, other) { match (self, other) {
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) <= LuaNumber::from_bits(*rhs); let res = LuaNumber((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64);
Ok(Value::Number((res as u64 as f64).to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Err(RuntimeError::InvalidOperands( _ => Err(RuntimeError::InvalidOperands(
BinaryOperator::LessThanOrEqual, BinaryOperator::LessThanOrEqual,
@ -267,8 +292,8 @@ impl Value {
pub fn unm(&self) -> Result<Value, RuntimeError> { pub fn unm(&self) -> Result<Value, RuntimeError> {
match self { match self {
Value::Number(lhs) => { Value::Number(lhs) => {
let res = -LuaNumber::from_bits(*lhs); let res = LuaNumber(-lhs.lua_number().0);
Ok(Value::Number(res.to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Err(RuntimeError::InvalidOperand( _ => Err(RuntimeError::InvalidOperand(
UnaryOperator::Negation, UnaryOperator::Negation,
@ -281,12 +306,13 @@ impl Value {
match (self, other) { match (self, other) {
(Value::Nil, _) | (_, Value::Nil) => Ok(Value::Nil), (Value::Nil, _) | (_, Value::Nil) => Ok(Value::Nil),
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) > 0. && LuaNumber::from_bits(*rhs) > 0.; let res =
Ok(Value::Number((res as u64 as f64).to_bits())) LuaNumber((lhs.lua_number().0 > 0. && rhs.lua_number().0 > 0.) as u64 as f64);
Ok(Value::Number(res.vm_number()))
} }
(Value::Number(value), _) | (_, Value::Number(value)) => { (Value::Number(value), _) | (_, Value::Number(value)) => {
let res = LuaNumber::from_bits(*value) > 0.; let res = LuaNumber((value.lua_number().0 > 0.) as u64 as f64);
Ok(Value::Number((res as u64 as f64).to_bits())) Ok(Value::Number(res.vm_number()))
} }
_ => Ok(Value::Nil), _ => Ok(Value::Nil),
} }
@ -296,11 +322,12 @@ impl Value {
match (self, other) { match (self, other) {
(Value::Nil, value) | (value, Value::Nil) => Ok(value.clone()), (Value::Nil, value) | (value, Value::Nil) => Ok(value.clone()),
(Value::Number(lhs), Value::Number(rhs)) => { (Value::Number(lhs), Value::Number(rhs)) => {
let res = LuaNumber::from_bits(*lhs) > 0. || LuaNumber::from_bits(*rhs) > 0.; let res =
Ok(Value::Number((res as u64 as f64).to_bits())) LuaNumber((lhs.lua_number().0 > 0. || rhs.lua_number().0 > 0.) as u64 as f64);
Ok(Value::Number(res.vm_number()))
} }
(Value::Number(value), other) => { (Value::Number(value), other) => {
if LuaNumber::from_bits(*value) > 0. { if value.lua_number().0 > 0. {
Ok(Value::Number(*value)) Ok(Value::Number(*value))
} else { } else {
Ok(other.clone()) Ok(other.clone())
@ -315,10 +342,7 @@ impl Value {
impl Debug for Value { impl Debug for Value {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self { match self {
Value::Number(arg0) => f Value::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(),
.debug_tuple("Number")
.field(&LuaNumber::from_bits(*arg0))
.finish(),
Value::String(value) => f.debug_tuple("String").field(value).finish(), Value::String(value) => f.debug_tuple("String").field(value).finish(),
Value::RustFunction(arg0) => f.debug_tuple("RustFunction").field(arg0).finish(), Value::RustFunction(arg0) => f.debug_tuple("RustFunction").field(arg0).finish(),
Value::Function(closure) => f Value::Function(closure) => f
@ -663,7 +687,7 @@ impl ClosureRunner {
.map(|v| v.borrow().clone()) .map(|v| v.borrow().clone())
.unwrap_or(Value::Nil) .unwrap_or(Value::Nil)
{ {
Value::Number(val) => (LuaNumber::from_bits(val) as u16) == *c, Value::Number(val) => (val.lua_number().0 as u16) == *c,
_ => false, _ => false,
}; };
if is_true { if is_true {