1
0

Pass tests

This commit is contained in:
Jeff 2024-09-24 11:40:12 -04:00
parent a6da34a79c
commit 855782c370
3 changed files with 51 additions and 32 deletions

View File

@ -731,7 +731,7 @@ impl<'src> Parser<'src> {
self.advance()?; self.advance()?;
self.parse_expression()?; self.parse_expression()?;
if matches!( let jump_position = if matches!(
self.chunk.get_last_n_operations(), self.chunk.get_last_n_operations(),
[ [
Some(Operation::LoadBoolean), Some(Operation::LoadBoolean),
@ -739,10 +739,22 @@ impl<'src> Parser<'src> {
Some(Operation::Jump) Some(Operation::Jump)
] ]
) { ) {
self.chunk.pop_instruction(self.current_position)?;
self.chunk.pop_instruction(self.current_position)?; self.chunk.pop_instruction(self.current_position)?;
self.chunk.pop_instruction(self.current_position)?; self.chunk.pop_instruction(self.current_position)?;
self.decrement_register()?; self.decrement_register()?;
self.chunk.pop_instruction(self.current_position)?.1
} else {
self.current_position
};
if let [Some(Operation::LoadBoolean)] = self.chunk.get_last_n_operations() {
let (mut load_boolean, load_boolean_position) =
self.chunk.pop_instruction(self.current_position)?;
load_boolean.set_second_argument_to_boolean(true);
self.emit_instruction(load_boolean, load_boolean_position);
self.increment_register()?;
} }
let jump_start = self.chunk.len(); let jump_start = self.chunk.len();
@ -752,10 +764,13 @@ impl<'src> Parser<'src> {
} }
let jump_end = self.chunk.len(); let jump_end = self.chunk.len();
let jump_instruction = Instruction::jump((jump_end - jump_start) as u8, true); let jump_distance = jump_end - jump_start;
self.chunk self.chunk.insert_instruction(
.insert_instruction(jump_start, jump_instruction, self.current_position); jump_start,
Instruction::jump(jump_distance as u8, true),
jump_position,
);
if self.allow(TokenKind::Else)? { if self.allow(TokenKind::Else)? {
if let Token::If = self.current_token { if let Token::If = self.current_token {

View File

@ -204,14 +204,16 @@ fn equality_assignment_long() {
.set_second_argument_to_constant(), .set_second_argument_to_constant(),
Span(13, 15) Span(13, 15)
), ),
(Instruction::jump(1, true), Span(13, 15)), (Instruction::jump(2, true), Span(13, 15)),
(Instruction::load_boolean(0, true, true), Span(13, 15)), (Instruction::load_boolean(0, true, false), Span(20, 24)),
(Instruction::load_boolean(0, false, false), Span(13, 15)), (Instruction::end(true), Span(25, 26)),
(Instruction::define_local(0, 0, false), Span(4, 5)), (Instruction::load_boolean(0, false, false), Span(34, 39)),
(Instruction::end(true), Span(40, 41)),
(Instruction::define_local(1, 0, false), Span(4, 5)),
(Instruction::end(false), Span(42, 42)), (Instruction::end(false), Span(42, 42)),
], ],
vec![Value::integer(4), Value::integer(4)], vec![Value::integer(4), Value::integer(4)],
vec![Local::new(Identifier::new("a"), false, 0, Some(0))] vec![Local::new(Identifier::new("a"), false, 0, Some(1))]
)), )),
); );
} }
@ -256,12 +258,12 @@ fn if_expression() {
.set_second_argument_to_constant(), .set_second_argument_to_constant(),
Span(5, 7) Span(5, 7)
), ),
(Instruction::jump(1, true), Span(5, 7)), (Instruction::jump(2, true), Span(5, 7)),
(Instruction::load_boolean(0, true, true), Span(5, 7)), (Instruction::load_constant(0, 2), Span(12, 13)),
(Instruction::load_boolean(0, false, false), Span(5, 7)), (Instruction::end(true), Span(14, 15)),
(Instruction::end(true), Span(15, 15)), (Instruction::end(true), Span(15, 15)),
], ],
vec![Value::integer(1), Value::integer(1)], vec![Value::integer(1), Value::integer(1), Value::integer(2)],
vec![] vec![]
)), )),
); );
@ -281,12 +283,19 @@ fn if_else_expression() {
.set_second_argument_to_constant(), .set_second_argument_to_constant(),
Span(5, 7) Span(5, 7)
), ),
(Instruction::jump(1, true), Span(5, 7)), (Instruction::jump(2, true), Span(5, 7)),
(Instruction::load_boolean(0, true, true), Span(5, 7)), (Instruction::load_constant(0, 2), Span(12, 13)),
(Instruction::load_boolean(0, false, false), Span(5, 7)), (Instruction::end(true), Span(14, 15)),
(Instruction::load_constant(0, 3), Span(23, 24)),
(Instruction::end(true), Span(25, 26)),
(Instruction::end(true), Span(26, 26)), (Instruction::end(true), Span(26, 26)),
], ],
vec![Value::integer(1), Value::integer(1)], vec![
Value::integer(1),
Value::integer(1),
Value::integer(2),
Value::integer(3)
],
vec![] vec![]
)), )),
); );

