1
0

Fix a parsing bug; Add a benchmark for lua

This commit is contained in:
Jeff 2024-12-04 02:52:09 -05:00
parent 8ef54bd60a
commit 19c6a4d42a
6 changed files with 48 additions and 39 deletions

View File

@ -0,0 +1,5 @@
local i = 1
while i < 1000000 do
i = i + 1
end

View File

@ -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'

View File

@ -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;

View File

@ -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::*;

View File

@ -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 {

View File

@ -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(())
} }