diff --git a/dust-lang/src/parser.rs b/dust-lang/src/parser.rs index 7abbd44..34317aa 100644 --- a/dust-lang/src/parser.rs +++ b/dust-lang/src/parser.rs @@ -814,24 +814,26 @@ impl<'src> Parser<'src> { match self.current_token { Token::Let => { self.parse_let_statement(true, allow_return)?; + self.allow(TokenKind::Semicolon)?; } Token::LeftCurlyBrace => { self.parse_block(true, true)?; + self.allow(TokenKind::Semicolon)?; } _ => { self.parse_expression()?; + + if !self.allow(TokenKind::Semicolon)? && self.is_eof() { + let register = self.current_register.saturating_sub(1); + + self.emit_instruction( + Instruction::r#return(register, register), + self.current_position, + ); + } } }; - if !self.allow(TokenKind::Semicolon)? && self.is_eof() { - let register = self.current_register.saturating_sub(1); - - self.emit_instruction( - Instruction::r#return(register, register), - self.current_position, - ); - } - Ok(()) } diff --git a/dust-lang/src/vm.rs b/dust-lang/src/vm.rs index 89e43dd..bd2c912 100644 --- a/dust-lang/src/vm.rs +++ b/dust-lang/src/vm.rs @@ -364,13 +364,11 @@ impl Vm { self.ip = new_ip; } Operation::Return => { - let start_register = instruction.a(); - let end_register = instruction.b(); - let return_value_count = (end_register - start_register).max(1); - - if return_value_count == 1 { - return Ok(Some(self.take(start_register, position)?)); - } + return if let Some(Some(value)) = self.register_stack.pop() { + Ok(Some(value)) + } else { + Ok(None) + }; } } } diff --git a/dust-lang/tests/expressions.rs b/dust-lang/tests/expressions.rs index aa59275..b504989 100644 --- a/dust-lang/tests/expressions.rs +++ b/dust-lang/tests/expressions.rs @@ -32,6 +32,7 @@ fn and() { (Instruction::test(0, false), Span(5, 7)), (Instruction::jump(1, true), Span(5, 7)), (Instruction::load_boolean(1, false, false), Span(8, 13)), + (Instruction::r#return(0, 0), Span(13, 13)), ], vec![], vec![] @@ -95,7 +96,10 @@ fn constant() { assert_eq!( parse("42"), 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![] )) @@ -124,20 +128,23 @@ fn define_local() { #[test] fn divide() { assert_eq!( - parse("1.0 / 2.0"), + parse("2 / 2"), Ok(Chunk::with_data( - vec![( - *Instruction::divide(0, 0, 1) - .set_b_is_constant() - .set_c_is_constant(), - Span(2, 3) - ),], - vec![Value::integer(1), Value::integer(2)], + vec![ + ( + *Instruction::divide(0, 0, 1) + .set_b_is_constant() + .set_c_is_constant(), + Span(2, 3) + ), + (Instruction::r#return(0, 0), Span(5, 5)) + ], + vec![Value::integer(2), Value::integer(2)], vec![] )) ); - assert_eq!(run("1 / 2"), Ok(Some(Value::float(0.5)))); + assert_eq!(run("2 / 2"), Ok(Some(Value::integer(1)))); } #[test]