1
0

Refactor how return instruction works; Begin passing tests

This commit is contained in:
Jeff 2024-10-04 22:33:47 -04:00
parent 5411a1db27
commit 5015cf4cc4
3 changed files with 33 additions and 26 deletions

View File

@ -814,14 +814,14 @@ impl<'src> Parser<'src> {
match self.current_token { match self.current_token {
Token::Let => { Token::Let => {
self.parse_let_statement(true, allow_return)?; self.parse_let_statement(true, allow_return)?;
self.allow(TokenKind::Semicolon)?;
} }
Token::LeftCurlyBrace => { Token::LeftCurlyBrace => {
self.parse_block(true, true)?; self.parse_block(true, true)?;
self.allow(TokenKind::Semicolon)?;
} }
_ => { _ => {
self.parse_expression()?; self.parse_expression()?;
}
};
if !self.allow(TokenKind::Semicolon)? && self.is_eof() { if !self.allow(TokenKind::Semicolon)? && self.is_eof() {
let register = self.current_register.saturating_sub(1); let register = self.current_register.saturating_sub(1);
@ -831,6 +831,8 @@ impl<'src> Parser<'src> {
self.current_position, self.current_position,
); );
} }
}
};
Ok(()) Ok(())
} }

View File

@ -364,13 +364,11 @@ impl Vm {
self.ip = new_ip; self.ip = new_ip;
} }
Operation::Return => { Operation::Return => {
let start_register = instruction.a(); return if let Some(Some(value)) = self.register_stack.pop() {
let end_register = instruction.b(); Ok(Some(value))
let return_value_count = (end_register - start_register).max(1); } else {
Ok(None)
if return_value_count == 1 { };
return Ok(Some(self.take(start_register, position)?));
}
} }
} }
} }

View File

@ -32,6 +32,7 @@ fn and() {
(Instruction::test(0, false), Span(5, 7)), (Instruction::test(0, false), Span(5, 7)),
(Instruction::jump(1, true), Span(5, 7)), (Instruction::jump(1, true), Span(5, 7)),
(Instruction::load_boolean(1, false, false), Span(8, 13)), (Instruction::load_boolean(1, false, false), Span(8, 13)),
(Instruction::r#return(0, 0), Span(13, 13)),
], ],
vec![], vec![],
vec![] vec![]
@ -95,7 +96,10 @@ fn constant() {
assert_eq!( assert_eq!(
parse("42"), parse("42"),
Ok(Chunk::with_data( Ok(Chunk::with_data(
vec![(Instruction::load_constant(0, 0, false), Span(0, 2)),], vec![
(Instruction::load_constant(0, 0, false), Span(0, 2)),
(Instruction::r#return(0, 0), Span(2, 2))
],
vec![Value::integer(42)], vec![Value::integer(42)],
vec![] vec![]
)) ))
@ -124,20 +128,23 @@ fn define_local() {
#[test] #[test]
fn divide() { fn divide() {
assert_eq!( assert_eq!(
parse("1.0 / 2.0"), parse("2 / 2"),
Ok(Chunk::with_data( Ok(Chunk::with_data(
vec![( vec![
(
*Instruction::divide(0, 0, 1) *Instruction::divide(0, 0, 1)
.set_b_is_constant() .set_b_is_constant()
.set_c_is_constant(), .set_c_is_constant(),
Span(2, 3) Span(2, 3)
),], ),
vec![Value::integer(1), Value::integer(2)], (Instruction::r#return(0, 0), Span(5, 5))
],
vec![Value::integer(2), Value::integer(2)],
vec![] vec![]
)) ))
); );
assert_eq!(run("1 / 2"), Ok(Some(Value::float(0.5)))); assert_eq!(run("2 / 2"), Ok(Some(Value::integer(1))));
} }
#[test] #[test]