View File

@ -1,5 +1,3 @@
use log::debug;
use crate::{ use crate::{
parse, AnnotatedError, Chunk, ChunkError, DustError, Identifier, Instruction, Local, Operation, parse, AnnotatedError, Chunk, ChunkError, DustError, Identifier, Instruction, Local, Operation,
Span, Value, ValueError, Span, Value, ValueError,
@ -254,18 +252,15 @@ impl Vm {
Operation::Less => { Operation::Less => {
let (jump, _) = *self.chunk.get_instruction(self.ip, position)?; let (jump, _) = *self.chunk.get_instruction(self.ip, position)?;
assert_eq!(jump.operation(), Operation::Jump); debug_assert_eq!(jump.operation(), Operation::Jump);
let (left, right) = get_arguments(self, instruction, position)?; let (left, right) = get_arguments(self, instruction, position)?;
let less = left
.less_than(right)
.map_err(|error| VmError::Value { error, position })?;
let boolean = left let boolean = left
.equal(right) .less_than(right)
.map_err(|error| VmError::Value { error, position })? .map_err(|error| VmError::Value { error, position })?
.as_boolean() .as_boolean()
.ok_or_else(|| VmError::ExpectedBoolean { .ok_or_else(|| VmError::ExpectedBoolean {
found: less, found: left.clone(),
position, position,
})?; })?;
let compare_to = instruction.destination_as_boolean(); let compare_to = instruction.destination_as_boolean();
@ -285,17 +280,17 @@ impl Vm {
} }
} }
Operation::LessEqual => { Operation::LessEqual => {
let (jump, _) = *self.read(position)?; let (jump, _) = *self.chunk.get_instruction(self.ip, position)?;
debug_assert_eq!(jump.operation(), Operation::Jump);
let (left, right) = get_arguments(self, instruction, position)?; let (left, right) = get_arguments(self, instruction, position)?;
let less_or_equal = left
.less_than_or_equal(right)
.map_err(|error| VmError::Value { error, position })?;
let boolean = left let boolean = left
.equal(right) .less_than_or_equal(right)
.map_err(|error| VmError::Value { error, position })? .map_err(|error| VmError::Value { error, position })?
.as_boolean() .as_boolean()
.ok_or_else(|| VmError::ExpectedBoolean { .ok_or_else(|| VmError::ExpectedBoolean {
found: less_or_equal, found: left.clone(),
position, position,
})?; })?;
let compare_to = instruction.destination_as_boolean(); let compare_to = instruction.destination_as_boolean();