Avoid emitting duplicate return instructions; Clean up
This commit is contained in:
parent
02877d06d3
commit
f1034534ed
@ -90,20 +90,6 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn _decrement_register(&mut self) -> Result<(), ParseError> {
|
|
||||||
let current = self.current_register;
|
|
||||||
|
|
||||||
if current == 0 {
|
|
||||||
Err(ParseError::RegisterUnderflow {
|
|
||||||
position: self.current_position,
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
self.current_register -= 1;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn advance(&mut self) -> Result<(), ParseError> {
|
fn advance(&mut self) -> Result<(), ParseError> {
|
||||||
if self.is_eof() {
|
if self.is_eof() {
|
||||||
return Ok(());
|
return Ok(());
|
||||||
@ -167,28 +153,28 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn parse_boolean(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_boolean(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
let boolean_text = if let Token::Boolean(text) = self.current_token {
|
let position = self.current_position;
|
||||||
text
|
|
||||||
|
if let Token::Boolean(text) = self.current_token {
|
||||||
|
self.advance()?;
|
||||||
|
|
||||||
|
let boolean = text.parse::<bool>().unwrap();
|
||||||
|
|
||||||
|
self.emit_instruction(
|
||||||
|
Instruction::load_boolean(self.current_register, boolean, false),
|
||||||
|
position,
|
||||||
|
);
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
return Err(ParseError::ExpectedToken {
|
Err(ParseError::ExpectedToken {
|
||||||
expected: TokenKind::Boolean,
|
expected: TokenKind::Boolean,
|
||||||
found: self.current_token.to_owned(),
|
found: self.current_token.to_owned(),
|
||||||
position: self.current_position,
|
position,
|
||||||
});
|
})
|
||||||
};
|
}
|
||||||
|
|
||||||
let position = self.current_position;
|
|
||||||
let boolean = boolean_text.parse::<bool>().unwrap();
|
|
||||||
|
|
||||||
self.advance()?;
|
|
||||||
self.emit_instruction(
|
|
||||||
Instruction::load_boolean(self.current_register, boolean, false),
|
|
||||||
position,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_byte(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_byte(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -197,19 +183,22 @@ impl<'src> Parser<'src> {
|
|||||||
if let Token::Byte(text) = self.current_token {
|
if let Token::Byte(text) = self.current_token {
|
||||||
self.advance()?;
|
self.advance()?;
|
||||||
|
|
||||||
let byte =
|
let byte = u8::from_str_radix(&text[2..], 16)
|
||||||
u8::from_str_radix(&text[2..], 16).map_err(|error| ParseError::ParseIntError {
|
.map_err(|error| ParseError::ParseIntError { error, position })?;
|
||||||
error,
|
|
||||||
position: self.previous_position,
|
|
||||||
})?;
|
|
||||||
let value = Value::byte(byte);
|
let value = Value::byte(byte);
|
||||||
|
|
||||||
self.emit_constant(value, position)?;
|
self.emit_constant(value, position)?;
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::Byte,
|
||||||
|
found: self.current_token.to_owned(),
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_character(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_character(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -221,11 +210,17 @@ impl<'src> Parser<'src> {
|
|||||||
let value = Value::character(character);
|
let value = Value::character(character);
|
||||||
|
|
||||||
self.emit_constant(value, position)?;
|
self.emit_constant(value, position)?;
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::Character,
|
||||||
|
found: self.current_token.to_owned(),
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_float(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_float(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -243,11 +238,17 @@ impl<'src> Parser<'src> {
|
|||||||
let value = Value::float(float);
|
let value = Value::float(float);
|
||||||
|
|
||||||
self.emit_constant(value, position)?;
|
self.emit_constant(value, position)?;
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::Float,
|
||||||
|
found: self.current_token.to_owned(),
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_integer(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_integer(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -265,11 +266,17 @@ impl<'src> Parser<'src> {
|
|||||||
let value = Value::integer(integer);
|
let value = Value::integer(integer);
|
||||||
|
|
||||||
self.emit_constant(value, position)?;
|
self.emit_constant(value, position)?;
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::Integer,
|
||||||
|
found: self.current_token.to_owned(),
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_string(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_string(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -281,11 +288,17 @@ impl<'src> Parser<'src> {
|
|||||||
let value = Value::string(text);
|
let value = Value::string(text);
|
||||||
|
|
||||||
self.emit_constant(value, position)?;
|
self.emit_constant(value, position)?;
|
||||||
|
|
||||||
|
self.parsed_expression = true;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
} else {
|
||||||
|
Err(ParseError::ExpectedToken {
|
||||||
|
expected: TokenKind::String,
|
||||||
|
found: self.current_token.to_owned(),
|
||||||
|
position,
|
||||||
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
self.parsed_expression = true;
|
|
||||||
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn parse_grouped(&mut self, _: Allowed) -> Result<(), ParseError> {
|
fn parse_grouped(&mut self, _: Allowed) -> Result<(), ParseError> {
|
||||||
@ -934,13 +947,15 @@ impl<'src> Parser<'src> {
|
|||||||
fn parse_statement(&mut self, allowed: Allowed, context: Context) -> Result<(), ParseError> {
|
fn parse_statement(&mut self, allowed: Allowed, context: Context) -> Result<(), ParseError> {
|
||||||
self.parse(Precedence::None, allowed)?;
|
self.parse(Precedence::None, allowed)?;
|
||||||
|
|
||||||
if let [Some((jump, _)), Some((comparison, comparison_position))] =
|
let previous_instructions = self.chunk.get_last_n_instructions();
|
||||||
self.chunk.get_last_n_instructions()
|
|
||||||
{
|
if let [Some((jump, _)), Some((comparison, comparison_position))] = previous_instructions {
|
||||||
if let (Operation::Jump, Operation::Equal | Operation::Less | Operation::LessEqual) =
|
if let (Operation::Jump, Operation::Equal | Operation::Less | Operation::LessEqual) =
|
||||||
(jump.operation(), comparison.operation())
|
(jump.operation(), comparison.operation())
|
||||||
{
|
{
|
||||||
if matches!(self.current_token, Token::Eof) || context == Context::Assignment {
|
if matches!(self.current_token, Token::Eof | Token::RightCurlyBrace)
|
||||||
|
|| context == Context::Assignment
|
||||||
|
{
|
||||||
let comparison_position = *comparison_position;
|
let comparison_position = *comparison_position;
|
||||||
|
|
||||||
self.emit_instruction(
|
self.emit_instruction(
|
||||||
@ -955,9 +970,10 @@ impl<'src> Parser<'src> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
let returned = self.chunk.get_last_operation()? == Operation::Return;
|
||||||
let has_semicolon = self.allow(Token::Semicolon)?;
|
let has_semicolon = self.allow(Token::Semicolon)?;
|
||||||
|
|
||||||
if !has_semicolon && self.parsed_expression && allowed.implicit_return {
|
if allowed.implicit_return && self.parsed_expression && !returned && !has_semicolon {
|
||||||
self.emit_instruction(Instruction::r#return(true), self.current_position);
|
self.emit_instruction(Instruction::r#return(true), self.current_position);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1248,8 +1264,8 @@ struct ParseRule<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl From<&Token<'_>> for ParseRule<'_> {
|
impl From<&Token<'_>> for ParseRule<'_> {
|
||||||
fn from(token_kind: &Token) -> Self {
|
fn from(token: &Token) -> Self {
|
||||||
match token_kind {
|
match token {
|
||||||
Token::Async => todo!(),
|
Token::Async => todo!(),
|
||||||
Token::Bang => ParseRule {
|
Token::Bang => ParseRule {
|
||||||
prefix: Some(Parser::parse_unary),
|
prefix: Some(Parser::parse_unary),
|
||||||
|
Loading…
Reference in New Issue
Block a user