Make VMNumber and LuaNumber into structs
This commit is contained in:
parent
4c8f52de1a
commit
3b18b6c71e
17
src/ast.rs
17
src/ast.rs
@ -1,12 +1,13 @@
|
||||
use std::{fmt::Debug, hash::Hash, ops::Add, path::PathBuf};
|
||||
|
||||
use crate::token_stream::{
|
||||
Parse, TokenRange, TokenStream, TokenStreamError,
|
||||
lexer::{Keyword, Position, Token},
|
||||
use crate::{
|
||||
token_stream::{
|
||||
Parse, TokenRange, TokenStream, TokenStreamError,
|
||||
lexer::{Keyword, Position, Token},
|
||||
},
|
||||
vm::LuaNumber,
|
||||
};
|
||||
|
||||
pub type LuaNumber = f64;
|
||||
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Node<T: Clone + Debug> {
|
||||
pub kind: T,
|
||||
@ -464,9 +465,9 @@ 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(
|
||||
u64::from_str_radix(&value, 10).unwrap() as f64
|
||||
))
|
||||
Expression::Literal(Literal::Number(LuaNumber(
|
||||
u64::from_str_radix(&value, 10).unwrap() as f64,
|
||||
)))
|
||||
} else if let Some(Token::StringLit(value)) = peeked {
|
||||
stream.next(); // Consume string-literal
|
||||
Expression::Literal(Literal::String(value))
|
||||
|
||||
@ -373,7 +373,7 @@ impl Expression {
|
||||
Expression::Literal(literal) => match literal {
|
||||
Literal::Number(value) => {
|
||||
let mut constants = HashSet::new();
|
||||
constants.insert(Constant::Number(value.to_bits()));
|
||||
constants.insert(Constant::Number(value.vm_number()));
|
||||
constants
|
||||
}
|
||||
Literal::String(value) => {
|
||||
@ -596,7 +596,7 @@ impl Expression {
|
||||
instructions.push(Instruction::LoadK(
|
||||
reg,
|
||||
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()),
|
||||
}),
|
||||
));
|
||||
|
||||
@ -1,12 +1,12 @@
|
||||
use std::{cell::RefCell, path::PathBuf, rc::Rc};
|
||||
|
||||
use crate::{
|
||||
ast::{Block, Function, LuaNumber},
|
||||
ast::{Block, Function},
|
||||
token_stream::{
|
||||
TokenStream,
|
||||
lexer::{Token, tokenize},
|
||||
},
|
||||
vm::{RuntimeError, RustFunction, VirtualMachine},
|
||||
vm::{LuaNumber, RuntimeError, RustFunction, VirtualMachine},
|
||||
};
|
||||
|
||||
mod ast;
|
||||
@ -24,8 +24,8 @@ impl RustFunction for Max {
|
||||
let rhs = parameters.get(1).cloned().unwrap_or(vm::Value::Nil);
|
||||
match lhs.lt(&rhs)? {
|
||||
vm::Value::Number(value) => {
|
||||
let res = LuaNumber::from_bits(value);
|
||||
Ok(vec![if res > 0. { rhs } else { lhs }])
|
||||
let res = value.lua_number();
|
||||
Ok(vec![if res.0 > 0. { rhs } else { lhs }])
|
||||
}
|
||||
_ => Ok(vec![vm::Value::Nil]),
|
||||
}
|
||||
|
||||
80
src/vm.rs
80
src/vm.rs
@ -9,11 +9,39 @@ use std::{
|
||||
};
|
||||
|
||||
use crate::{
|
||||
ast::{BinaryOperator, LuaNumber, UnaryOperator},
|
||||
ast::{BinaryOperator, UnaryOperator},
|
||||
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)]
|
||||
pub enum Constant {
|
||||
@ -25,10 +53,7 @@ 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(&LuaNumber::from_bits(*arg0))
|
||||
.finish(),
|
||||
Self::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).finish(),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -211,8 +236,8 @@ impl Value {
|
||||
pub fn add(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||
match (self, other) {
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = LuaNumber::from_bits(*lhs) + LuaNumber::from_bits(*rhs);
|
||||
Ok(Value::Number(res.to_bits()))
|
||||
let res = LuaNumber(lhs.lua_number().0 + rhs.lua_number().0);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Err(RuntimeError::InvalidOperands(
|
||||
BinaryOperator::Add,
|
||||
@ -225,8 +250,8 @@ impl Value {
|
||||
pub fn eq(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||
match (self, other) {
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = lhs == rhs;
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res = LuaNumber((lhs == rhs) as u64 as f64);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Err(RuntimeError::InvalidOperands(
|
||||
BinaryOperator::Equal,
|
||||
@ -239,8 +264,8 @@ impl Value {
|
||||
pub fn lt(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||
match (self, other) {
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = LuaNumber::from_bits(*lhs) < LuaNumber::from_bits(*rhs);
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res = LuaNumber((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Err(RuntimeError::InvalidOperands(
|
||||
BinaryOperator::LessThan,
|
||||
@ -253,8 +278,8 @@ impl Value {
|
||||
pub fn lte(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||
match (self, other) {
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = LuaNumber::from_bits(*lhs) <= LuaNumber::from_bits(*rhs);
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res = LuaNumber((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Err(RuntimeError::InvalidOperands(
|
||||
BinaryOperator::LessThanOrEqual,
|
||||
@ -267,8 +292,8 @@ impl Value {
|
||||
pub fn unm(&self) -> Result<Value, RuntimeError> {
|
||||
match self {
|
||||
Value::Number(lhs) => {
|
||||
let res = -LuaNumber::from_bits(*lhs);
|
||||
Ok(Value::Number(res.to_bits()))
|
||||
let res = LuaNumber(-lhs.lua_number().0);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Err(RuntimeError::InvalidOperand(
|
||||
UnaryOperator::Negation,
|
||||
@ -281,12 +306,13 @@ impl Value {
|
||||
match (self, other) {
|
||||
(Value::Nil, _) | (_, Value::Nil) => Ok(Value::Nil),
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = LuaNumber::from_bits(*lhs) > 0. && LuaNumber::from_bits(*rhs) > 0.;
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res =
|
||||
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)) => {
|
||||
let res = LuaNumber::from_bits(*value) > 0.;
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res = LuaNumber((value.lua_number().0 > 0.) as u64 as f64);
|
||||
Ok(Value::Number(res.vm_number()))
|
||||
}
|
||||
_ => Ok(Value::Nil),
|
||||
}
|
||||
@ -296,11 +322,12 @@ impl Value {
|
||||
match (self, other) {
|
||||
(Value::Nil, value) | (value, Value::Nil) => Ok(value.clone()),
|
||||
(Value::Number(lhs), Value::Number(rhs)) => {
|
||||
let res = LuaNumber::from_bits(*lhs) > 0. || LuaNumber::from_bits(*rhs) > 0.;
|
||||
Ok(Value::Number((res as u64 as f64).to_bits()))
|
||||
let res =
|
||||
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) => {
|
||||
if LuaNumber::from_bits(*value) > 0. {
|
||||
if value.lua_number().0 > 0. {
|
||||
Ok(Value::Number(*value))
|
||||
} else {
|
||||
Ok(other.clone())
|
||||
@ -315,10 +342,7 @@ 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(&LuaNumber::from_bits(*arg0))
|
||||
.finish(),
|
||||
Value::Number(arg0) => f.debug_tuple("Number").field(&arg0.lua_number()).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
|
||||
@ -663,7 +687,7 @@ impl ClosureRunner {
|
||||
.map(|v| v.borrow().clone())
|
||||
.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,
|
||||
};
|
||||
if is_true {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user