Add integers and floats separately
This commit is contained in:
parent
3b18b6c71e
commit
0795957d0d
@ -5,7 +5,7 @@ use crate::{
|
|||||||
Parse, TokenRange, TokenStream, TokenStreamError,
|
Parse, TokenRange, TokenStream, TokenStreamError,
|
||||||
lexer::{Keyword, Position, Token},
|
lexer::{Keyword, Position, Token},
|
||||||
},
|
},
|
||||||
vm::LuaNumber,
|
vm::{LuaFloat, LuaInteger},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
@ -465,8 +465,8 @@ 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(LuaNumber(
|
Expression::Literal(Literal::Integer(LuaInteger(
|
||||||
u64::from_str_radix(&value, 10).unwrap() as f64,
|
u64::from_str_radix(&value, 10).unwrap(),
|
||||||
)))
|
)))
|
||||||
} 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
|
||||||
@ -553,6 +553,7 @@ fn parse_binop_rhs(
|
|||||||
|
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub enum Literal {
|
pub enum Literal {
|
||||||
Number(LuaNumber),
|
Float(LuaFloat),
|
||||||
|
Integer(LuaInteger),
|
||||||
String(String),
|
String(String),
|
||||||
}
|
}
|
||||||
|
|||||||
@ -2,7 +2,7 @@ use std::collections::{HashMap, HashSet};
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement, UnaryOperator},
|
ast::{AccessModifier, BinaryOperator, Block, Expression, Literal, Statement, UnaryOperator},
|
||||||
vm::{Constant, Instruction, VMNumber},
|
vm::{Constant, Instruction, VMFloat},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub struct State {
|
pub struct State {
|
||||||
@ -371,9 +371,14 @@ impl Expression {
|
|||||||
constants
|
constants
|
||||||
}
|
}
|
||||||
Expression::Literal(literal) => match literal {
|
Expression::Literal(literal) => match literal {
|
||||||
Literal::Number(value) => {
|
Literal::Float(value) => {
|
||||||
let mut constants = HashSet::new();
|
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
|
constants
|
||||||
}
|
}
|
||||||
Literal::String(value) => {
|
Literal::String(value) => {
|
||||||
@ -596,8 +601,9 @@ 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.vm_number()),
|
Literal::Float(value) => Constant::Float(value.vm_number()),
|
||||||
Literal::String(value) => Constant::String(value.clone()),
|
Literal::String(value) => Constant::String(value.clone()),
|
||||||
|
Literal::Integer(lua_integer) => Constant::Integer(*lua_integer),
|
||||||
}),
|
}),
|
||||||
));
|
));
|
||||||
(instructions, vec![reg])
|
(instructions, vec![reg])
|
||||||
|
|||||||
@ -6,7 +6,7 @@ use crate::{
|
|||||||
TokenStream,
|
TokenStream,
|
||||||
lexer::{Token, tokenize},
|
lexer::{Token, tokenize},
|
||||||
},
|
},
|
||||||
vm::{LuaNumber, RuntimeError, RustFunction, VirtualMachine},
|
vm::{LuaFloat, RuntimeError, RustFunction, VirtualMachine},
|
||||||
};
|
};
|
||||||
|
|
||||||
mod ast;
|
mod ast;
|
||||||
@ -23,7 +23,7 @@ impl RustFunction for Max {
|
|||||||
let lhs = parameters.get(0).cloned().unwrap_or(vm::Value::Nil);
|
let lhs = parameters.get(0).cloned().unwrap_or(vm::Value::Nil);
|
||||||
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::Float(value) => {
|
||||||
let res = value.lua_number();
|
let res = value.lua_number();
|
||||||
Ok(vec![if res.0 > 0. { rhs } else { lhs }])
|
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)]
|
#[derive(Clone, Hash, PartialEq, Eq, Copy)]
|
||||||
pub struct VMNumber(u64);
|
pub struct VMFloat(u64);
|
||||||
|
|
||||||
impl VMNumber {
|
impl VMFloat {
|
||||||
pub fn lua_number(&self) -> LuaNumber {
|
pub fn lua_number(&self) -> LuaFloat {
|
||||||
LuaNumber(f64::from_bits(self.0))
|
LuaFloat(f64::from_bits(self.0))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone, Copy)]
|
impl Debug for VMFloat {
|
||||||
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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.lua_number().fmt(f)
|
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 {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
self.0.fmt(f)
|
self.0.fmt(f)
|
||||||
}
|
}
|
||||||
@ -46,14 +55,16 @@ impl Debug for LuaNumber {
|
|||||||
#[derive(Clone, Hash, PartialEq, Eq)]
|
#[derive(Clone, Hash, PartialEq, Eq)]
|
||||||
pub enum Constant {
|
pub enum Constant {
|
||||||
String(String),
|
String(String),
|
||||||
Number(VMNumber),
|
Float(VMFloat),
|
||||||
|
Integer(LuaInteger),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Debug for Constant {
|
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.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)]
|
#[derive(Clone)]
|
||||||
pub enum Value {
|
pub enum Value {
|
||||||
String(String),
|
String(String),
|
||||||
Number(VMNumber),
|
Float(VMFloat),
|
||||||
|
Integer(LuaInteger),
|
||||||
RustFunction(Rc<RefCell<dyn RustFunction>>),
|
RustFunction(Rc<RefCell<dyn RustFunction>>),
|
||||||
Function(Closure),
|
Function(Closure),
|
||||||
Nil,
|
Nil,
|
||||||
@ -213,7 +225,8 @@ impl Value {
|
|||||||
pub fn as_indexable(self) -> Result<IndexableValue, RuntimeError> {
|
pub fn as_indexable(self) -> Result<IndexableValue, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Value::String(value) => Ok(IndexableValue::String(value)),
|
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) => {
|
Value::RustFunction(value) => {
|
||||||
Ok(IndexableValue::RustFunction(value.borrow().as_indexable()))
|
Ok(IndexableValue::RustFunction(value.borrow().as_indexable()))
|
||||||
}
|
}
|
||||||
@ -227,7 +240,8 @@ impl Value {
|
|||||||
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
#[derive(Debug, PartialEq, Eq, Hash, Clone)]
|
||||||
pub enum IndexableValue {
|
pub enum IndexableValue {
|
||||||
String(String),
|
String(String),
|
||||||
Number(VMNumber),
|
Number(VMFloat),
|
||||||
|
Integer(LuaInteger),
|
||||||
RustFunction(String),
|
RustFunction(String),
|
||||||
Function(u32),
|
Function(u32),
|
||||||
}
|
}
|
||||||
@ -235,9 +249,9 @@ pub enum IndexableValue {
|
|||||||
impl Value {
|
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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res = LuaNumber(lhs.lua_number().0 + rhs.lua_number().0);
|
let res = LuaFloat(lhs.lua_number().0 + rhs.lua_number().0);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidOperands(
|
_ => Err(RuntimeError::InvalidOperands(
|
||||||
BinaryOperator::Add,
|
BinaryOperator::Add,
|
||||||
@ -249,9 +263,9 @@ 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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res = LuaNumber((lhs == rhs) as u64 as f64);
|
let res = LuaFloat((lhs == rhs) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidOperands(
|
_ => Err(RuntimeError::InvalidOperands(
|
||||||
BinaryOperator::Equal,
|
BinaryOperator::Equal,
|
||||||
@ -263,9 +277,9 @@ 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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res = LuaNumber((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64);
|
let res = LuaFloat((lhs.lua_number().0 < rhs.lua_number().0) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidOperands(
|
_ => Err(RuntimeError::InvalidOperands(
|
||||||
BinaryOperator::LessThan,
|
BinaryOperator::LessThan,
|
||||||
@ -277,9 +291,9 @@ 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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res = LuaNumber((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64);
|
let res = LuaFloat((lhs.lua_number().0 <= rhs.lua_number().0) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidOperands(
|
_ => Err(RuntimeError::InvalidOperands(
|
||||||
BinaryOperator::LessThanOrEqual,
|
BinaryOperator::LessThanOrEqual,
|
||||||
@ -291,9 +305,9 @@ impl Value {
|
|||||||
|
|
||||||
pub fn unm(&self) -> Result<Value, RuntimeError> {
|
pub fn unm(&self) -> Result<Value, RuntimeError> {
|
||||||
match self {
|
match self {
|
||||||
Value::Number(lhs) => {
|
Value::Float(lhs) => {
|
||||||
let res = LuaNumber(-lhs.lua_number().0);
|
let res = LuaFloat(-lhs.lua_number().0);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Err(RuntimeError::InvalidOperand(
|
_ => Err(RuntimeError::InvalidOperand(
|
||||||
UnaryOperator::Negation,
|
UnaryOperator::Negation,
|
||||||
@ -305,14 +319,14 @@ impl Value {
|
|||||||
pub fn and(&self, other: &Value) -> Result<Value, RuntimeError> {
|
pub fn and(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||||
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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res =
|
let res =
|
||||||
LuaNumber((lhs.lua_number().0 > 0. && rhs.lua_number().0 > 0.) as u64 as f64);
|
LuaFloat((lhs.lua_number().0 > 0. && rhs.lua_number().0 > 0.) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
(Value::Number(value), _) | (_, Value::Number(value)) => {
|
(Value::Float(value), _) | (_, Value::Float(value)) => {
|
||||||
let res = LuaNumber((value.lua_number().0 > 0.) as u64 as f64);
|
let res = LuaFloat((value.lua_number().0 > 0.) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
_ => Ok(Value::Nil),
|
_ => Ok(Value::Nil),
|
||||||
}
|
}
|
||||||
@ -321,14 +335,14 @@ impl Value {
|
|||||||
pub fn or(&self, other: &Value) -> Result<Value, RuntimeError> {
|
pub fn or(&self, other: &Value) -> Result<Value, RuntimeError> {
|
||||||
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::Float(lhs), Value::Float(rhs)) => {
|
||||||
let res =
|
let res =
|
||||||
LuaNumber((lhs.lua_number().0 > 0. || rhs.lua_number().0 > 0.) as u64 as f64);
|
LuaFloat((lhs.lua_number().0 > 0. || rhs.lua_number().0 > 0.) as u64 as f64);
|
||||||
Ok(Value::Number(res.vm_number()))
|
Ok(Value::Float(res.vm_number()))
|
||||||
}
|
}
|
||||||
(Value::Number(value), other) => {
|
(Value::Float(value), other) => {
|
||||||
if value.lua_number().0 > 0. {
|
if value.lua_number().0 > 0. {
|
||||||
Ok(Value::Number(*value))
|
Ok(Value::Float(*value))
|
||||||
} else {
|
} else {
|
||||||
Ok(other.clone())
|
Ok(other.clone())
|
||||||
}
|
}
|
||||||
@ -342,7 +356,8 @@ 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.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::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
|
||||||
@ -567,7 +582,8 @@ impl ClosureRunner {
|
|||||||
*reg,
|
*reg,
|
||||||
StackValue::Value(match constants.get(*constant as usize).unwrap() {
|
StackValue::Value(match constants.get(*constant as usize).unwrap() {
|
||||||
Constant::String(value) => Value::String(value.clone()),
|
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())
|
.map(|v| v.borrow().clone())
|
||||||
.unwrap_or(Value::Nil)
|
.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,
|
_ => false,
|
||||||
};
|
};
|
||||||
if is_true {
|
if is_true {
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user