diff --git a/bench/assets/count_to_one_million.lua b/bench/assets/count_to_one_million.lua new file mode 100644 index 0000000..41b94f7 --- /dev/null +++ b/bench/assets/count_to_one_million.lua @@ -0,0 +1,5 @@ +local i = 1 + +while i < 1000000 do + i = i + 1 +end diff --git a/bench/count_one_one_million.sh b/bench/count_to_one_million.sh similarity index 69% rename from bench/count_one_one_million.sh rename to bench/count_to_one_million.sh index 020075a..3f27f55 100644 --- a/bench/count_one_one_million.sh +++ b/bench/count_to_one_million.sh @@ -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' diff --git a/dust-lang/src/compiler.rs b/dust-lang/src/compiler.rs index 8d8e1ef..8684de9 100644 --- a/dust-lang/src/compiler.rs +++ b/dust-lang/src/compiler.rs @@ -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; diff --git a/dust-lang/src/value/concrete_value.rs b/dust-lang/src/value/concrete_value.rs index 3b3de31..b74e55b 100644 --- a/dust-lang/src/value/concrete_value.rs +++ b/dust-lang/src/value/concrete_value.rs @@ -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 { use ConcreteValue::*; diff --git a/dust-lang/src/value/mod.rs b/dust-lang/src/value/mod.rs index 47079f9..2049ebd 100644 --- a/dust-lang/src/value/mod.rs +++ b/dust-lang/src/value/mod.rs @@ -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 { diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 518c7d4..a117706 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -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(()) }