1
0
This commit is contained in:
Jeff 2024-11-05 16:25:55 -05:00
parent cfb4fa66b5
commit 5ff5568e95
2 changed files with 56 additions and 61 deletions

View File

@ -234,6 +234,16 @@ impl<'src> Parser<'src> {
self.current_statement_length = 0; self.current_statement_length = 0;
} }
fn pop_last_instruction(&mut self) -> Result<(Instruction, Span), ParseError> {
self.chunk
.instructions_mut()
.pop()
.ok_or_else(|| ParseError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: self.previous_position,
})
}
fn get_last_value_operation(&self) -> Option<Operation> { fn get_last_value_operation(&self) -> Option<Operation> {
self.chunk self.chunk
.instructions() .instructions()
@ -475,15 +485,7 @@ impl<'src> Parser<'src> {
self.advance()?; self.advance()?;
self.parse_expression()?; self.parse_expression()?;
let (previous_instruction, previous_position) = self let (previous_instruction, previous_position) = self.pop_last_instruction()?;
.chunk
.instructions_mut()
.pop()
.ok_or_else(|| ParseError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: self.previous_position,
})?;
let (push_back, is_constant, argument) = { let (push_back, is_constant, argument) = {
match previous_instruction.operation() { match previous_instruction.operation() {
Operation::GetLocal => (false, false, previous_instruction.a()), Operation::GetLocal => (false, false, previous_instruction.a()),
@ -601,14 +603,7 @@ impl<'src> Parser<'src> {
self.advance()?; self.advance()?;
self.parse_sub_expression(&rule.precedence)?; self.parse_sub_expression(&rule.precedence)?;
let (right_instruction, right_position) = let (right_instruction, right_position) = self.pop_last_instruction()?;
self.chunk
.instructions_mut()
.pop()
.ok_or_else(|| ParseError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: self.previous_position,
})?;
let (push_back_right, right_is_constant, _, right) = let (push_back_right, right_is_constant, _, right) =
self.handle_binary_argument(&right_instruction)?; self.handle_binary_argument(&right_instruction)?;
@ -775,15 +770,7 @@ impl<'src> Parser<'src> {
fn parse_logical_binary(&mut self) -> Result<(), ParseError> { fn parse_logical_binary(&mut self) -> Result<(), ParseError> {
let start_length = self.chunk.len(); let start_length = self.chunk.len();
let (left_instruction, left_position) = let (left_instruction, left_position) = self.pop_last_instruction()?;
self.chunk
.instructions_mut()
.pop()
.ok_or_else(|| ParseError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: self.previous_position,
})?;
let operator = self.current_token; let operator = self.current_token;
let operator_position = self.current_position; let operator_position = self.current_position;
let rule = ParseRule::from(&operator); let rule = ParseRule::from(&operator);
@ -961,7 +948,7 @@ impl<'src> Parser<'src> {
self.chunk.begin_scope(); self.chunk.begin_scope();
while !self.allow(Token::RightCurlyBrace)? && !self.is_eof() { while !self.allow(Token::RightCurlyBrace)? && !self.is_eof() {
self.parse_statement(allowed)?; self.parse(Precedence::None, allowed)?;
} }
self.chunk.end_scope(); self.chunk.end_scope();
@ -1231,10 +1218,13 @@ impl<'src> Parser<'src> {
fn parse_top_level(&mut self) -> Result<(), ParseError> { fn parse_top_level(&mut self) -> Result<(), ParseError> {
loop { loop {
self.parse_statement(Allowed { self.parse(
Precedence::None,
Allowed {
assignment: true, assignment: true,
explicit_return: false, explicit_return: false,
})?; },
)?;
if self.is_eof() || self.allow(Token::RightCurlyBrace)? { if self.is_eof() || self.allow(Token::RightCurlyBrace)? {
self.parse_implicit_return()?; self.parse_implicit_return()?;
@ -1246,16 +1236,6 @@ impl<'src> Parser<'src> {
Ok(()) Ok(())
} }
fn parse_statement(&mut self, allowed: Allowed) -> Result<(), ParseError> {
self.parse(Precedence::None, allowed)?;
if self.allow(Token::Semicolon)? {
self.current_is_expression = false;
}
Ok(())
}
fn parse_expression(&mut self) -> Result<(), ParseError> { fn parse_expression(&mut self) -> Result<(), ParseError> {
self.parse( self.parse(
Precedence::None, Precedence::None,
@ -1263,7 +1243,16 @@ impl<'src> Parser<'src> {
assignment: false, assignment: false,
explicit_return: false, explicit_return: false,
}, },
) )?;
if !self.current_is_expression || self.chunk.is_empty() {
return Err(ParseError::ExpectedExpression {
found: self.previous_token.to_owned(),
position: self.current_position,
});
}
Ok(())
} }
fn parse_sub_expression(&mut self, precedence: &Precedence) -> Result<(), ParseError> { fn parse_sub_expression(&mut self, precedence: &Precedence) -> Result<(), ParseError> {
@ -1502,11 +1491,13 @@ impl<'src> Parser<'src> {
} }
fn parse_call(&mut self) -> Result<(), ParseError> { fn parse_call(&mut self) -> Result<(), ParseError> {
let (last_instruction, _) = self.chunk.instructions().last().copied().ok_or_else(|| { let (last_instruction, _) =
ParseError::ExpectedExpression { self.chunk
.instructions()
.last()
.ok_or_else(|| ParseError::ExpectedExpression {
found: self.previous_token.to_owned(), found: self.previous_token.to_owned(),
position: self.previous_position, position: self.previous_position,
}
})?; })?;
if !last_instruction.yields_value() { if !last_instruction.yields_value() {
@ -1552,16 +1543,20 @@ impl<'src> Parser<'src> {
Ok(()) Ok(())
} }
fn expect_expression(&mut self, _: Allowed) -> Result<(), ParseError> { fn parse_semicolon(&mut self, _: Allowed) -> Result<(), ParseError> {
if self.current_token.is_expression() { self.advance()?;
self.current_is_expression = false;
Ok(()) Ok(())
} else { }
fn expect_expression(&mut self, _: Allowed) -> Result<(), ParseError> {
Err(ParseError::ExpectedExpression { Err(ParseError::ExpectedExpression {
found: self.current_token.to_owned(), found: self.current_token.to_owned(),
position: self.current_position, position: self.current_position,
}) })
} }
}
fn parse(&mut self, precedence: Precedence, allowed: Allowed) -> Result<(), ParseError> { fn parse(&mut self, precedence: Precedence, allowed: Allowed) -> Result<(), ParseError> {
if let Some(prefix_parser) = ParseRule::from(&self.current_token).prefix { if let Some(prefix_parser) = ParseRule::from(&self.current_token).prefix {
@ -1887,7 +1882,7 @@ impl From<&Token<'_>> for ParseRule<'_> {
precedence: Precedence::None, precedence: Precedence::None,
}, },
Token::Semicolon => ParseRule { Token::Semicolon => ParseRule {
prefix: Some(Parser::expect_expression), prefix: Some(Parser::parse_semicolon),
infix: None, infix: None,
precedence: Precedence::None, precedence: Precedence::None,
}, },

View File

@ -1,7 +1,7 @@
use dust_lang::*; use dust_lang::*;
#[test] #[test]
fn add_assign_expects_variable() { fn add_assign_expects_mutable_variable() {
let source = "1 += 2"; let source = "1 += 2";
assert_eq!( assert_eq!(
@ -17,7 +17,7 @@ fn add_assign_expects_variable() {
} }
#[test] #[test]
fn divide_assign_expects_variable() { fn divide_assign_expects_mutable_variable() {
let source = "1 -= 2"; let source = "1 -= 2";
assert_eq!( assert_eq!(
@ -33,7 +33,7 @@ fn divide_assign_expects_variable() {
} }
#[test] #[test]
fn multiply_assign_expects_variable() { fn multiply_assign_expects_mutable_variable() {
let source = "1 *= 2"; let source = "1 *= 2";
assert_eq!( assert_eq!(
@ -49,7 +49,7 @@ fn multiply_assign_expects_variable() {
} }
#[test] #[test]
fn subtract_assign_expects_variable() { fn subtract_assign_expects_mutable_variable() {
let source = "1 -= 2"; let source = "1 -= 2";
assert_eq!( assert_eq!(