Fix a parsing bug; Add a benchmark for lua
This commit is contained in:
parent
8ef54bd60a
commit
19c6a4d42a
5
bench/assets/count_to_one_million.lua
Normal file
5
bench/assets/count_to_one_million.lua
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
local i = 1
|
||||||
|
|
||||||
|
while i < 1000000 do
|
||||||
|
i = i + 1
|
||||||
|
end
|
@ -4,4 +4,5 @@ hyperfine \
|
|||||||
'../target/release/dust assets/count_to_one_million.ds' \
|
'../target/release/dust assets/count_to_one_million.ds' \
|
||||||
'node assets/count_to_one_million.js' \
|
'node assets/count_to_one_million.js' \
|
||||||
'deno assets/count_to_one_million.js' \
|
'deno assets/count_to_one_million.js' \
|
||||||
'python assets/count_to_one_million.py'
|
'python assets/count_to_one_million.py' \
|
||||||
|
'lua assets/count_to_one_million.lua'
|
@ -1279,6 +1279,7 @@ impl<'src> Compiler<'src> {
|
|||||||
let start = self.previous_position.0;
|
let start = self.previous_position.0;
|
||||||
let start_register = self.next_register();
|
let start_register = self.next_register();
|
||||||
|
|
||||||
|
self.advance()?;
|
||||||
self.expect(Token::LeftParenthesis)?;
|
self.expect(Token::LeftParenthesis)?;
|
||||||
|
|
||||||
while !self.allow(Token::RightParenthesis)? {
|
while !self.allow(Token::RightParenthesis)? {
|
||||||
@ -1614,7 +1615,6 @@ impl<'src> Compiler<'src> {
|
|||||||
let start = self.current_position.0;
|
let start = self.current_position.0;
|
||||||
|
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
self.expect(Token::LeftParenthesis)?;
|
|
||||||
|
|
||||||
let mut argument_count = 0;
|
let mut argument_count = 0;
|
||||||
|
|
||||||
|
@ -90,6 +90,33 @@ impl ConcreteValue {
|
|||||||
Ok(sum)
|
Ok(sum)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_assign(&mut self, other: &Self) -> Result<(), ValueError> {
|
||||||
|
use ConcreteValue::*;
|
||||||
|
|
||||||
|
match (self, other) {
|
||||||
|
(Integer(left), Integer(right)) => {
|
||||||
|
*left += right;
|
||||||
|
}
|
||||||
|
(Float(left), Float(right)) => {
|
||||||
|
*left += right;
|
||||||
|
}
|
||||||
|
(String(left), String(right)) => {
|
||||||
|
*left += right;
|
||||||
|
}
|
||||||
|
(String(left), Character(right)) => {
|
||||||
|
*left += &right.to_string();
|
||||||
|
}
|
||||||
|
(left, right) => {
|
||||||
|
return Err(ValueError::CannotAdd(
|
||||||
|
left.clone().to_value(),
|
||||||
|
right.clone().to_value(),
|
||||||
|
))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|
||||||
pub fn subtract(&self, other: &Self) -> Result<ConcreteValue, ValueError> {
|
pub fn subtract(&self, other: &Self) -> Result<ConcreteValue, ValueError> {
|
||||||
use ConcreteValue::*;
|
use ConcreteValue::*;
|
||||||
|
|
||||||
|
@ -38,6 +38,13 @@ impl Value {
|
|||||||
Value::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
Value::Concrete(concrete_value) => Ok(concrete_value.to_string()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn add_assign(&mut self, other: ValueRef) -> Result<(), ValueError> {
|
||||||
|
match (self, other) {
|
||||||
|
(Value::Concrete(left), ValueRef::Concrete(right)) => left.add_assign(right),
|
||||||
|
(left, right) => Err(ValueError::CannotAdd(left.clone(), right.to_owned())),
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Display for Value {
|
impl Display for Value {
|
||||||
|
@ -1,6 +1,5 @@
|
|||||||
//! Virtual machine and errors
|
//! Virtual machine and errors
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Ordering,
|
|
||||||
fmt::{self, Display, Formatter},
|
fmt::{self, Display, Formatter},
|
||||||
io,
|
io,
|
||||||
};
|
};
|
||||||
@ -37,8 +36,6 @@ pub struct Vm<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> Vm<'a> {
|
impl<'a> Vm<'a> {
|
||||||
const STACK_LIMIT: u16 = u16::MAX;
|
|
||||||
|
|
||||||
pub fn new(chunk: &'a Chunk, parent: Option<&'a Vm<'a>>) -> Self {
|
pub fn new(chunk: &'a Chunk, parent: Option<&'a Vm<'a>>) -> Self {
|
||||||
Self {
|
Self {
|
||||||
chunk,
|
chunk,
|
||||||
@ -647,42 +644,14 @@ impl<'a> Vm<'a> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn set_register(&mut self, to_register: u16, register: Register) -> Result<(), VmError> {
|
fn set_register(&mut self, to_register: u16, register: Register) -> Result<(), VmError> {
|
||||||
let length = self.stack.len() as u16;
|
|
||||||
|
|
||||||
if length == Self::STACK_LIMIT {
|
|
||||||
return Err(VmError::StackOverflow {
|
|
||||||
position: self.current_position,
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
match to_register.cmp(&length) {
|
|
||||||
Ordering::Less => {
|
|
||||||
log::trace!("Change R{to_register} to {register}");
|
|
||||||
|
|
||||||
self.stack[to_register as usize] = register;
|
|
||||||
}
|
|
||||||
Ordering::Equal => {
|
|
||||||
log::trace!("Set R{to_register} to {register}");
|
|
||||||
|
|
||||||
self.stack.push(register);
|
|
||||||
}
|
|
||||||
Ordering::Greater => {
|
|
||||||
let difference = to_register - length;
|
|
||||||
|
|
||||||
for index in 0..difference {
|
|
||||||
log::trace!("Set R{index} to {register}");
|
|
||||||
|
|
||||||
self.stack.push(Register::Empty);
|
|
||||||
}
|
|
||||||
|
|
||||||
log::trace!("Set R{to_register} to {register}");
|
|
||||||
|
|
||||||
self.stack.push(register);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.last_assigned_register = Some(to_register);
|
self.last_assigned_register = Some(to_register);
|
||||||
|
|
||||||
|
let to_register = to_register as usize;
|
||||||
|
|
||||||
|
assert!(self.stack.len() > to_register); // Compiler hint to avoid bounds check
|
||||||
|
|
||||||
|
self.stack[to_register] = register;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user