diff --git a/dust-lang/src/parser/mod.rs b/dust-lang/src/parser/mod.rs index cdfa649..95e4db2 100644 --- a/dust-lang/src/parser/mod.rs +++ b/dust-lang/src/parser/mod.rs @@ -482,20 +482,14 @@ impl<'src> Parser<'src> { previous_instruction.set_destination(register_index); self.emit_instruction(previous_instruction, self.current_position); - } else { - self.emit_instruction(previous_instruction, previous_position); - self.emit_instruction( - Instruction::set_local(self.current_register - 1, local_index), - self.current_position, - ); } - } else { - self.emit_instruction(previous_instruction, previous_position); - self.emit_instruction( - Instruction::set_local(self.current_register - 1, local_index), - start_position, - ); } + + self.emit_instruction(previous_instruction, previous_position); + self.emit_instruction( + Instruction::set_local(self.current_register - 1, local_index), + start_position, + ); } else { self.emit_instruction( Instruction::get_local(self.current_register, local_index), @@ -595,6 +589,14 @@ impl<'src> Parser<'src> { Ok(()) } + fn parse_while(&mut self, allow_assignment: bool) -> Result<(), ParseError> { + self.advance()?; + self.parse_expression()?; + self.parse_block(allow_assignment)?; + + Ok(()) + } + fn parse_expression(&mut self) -> Result<(), ParseError> { self.parse(Precedence::None) } @@ -853,7 +855,11 @@ impl From<&TokenKind> for ParseRule<'_> { TokenKind::Loop => todo!(), TokenKind::Map => todo!(), TokenKind::Str => todo!(), - TokenKind::While => todo!(), + TokenKind::While => ParseRule { + prefix: Some(Parser::parse_while), + infix: None, + precedence: Precedence::None, + }, TokenKind::BangEqual => todo!(), TokenKind::Bang => ParseRule { prefix: Some(Parser::parse_unary), diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 48cb072..a5f71a8 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -1,6 +1,6 @@ use crate::{ - dust_error::AnnotatedError, parse, Chunk, ChunkError, DustError, Identifier, Instruction, - Local, Operation, Span, Value, ValueError, + parse, AnnotatedError, Chunk, ChunkError, DustError, Identifier, Instruction, Local, Operation, + Span, Value, ValueError, }; pub fn run(source: &str) -> Result, DustError> { @@ -35,11 +35,12 @@ impl Vm { } pub fn run(&mut self) -> Result, VmError> { - // DRY helper closure to take a constant or clone a register - let take_constants_or_clone = |vm: &mut Vm, - instruction: Instruction, - position: Span| - -> Result<(Value, Value), VmError> { + // DRY helper to take constants or clone registers for binary operations + fn take_constants_or_clone( + vm: &mut Vm, + instruction: Instruction, + position: Span, + ) -> Result<(Value, Value), VmError> { let left = if instruction.first_argument_is_constant() { vm.chunk .take_constant(instruction.first_argument(), position)? @@ -54,7 +55,7 @@ impl Vm { }; Ok((left, right)) - }; + } while let Ok((instruction, position)) = self.read(Span(0, 0)).copied() { log::trace!("Running instruction {instruction} at {position}");