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 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))
|
||||||
|
|||||||
@ -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()),
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
|
|||||||
@ -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]),
|
||||||
}
|
}
|
||||||
|
|||||||
80
src/vm.rs
80
src/vm.rs
@ -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 {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user