Add integers and floats separately
This commit is contained in:
parent
3b18b6c71e
commit
0795957d0d
@ -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),
|
||||
}
|
||||
|
||||
@ -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])
|
||||
|
||||
@ -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 }])
|
||||
}
|
||||
|
||||
114
src/vm.rs
114
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<RefCell<dyn RustFunction>>),
|
||||
Function(Closure),
|
||||
Nil,
|
||||
@ -213,7 +225,8 @@ impl Value {
|
||||
pub fn as_indexable(self) -> Result<IndexableValue, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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<Value, RuntimeError> {
|
||||
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 {
|
||||
|
||||
Loading…
Reference in New Issue
Block a user