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' \
|
||||
'node 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_register = self.next_register();
|
||||
|
||||
self.advance()?;
|
||||
self.expect(Token::LeftParenthesis)?;
|
||||
|
||||
while !self.allow(Token::RightParenthesis)? {
|
||||
@ -1614,7 +1615,6 @@ impl<'src> Compiler<'src> {
|
||||
let start = self.current_position.0;
|
||||
|
||||
self.advance()?;
|
||||
self.expect(Token::LeftParenthesis)?;
|
||||
|
||||
let mut argument_count = 0;
|
||||
|
||||
|
@ -90,6 +90,33 @@ impl ConcreteValue {
|
||||
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> {
|
||||
use ConcreteValue::*;
|
||||
|
||||
|
@ -38,6 +38,13 @@ impl Value {
|
||||
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 {
|
||||
|
@ -1,6 +1,5 @@
|
||||
//! Virtual machine and errors
|
||||
use std::{
|
||||
cmp::Ordering,
|
||||
fmt::{self, Display, Formatter},
|
||||
io,
|
||||
};
|
||||
@ -37,8 +36,6 @@ pub struct Vm<'a> {
|
||||
}
|
||||
|
||||
impl<'a> Vm<'a> {
|
||||
const STACK_LIMIT: u16 = u16::MAX;
|
||||
|
||||
pub fn new(chunk: &'a Chunk, parent: Option<&'a Vm<'a>>) -> Self {
|
||||
Self {
|
||||
chunk,
|
||||
@ -647,42 +644,14 @@ impl<'a> Vm<'a> {
|
||||
|
||||
#[inline(always)]
|
||||
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);
|
||||
|
||||
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(())
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user