Add parser mode to pass tests

This commit is contained in:
Jeff 2024-08-15 21:34:47 -04:00
parent 44d6a88faa
commit 40b5d15b96

View File

@ -125,6 +125,7 @@ pub struct Parser<'src> {
lexer: Lexer, lexer: Lexer,
current_token: Token<'src>, current_token: Token<'src>,
current_position: Span, current_position: Span,
mode: ParserMode,
} }
impl<'src> Parser<'src> { impl<'src> Parser<'src> {
@ -138,6 +139,7 @@ impl<'src> Parser<'src> {
lexer, lexer,
current_token, current_token,
current_position, current_position,
mode: ParserMode::Normal,
} }
} }
@ -357,6 +359,53 @@ impl<'src> Parser<'src> {
let identifier = Identifier::new(text); let identifier = Identifier::new(text);
if let ParserMode::Condition = self.mode {
return Ok(Expression::identifier(identifier, start_position));
}
if let Token::LeftCurlyBrace = self.current_token {
let name = Node::new(identifier, start_position);
self.next_token()?;
let mut fields = Vec::new();
loop {
if let Token::RightCurlyBrace = self.current_token {
self.next_token()?;
break;
}
let field_name = self.parse_identifier()?;
if let Token::Colon = self.current_token {
self.next_token()?;
} else {
return Err(ParseError::ExpectedToken {
expected: TokenKind::Colon,
actual: self.current_token.to_owned(),
position: self.current_position,
});
}
let field_value = self.parse_expression(0)?;
fields.push((field_name, field_value));
if let Token::Comma = self.current_token {
self.next_token()?;
}
}
let position = (start_position.0, self.current_position.1);
return Ok(Expression::r#struct(
StructExpression::Fields { name, fields },
position,
));
}
Ok(Expression::identifier(identifier, start_position)) Ok(Expression::identifier(identifier, start_position))
} }
Token::Integer(text) => { Token::Integer(text) => {
@ -664,51 +713,6 @@ impl<'src> Parser<'src> {
Expression::field_access(left, field, position) Expression::field_access(left, field, position)
} }
} }
Token::LeftCurlyBrace => {
let identifier = if let Some(identifier) = left.as_identifier() {
identifier
} else {
return Err(ParseError::ExpectedIdentifierNode { actual: left });
};
let name = Node::new(identifier.clone(), left.position());
self.next_token()?;
let mut fields = Vec::new();
loop {
if let Token::RightCurlyBrace = self.current_token {
self.next_token()?;
break;
}
let field_name = self.parse_identifier()?;
if let Token::Colon = self.current_token {
self.next_token()?;
} else {
return Err(ParseError::ExpectedToken {
expected: TokenKind::Colon,
actual: self.current_token.to_owned(),
position: self.current_position,
});
}
let field_value = self.parse_expression(0)?;
fields.push((field_name, field_value));
if let Token::Comma = self.current_token {
self.next_token()?;
}
}
let position = (left.position().0, self.current_position.1);
Expression::r#struct(StructExpression::Fields { name, fields }, position)
}
Token::LeftParenthesis => { Token::LeftParenthesis => {
self.next_token()?; self.next_token()?;
@ -773,7 +777,12 @@ impl<'src> Parser<'src> {
fn parse_if(&mut self) -> Result<If, ParseError> { fn parse_if(&mut self) -> Result<If, ParseError> {
// Assume that the "if" token has already been consumed // Assume that the "if" token has already been consumed
let condition = self.parse_expression(10)?; self.mode = ParserMode::Condition;
let condition = self.parse_expression(0)?;
self.mode = ParserMode::Normal;
let if_block = self.parse_block()?; let if_block = self.parse_block()?;
if let Token::Else = self.current_token { if let Token::Else = self.current_token {
@ -884,6 +893,12 @@ impl<'src> Parser<'src> {
} }
} }
#[derive(Debug, PartialEq, Clone)]
pub enum ParserMode {
Condition,
Normal,
}
#[derive(Debug, PartialEq, Clone)] #[derive(Debug, PartialEq, Clone)]
pub enum ParseError { pub enum ParseError {
Boolean { Boolean {
@ -1092,19 +1107,19 @@ mod tests {
Ok(AbstractSyntaxTree::with_statements([ Ok(AbstractSyntaxTree::with_statements([
Statement::Expression(Expression::r#struct( Statement::Expression(Expression::r#struct(
StructExpression::Fields { StructExpression::Fields {
name: Node::new(Identifier::new("Foo"), (0, 0)), name: Node::new(Identifier::new("Foo"), (0, 3)),
fields: vec![ fields: vec![
( (
Node::new(Identifier::new("a"), (0, 0)), Node::new(Identifier::new("a"), (6, 7)),
Expression::literal(LiteralExpression::Integer(42), (0, 0)), Expression::literal(LiteralExpression::Integer(42), (9, 11)),
), ),
( (
Node::new(Identifier::new("b"), (0, 0)), Node::new(Identifier::new("b"), (13, 14)),
Expression::literal(LiteralExpression::Float(4.0), (0, 0)) Expression::literal(LiteralExpression::Float(4.0), (16, 19))
) )
] ]
}, },
(0, 0) (0, 21)
)) ))
])) ]))
); );