Refactor parsing pt5
This commit is contained in:
parent
61051ed11b
commit
8a039ffc64
@ -1,10 +1,10 @@
|
||||
use super::ast::var_binding::Binding;
|
||||
use super::utils::{parse_token_type, try_operator};
|
||||
use super::{expression, ParseResult, ParsingError};
|
||||
use super::{expression, ParsingError, ParsingResult};
|
||||
use crate::error_handling::SyntaxError;
|
||||
use crate::lexic::token::{Token, TokenType};
|
||||
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding> {
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Binding> {
|
||||
let mut current_pos = pos;
|
||||
|
||||
// TODO: Detect if the binding starts with a datatype
|
||||
@ -23,7 +23,7 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding>
|
||||
_ => (false, let_token, next_let),
|
||||
}
|
||||
}
|
||||
_ => return ParseResult::Unmatched,
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
}
|
||||
};
|
||||
current_pos = next_pos;
|
||||
@ -36,25 +36,25 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding>
|
||||
Ok((t, n)) => (t, n),
|
||||
Err(ParsingError::Mismatch(token)) => {
|
||||
// The parser found a token, but it's not an identifier
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
error_start: token.position,
|
||||
error_end: token.get_end_position(),
|
||||
reason: "??".into(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
Err(ParsingError::Err(error)) => {
|
||||
return ParseResult::Err(error);
|
||||
return Err(ParsingError::Err(error));
|
||||
}
|
||||
_ => {
|
||||
// The parser didn't find an Identifier after VAL/VAR
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: format!(
|
||||
"There should be an identifier after a `{}` token",
|
||||
if is_mutable { "val" } else { "var" }
|
||||
),
|
||||
error_start: binding_token.position,
|
||||
error_end: binding_token.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
current_pos = next_pos;
|
||||
@ -66,31 +66,31 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding>
|
||||
Ok((t, _)) => t,
|
||||
Err(ParsingError::Mismatch(t)) => {
|
||||
// The parser found a token, but it's not the `=` operator
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: format!("There should be an equal sign `=` after the identifier"),
|
||||
error_start: t.position,
|
||||
error_end: t.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
_ => {
|
||||
// The parser didn't find the `=` operator after the identifier
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: format!("There should be an equal sign `=` after the identifier",),
|
||||
error_start: identifier.position,
|
||||
error_end: identifier.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
current_pos += 1;
|
||||
|
||||
let (expression, next_pos) = match expression::try_parse(tokens, current_pos) {
|
||||
ParseResult::Ok(exp, next) => (exp, next),
|
||||
Ok((exp, next)) => (exp, next),
|
||||
_ => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected an expression after the equal `=` operator"),
|
||||
error_start: equal_operator.position,
|
||||
error_end: equal_operator.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
current_pos = next_pos;
|
||||
@ -102,7 +102,7 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Binding>
|
||||
is_mutable,
|
||||
};
|
||||
|
||||
ParseResult::Ok(binding, current_pos)
|
||||
Ok((binding, current_pos))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -113,7 +113,7 @@ mod tests {
|
||||
#[test]
|
||||
fn should_parse_val_binding() {
|
||||
let tokens = get_tokens(&String::from("let identifier = 20")).unwrap();
|
||||
let ParseResult::Ok(binding, _) = try_parse(&tokens, 0) else {
|
||||
let Ok((binding, _)) = try_parse(&tokens, 0) else {
|
||||
panic!()
|
||||
};
|
||||
|
||||
@ -174,7 +174,7 @@ mod tests {
|
||||
let binding = try_parse(&tokens, 0);
|
||||
|
||||
match binding {
|
||||
ParseResult::Err(error) => {
|
||||
Err(ParsingError::Err(error)) => {
|
||||
assert_eq!(0, error.error_start);
|
||||
assert_eq!(3, error.error_end);
|
||||
}
|
||||
@ -190,7 +190,7 @@ mod tests {
|
||||
let binding = try_parse(&tokens, 0);
|
||||
|
||||
match binding {
|
||||
ParseResult::Err(error) => {
|
||||
Err(ParsingError::Err(error)) => {
|
||||
assert_eq!(4, error.error_start);
|
||||
assert_eq!(7, error.error_end);
|
||||
}
|
||||
@ -201,7 +201,7 @@ mod tests {
|
||||
let binding = try_parse(&tokens, 0);
|
||||
|
||||
match binding {
|
||||
ParseResult::Err(error) => {
|
||||
Err(ParsingError::Err(error)) => {
|
||||
assert_eq!(4, error.error_start);
|
||||
assert_eq!(11, error.error_end);
|
||||
}
|
||||
@ -215,7 +215,7 @@ mod tests {
|
||||
let binding = try_parse(&tokens, 0);
|
||||
|
||||
match binding {
|
||||
ParseResult::Err(error) => {
|
||||
Err(ParsingError::Err(error)) => {
|
||||
assert_eq!(7, error.error_start);
|
||||
assert_eq!(14, error.error_end);
|
||||
}
|
||||
|
@ -3,19 +3,13 @@ use crate::{
|
||||
lexic::token::{Token, TokenType},
|
||||
};
|
||||
|
||||
use super::{ast::Block, utils::parse_token_type, ParseResult, ParsingError};
|
||||
use super::{ast::Block, utils::parse_token_type, ParsingError, ParsingResult};
|
||||
|
||||
// Assumes that the token at `pos` is a {
|
||||
pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block> {
|
||||
pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Block> {
|
||||
let mut current_pos = pos;
|
||||
|
||||
let (opening_brace, next_pos) =
|
||||
match parse_token_type(tokens, current_pos, TokenType::LeftBrace) {
|
||||
Ok((t, next)) => (t, next),
|
||||
Err(ParsingError::Err(err)) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t),
|
||||
Err(ParsingError::Unmatched) => return ParseResult::Unmatched,
|
||||
};
|
||||
let (opening_brace, next_pos) = parse_token_type(tokens, current_pos, TokenType::LeftBrace)?;
|
||||
current_pos = next_pos;
|
||||
|
||||
// Parse block statements
|
||||
@ -23,13 +17,12 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block>
|
||||
|
||||
// First statement
|
||||
match super::statement::try_parse(tokens, current_pos) {
|
||||
ParseResult::Ok(statement, next_pos) => {
|
||||
Ok((statement, next_pos)) => {
|
||||
current_pos = next_pos;
|
||||
statements.push(statement);
|
||||
}
|
||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||
ParseResult::Unmatched => {}
|
||||
ParseResult::Mismatch(_) => {}
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
_ => {}
|
||||
}
|
||||
|
||||
// More statements separated by new lines
|
||||
@ -40,11 +33,11 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block>
|
||||
current_pos += 1;
|
||||
|
||||
match super::statement::try_parse(tokens, current_pos) {
|
||||
ParseResult::Ok(statement, next_pos) => {
|
||||
Ok((statement, next_pos)) => {
|
||||
current_pos = next_pos;
|
||||
statements.push(statement);
|
||||
}
|
||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
_ => break,
|
||||
}
|
||||
}
|
||||
@ -53,25 +46,25 @@ pub fn parse_block<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Block>
|
||||
let (_closing_brace, next_pos) =
|
||||
match parse_token_type(tokens, current_pos, TokenType::RightBrace) {
|
||||
Ok((t, next)) => (t, next),
|
||||
Err(ParsingError::Err(err)) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
Err(ParsingError::Mismatch(t)) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a closing brace after the block body."),
|
||||
error_start: t.position,
|
||||
error_end: t.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
Err(ParsingError::Unmatched) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a closing brace after the block body."),
|
||||
error_start: opening_brace.position,
|
||||
error_end: opening_brace.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
current_pos = next_pos;
|
||||
|
||||
ParseResult::Ok(Block { statements }, current_pos)
|
||||
Ok((Block { statements }, current_pos))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -85,7 +78,7 @@ mod tests {
|
||||
let block = parse_block(&tokens, 0);
|
||||
|
||||
let block = match block {
|
||||
ParseResult::Ok(p, _) => p,
|
||||
ParsingResult::Ok((p, _)) => p,
|
||||
_ => panic!("Expected a block, got: {:?}", block),
|
||||
};
|
||||
|
||||
@ -98,7 +91,7 @@ mod tests {
|
||||
let block = parse_block(&tokens, 0);
|
||||
|
||||
let block = match block {
|
||||
ParseResult::Ok(p, _) => p,
|
||||
ParsingResult::Ok((p, _)) => p,
|
||||
_ => panic!("Expected a block, got: {:?}", block),
|
||||
};
|
||||
|
||||
@ -111,7 +104,7 @@ mod tests {
|
||||
let block = parse_block(&tokens, 0);
|
||||
|
||||
let block = match block {
|
||||
ParseResult::Ok(p, _) => p,
|
||||
ParsingResult::Ok((p, _)) => p,
|
||||
_ => {
|
||||
panic!("Expected a block, got: {:?}\n\n{:?}", block, tokens)
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
lexic::token::Token,
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
/// Parses a factor expression.
|
||||
@ -8,10 +8,10 @@ use crate::{
|
||||
/// ```ebnf
|
||||
/// comparison = term, ((">" | ">=" | "<" | "<="), term)*;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let (term, next_pos) = match super::term::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
|
||||
_ => return ParseResult::Unmatched,
|
||||
Ok((expr, next_pos)) => (expr, next_pos),
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, term)
|
||||
@ -21,7 +21,7 @@ fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
pos: usize,
|
||||
prev_expr: Expression<'a>,
|
||||
) -> ParseResult<'a, Expression<'a>> {
|
||||
) -> ParsingResult<'a, Expression<'a>> {
|
||||
// comparison = term, ((">" | ">=" | "<" | "<="), term)*;
|
||||
|
||||
match tokens.get(pos) {
|
||||
@ -32,7 +32,7 @@ fn parse_many<'a>(
|
||||
|| token.value == ">=" =>
|
||||
{
|
||||
match super::term::try_parse(tokens, pos + 1) {
|
||||
ParseResult::Ok(expr, next_pos) => {
|
||||
Ok((expr, next_pos)) => {
|
||||
let expr = Expression::BinaryOperator(
|
||||
Box::new(prev_expr),
|
||||
Box::new(expr),
|
||||
@ -41,9 +41,9 @@ fn parse_many<'a>(
|
||||
|
||||
parse_many(tokens, next_pos, expr)
|
||||
}
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
_ => ParseResult::Ok(prev_expr, pos),
|
||||
_ => Ok((prev_expr, pos)),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
lexic::token::Token,
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
/// Parses a factor expression.
|
||||
@ -8,10 +8,10 @@ use crate::{
|
||||
/// ```ebnf
|
||||
/// equality = comparison, (("==" | "!="), comparison )*;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let (comparison, next_pos) = match super::comparison::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
|
||||
_ => return ParseResult::Unmatched,
|
||||
Ok((expr, next_pos)) => (expr, next_pos),
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, comparison)
|
||||
@ -21,13 +21,13 @@ fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
pos: usize,
|
||||
prev_expr: Expression<'a>,
|
||||
) -> ParseResult<'a, Expression<'a>> {
|
||||
) -> ParsingResult<'a, Expression<'a>> {
|
||||
// equality = comparison, (("==" | "!="), comparison )*;
|
||||
|
||||
match tokens.get(pos) {
|
||||
Some(token) if token.value == "==" || token.value == "!=" => {
|
||||
match super::comparison::try_parse(tokens, pos + 1) {
|
||||
ParseResult::Ok(expr, next_pos) => {
|
||||
Ok((expr, next_pos)) => {
|
||||
let expr = Expression::BinaryOperator(
|
||||
Box::new(prev_expr),
|
||||
Box::new(expr),
|
||||
@ -36,9 +36,9 @@ fn parse_many<'a>(
|
||||
|
||||
parse_many(tokens, next_pos, expr)
|
||||
}
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
_ => ParseResult::Ok(prev_expr, pos),
|
||||
_ => Ok((prev_expr, pos)),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
lexic::token::Token,
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
/// Parses a factor expression.
|
||||
@ -8,10 +8,10 @@ use crate::{
|
||||
/// ```ebnf
|
||||
/// factor = unary, (("/" | "*"), unary)*;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let (unary, next_pos) = match super::unary::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
|
||||
_ => return ParseResult::Unmatched,
|
||||
Ok((expr, next_pos)) => (expr, next_pos),
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, unary)
|
||||
@ -21,13 +21,13 @@ fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
pos: usize,
|
||||
prev_expr: Expression<'a>,
|
||||
) -> ParseResult<'a, Expression<'a>> {
|
||||
) -> ParsingResult<'a, Expression<'a>> {
|
||||
// (("/" | "*"), unary)*
|
||||
|
||||
match tokens.get(pos) {
|
||||
Some(token) if token.value == "/" || token.value == "*" => {
|
||||
match super::unary::try_parse(tokens, pos + 1) {
|
||||
ParseResult::Ok(expr, next_pos) => {
|
||||
Ok((expr, next_pos)) => {
|
||||
let expr = Expression::BinaryOperator(
|
||||
Box::new(prev_expr),
|
||||
Box::new(expr),
|
||||
@ -36,9 +36,9 @@ fn parse_many<'a>(
|
||||
|
||||
parse_many(tokens, next_pos, expr)
|
||||
}
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
_ => ParseResult::Ok(prev_expr, pos),
|
||||
_ => Ok((prev_expr, pos)),
|
||||
}
|
||||
}
|
||||
|
@ -3,7 +3,7 @@ use crate::{
|
||||
syntax::{
|
||||
ast::{functions::FunctionCall, Expression},
|
||||
functions::arguments_list,
|
||||
ParseResult,
|
||||
ParsingError, ParsingResult,
|
||||
},
|
||||
};
|
||||
|
||||
@ -13,18 +13,18 @@ use crate::{
|
||||
/// function call expr = primary, "(", (arguments list)?, ")"
|
||||
/// | primary;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let (primary_expr, next_pos) = match super::primary::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
|
||||
_ => return ParseResult::Unmatched,
|
||||
Ok((expr, next_pos)) => (expr, next_pos),
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
// Parse arguments list
|
||||
let (arguments, next_pos) = match arguments_list::try_parse(tokens, next_pos) {
|
||||
ParseResult::Ok(args, next) => (args, next),
|
||||
ParseResult::Err(err) => return ParseResult::Err(err),
|
||||
Ok((args, next)) => (args, next),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
_ => {
|
||||
return ParseResult::Ok(primary_expr, next_pos);
|
||||
return Ok((primary_expr, next_pos));
|
||||
}
|
||||
};
|
||||
|
||||
@ -33,7 +33,7 @@ pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
arguments: Box::new(arguments),
|
||||
};
|
||||
|
||||
ParseResult::Ok(Expression::FunctionCall(fun_call), next_pos)
|
||||
Ok((Expression::FunctionCall(fun_call), next_pos))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,4 +1,4 @@
|
||||
use super::{ast::Expression, ParseResult};
|
||||
use super::{ast::Expression, ParsingResult};
|
||||
use crate::lexic::token::Token;
|
||||
|
||||
mod comparison;
|
||||
@ -10,8 +10,8 @@ mod term;
|
||||
mod unary;
|
||||
|
||||
/// Expression is defined in the grammar.
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
return equality::try_parse(tokens, pos);
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
equality::try_parse(tokens, pos)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
|
@ -1,7 +1,7 @@
|
||||
use super::super::utils::Tokenizer;
|
||||
use crate::{
|
||||
lexic::token::{Token, TokenType},
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
/// This grammar may not be up to date. Refer to the spec for the latest grammar.
|
||||
@ -9,35 +9,33 @@ use crate::{
|
||||
/// ```ebnf
|
||||
/// primary = number | string | boolean | identifier | ("(", expression, ")");
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
match tokens.get_significant(pos) {
|
||||
Some((token, token_pos)) => match token.token_type {
|
||||
TokenType::Number => ParseResult::Ok(Expression::Number(&token.value), token_pos + 1),
|
||||
TokenType::String => ParseResult::Ok(Expression::String(&token.value), token_pos + 1),
|
||||
TokenType::Number => Ok((Expression::Number(&token.value), token_pos + 1)),
|
||||
TokenType::String => Ok((Expression::String(&token.value), token_pos + 1)),
|
||||
TokenType::Identifier if token.value == "true" || token.value == "false" => {
|
||||
ParseResult::Ok(Expression::Boolean(token.value == "true"), token_pos + 1)
|
||||
}
|
||||
TokenType::Identifier => {
|
||||
ParseResult::Ok(Expression::Identifier(&token.value), token_pos + 1)
|
||||
Ok((Expression::Boolean(token.value == "true"), token_pos + 1))
|
||||
}
|
||||
TokenType::Identifier => Ok((Expression::Identifier(&token.value), token_pos + 1)),
|
||||
TokenType::LeftParen => parse_parenthesized_expression(tokens, token_pos),
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
},
|
||||
None => ParseResult::Unmatched,
|
||||
None => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
|
||||
fn parse_parenthesized_expression(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
fn parse_parenthesized_expression(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let expression = super::try_parse(tokens, pos + 1);
|
||||
match expression {
|
||||
ParseResult::Ok(expression, next_pos) => match tokens.get(next_pos) {
|
||||
Ok((expression, next_pos)) => match tokens.get(next_pos) {
|
||||
Some(token) => match token.token_type {
|
||||
TokenType::RightParen => ParseResult::Ok(expression, next_pos + 1),
|
||||
_ => ParseResult::Unmatched,
|
||||
TokenType::RightParen => Ok((expression, next_pos + 1)),
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
},
|
||||
None => ParseResult::Unmatched,
|
||||
None => Err(ParsingError::Unmatched),
|
||||
},
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
|
||||
@ -52,7 +50,9 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::Number(value), _) => assert_eq!("40", format!("{}", value)),
|
||||
Ok((Expression::Number(value), _)) => {
|
||||
assert_eq!("40", format!("{}", value))
|
||||
}
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -63,7 +63,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::String(value), _) => {
|
||||
Ok((Expression::String(value), _)) => {
|
||||
assert_eq!("\"Hello\"", format!("{}", value))
|
||||
}
|
||||
_ => panic!(),
|
||||
@ -76,7 +76,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::Boolean(value), _) => assert!(value),
|
||||
Ok((Expression::Boolean(value), _)) => assert!(value),
|
||||
_ => panic!(),
|
||||
}
|
||||
}
|
||||
@ -87,7 +87,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::Identifier(value), _) => {
|
||||
Ok((Expression::Identifier(value), _)) => {
|
||||
assert_eq!("someIdentifier", format!("{}", value))
|
||||
}
|
||||
_ => panic!(),
|
||||
@ -100,7 +100,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::Identifier(value), _) => {
|
||||
Ok((Expression::Identifier(value), _)) => {
|
||||
assert_eq!("identifier", format!("{}", value))
|
||||
}
|
||||
_ => panic!(),
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
lexic::token::Token,
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
/// Parses a factor expression.
|
||||
@ -8,10 +8,10 @@ use crate::{
|
||||
/// ```ebnf
|
||||
/// term = factor, (("-" | "+"), factor)*;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
let (factor, next_pos) = match super::factor::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(expr, next_pos) => (expr, next_pos),
|
||||
_ => return ParseResult::Unmatched,
|
||||
Ok((expr, next_pos)) => (expr, next_pos),
|
||||
_ => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
|
||||
parse_many(tokens, next_pos, factor)
|
||||
@ -21,13 +21,13 @@ fn parse_many<'a>(
|
||||
tokens: &'a Vec<Token>,
|
||||
pos: usize,
|
||||
prev_expr: Expression<'a>,
|
||||
) -> ParseResult<'a, Expression<'a>> {
|
||||
) -> ParsingResult<'a, Expression<'a>> {
|
||||
// term = factor, (("-" | "+"), factor)*;
|
||||
|
||||
match tokens.get(pos) {
|
||||
Some(token) if token.value == "+" || token.value == "-" => {
|
||||
match super::factor::try_parse(tokens, pos + 1) {
|
||||
ParseResult::Ok(expr, next_pos) => {
|
||||
Ok((expr, next_pos)) => {
|
||||
let expr = Expression::BinaryOperator(
|
||||
Box::new(prev_expr),
|
||||
Box::new(expr),
|
||||
@ -36,9 +36,9 @@ fn parse_many<'a>(
|
||||
|
||||
parse_many(tokens, next_pos, expr)
|
||||
}
|
||||
_ => ParseResult::Unmatched,
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
_ => ParseResult::Ok(prev_expr, pos),
|
||||
_ => Ok((prev_expr, pos)),
|
||||
}
|
||||
}
|
||||
|
@ -1,6 +1,6 @@
|
||||
use crate::{
|
||||
lexic::token::Token,
|
||||
syntax::{ast::Expression, ParseResult},
|
||||
syntax::{ast::Expression, ParsingError, ParsingResult},
|
||||
};
|
||||
|
||||
use super::function_call_expr;
|
||||
@ -11,15 +11,15 @@ use super::function_call_expr;
|
||||
/// unary = ("!" | "-"), expression
|
||||
/// | function call expr;
|
||||
/// ```
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParseResult<Expression> {
|
||||
pub fn try_parse(tokens: &Vec<Token>, pos: usize) -> ParsingResult<Expression> {
|
||||
match tokens.get(pos) {
|
||||
Some(token) if token.value == "!" || token.value == "-" => {
|
||||
match super::try_parse(tokens, pos + 1) {
|
||||
ParseResult::Ok(expression, next_pos) => ParseResult::Ok(
|
||||
Ok((expression, next_pos)) => Ok((
|
||||
Expression::UnaryOperator(&token.value, Box::new(expression)),
|
||||
next_pos,
|
||||
),
|
||||
_ => ParseResult::Unmatched,
|
||||
)),
|
||||
_ => Err(ParsingError::Unmatched),
|
||||
}
|
||||
}
|
||||
_ => function_call_expr::try_parse(tokens, pos),
|
||||
@ -37,7 +37,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::Identifier(value), _) => {
|
||||
Ok((Expression::Identifier(value), _)) => {
|
||||
assert_eq!("identifier", format!("{}", value))
|
||||
}
|
||||
_ => panic!(),
|
||||
@ -50,7 +50,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::UnaryOperator(operator, expression), _) => {
|
||||
Ok((Expression::UnaryOperator(operator, expression), _)) => {
|
||||
match (operator, *expression) {
|
||||
(op, Expression::Number(value)) => {
|
||||
assert_eq!(*op, "-");
|
||||
@ -69,7 +69,7 @@ mod tests {
|
||||
let expression = try_parse(&tokens, 0);
|
||||
|
||||
match expression {
|
||||
ParseResult::Ok(Expression::UnaryOperator(operator, expression), _) => {
|
||||
Ok((Expression::UnaryOperator(operator, expression), _)) => {
|
||||
assert_eq!(*operator, "-");
|
||||
match *expression {
|
||||
Expression::BinaryOperator(_, _, _) => {
|
||||
|
@ -4,19 +4,19 @@ use crate::{
|
||||
syntax::{
|
||||
ast::{functions::ArgumentsList, Expression},
|
||||
utils::parse_token_type,
|
||||
ParseResult, ParsingError,
|
||||
ParsingError, ParsingResult,
|
||||
},
|
||||
};
|
||||
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<ArgumentsList> {
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<ArgumentsList> {
|
||||
let mut current_pos = pos;
|
||||
|
||||
let (opening_paren, next_pos) =
|
||||
match parse_token_type(tokens, current_pos, TokenType::LeftParen) {
|
||||
Ok((t, next)) => (t, next),
|
||||
Err(ParsingError::Err(err)) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t),
|
||||
Err(ParsingError::Unmatched) => return ParseResult::Unmatched,
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
Err(ParsingError::Mismatch(t)) => return Err(ParsingError::Mismatch(t)),
|
||||
Err(ParsingError::Unmatched) => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
current_pos = next_pos;
|
||||
|
||||
@ -24,10 +24,10 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Argument
|
||||
loop {
|
||||
let (next_expression, next_pos) =
|
||||
match super::super::expression::try_parse(tokens, current_pos) {
|
||||
ParseResult::Ok(expression, next_pos) => (expression, next_pos),
|
||||
ParseResult::Err(error) => {
|
||||
Ok((expression, next_pos)) => (expression, next_pos),
|
||||
Err(ParsingError::Err(error)) => {
|
||||
// TODO: Write a more detailed error
|
||||
return ParseResult::Err(error);
|
||||
return Err(ParsingError::Err(error));
|
||||
}
|
||||
_ => break,
|
||||
};
|
||||
@ -41,7 +41,7 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Argument
|
||||
current_pos = next;
|
||||
}
|
||||
// This should never happen
|
||||
Err(ParsingError::Err(err)) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
Err(ParsingError::Mismatch(_)) => {
|
||||
// Something other than a comma was found. It must be a closing paren )
|
||||
// Still, break the loop, assume there are no more arguments
|
||||
@ -56,25 +56,25 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Argument
|
||||
let (_closing_paren, next_pos) =
|
||||
match parse_token_type(tokens, current_pos, TokenType::RightParen) {
|
||||
Ok((t, next)) => (t, next),
|
||||
Err(ParsingError::Err(err)) => return ParseResult::Err(err),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
Err(ParsingError::Mismatch(t)) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a closing paren after the function identifier."),
|
||||
error_start: t.position,
|
||||
error_end: t.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
Err(ParsingError::Unmatched) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a closing paren after the function identifier."),
|
||||
error_start: opening_paren.position,
|
||||
error_end: opening_paren.get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
};
|
||||
current_pos = next_pos;
|
||||
|
||||
ParseResult::Ok(ArgumentsList { arguments }, current_pos)
|
||||
Ok((ArgumentsList { arguments }, current_pos))
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -87,7 +87,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("()")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(list, next) = fun_decl else {
|
||||
let Ok((list, next)) = fun_decl else {
|
||||
panic!("Expected an unmatched result: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -100,7 +100,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("( ) ")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(list, next) = fun_decl else {
|
||||
let Ok((list, next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -113,7 +113,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("(\n \n)")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(list, next) = fun_decl else {
|
||||
let Ok((list, next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -126,7 +126,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("(0)")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(arguments_list, next) = fun_decl else {
|
||||
let Ok((arguments_list, next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -145,7 +145,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("(0, )")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(arguments_list, next) = fun_decl else {
|
||||
let Ok((arguments_list, next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -163,7 +163,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("(\"Hello new world\", 322, )")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(arguments_list, _next) = fun_decl else {
|
||||
let Ok((arguments_list, _next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
@ -185,7 +185,7 @@ mod tests {
|
||||
let tokens = get_tokens(&String::from("(foo(), bar())")).unwrap();
|
||||
let fun_decl = try_parse(&tokens, 0);
|
||||
|
||||
let ParseResult::Ok(arguments_list, _next) = fun_decl else {
|
||||
let Ok((arguments_list, _next)) = fun_decl else {
|
||||
panic!("Expected a result, got: {:?}", fun_decl);
|
||||
};
|
||||
|
||||
|
@ -5,7 +5,7 @@ use crate::{
|
||||
};
|
||||
|
||||
use super::{
|
||||
super::{ast::FunctionDeclaration, block::parse_block, utils::parse_token_type, ParseResult},
|
||||
super::{ast::FunctionDeclaration, block::parse_block, utils::parse_token_type},
|
||||
params_list::parse_params_list,
|
||||
};
|
||||
|
||||
@ -61,18 +61,18 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Functi
|
||||
current_pos = next_pos;
|
||||
|
||||
let (block, next_pos) = match parse_block(tokens, current_pos) {
|
||||
ParseResult::Ok(block, next_pos) => (block, next_pos),
|
||||
ParseResult::Err(error) => {
|
||||
Ok((block, next_pos)) => (block, next_pos),
|
||||
Err(ParsingError::Err(error)) => {
|
||||
return Err(ParsingError::Err(error));
|
||||
}
|
||||
ParseResult::Mismatch(wrong_token) => {
|
||||
Err(ParsingError::Mismatch(wrong_token)) => {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a block after the function declaration."),
|
||||
error_start: wrong_token.position,
|
||||
error_end: wrong_token.get_end_position(),
|
||||
}));
|
||||
}
|
||||
ParseResult::Unmatched => {
|
||||
Err(ParsingError::Unmatched) => {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected a block after the function declaration."),
|
||||
error_start: identifier.position,
|
||||
|
@ -6,7 +6,7 @@ use crate::{
|
||||
|
||||
use super::super::{
|
||||
ast::{Parameter, ParamsList},
|
||||
utils, ParseResult,
|
||||
utils,
|
||||
};
|
||||
|
||||
pub fn parse_params_list<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<ParamsList> {
|
||||
@ -33,8 +33,8 @@ pub fn parse_params_list<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResul
|
||||
let mut parameters = Vec::<Parameter>::new();
|
||||
loop {
|
||||
let (next_parameter, next_pos) = match parse_param_definition(tokens, current_pos) {
|
||||
ParseResult::Ok(parameter, next_pos) => (parameter, next_pos),
|
||||
ParseResult::Err(error) => {
|
||||
Ok((parameter, next_pos)) => (parameter, next_pos),
|
||||
Err(ParsingError::Err(error)) => {
|
||||
return Err(ParsingError::Err(error));
|
||||
}
|
||||
_ => break,
|
||||
@ -84,7 +84,7 @@ pub fn parse_params_list<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResul
|
||||
Ok((ParamsList {}, current_pos))
|
||||
}
|
||||
|
||||
fn parse_param_definition<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Parameter> {
|
||||
fn parse_param_definition<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Parameter> {
|
||||
// Parse a single parameter definition of the form:
|
||||
// - Type identifier
|
||||
// There will be more constructs in the future, like:
|
||||
@ -97,12 +97,12 @@ fn parse_param_definition<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult
|
||||
match utils::parse_token_type(tokens, current_pos, TokenType::Datatype) {
|
||||
Ok((token, next)) => (token, next),
|
||||
Err(ParsingError::Err(err)) => {
|
||||
return ParseResult::Err(err);
|
||||
return Err(ParsingError::Err(err));
|
||||
}
|
||||
// If there is no datatype this construction doesn't apply.
|
||||
// Return a mismatch and let the caller handle it
|
||||
Err(ParsingError::Mismatch(t)) => return ParseResult::Mismatch(t),
|
||||
Err(ParsingError::Unmatched) => return ParseResult::Unmatched,
|
||||
Err(ParsingError::Mismatch(t)) => return Err(ParsingError::Mismatch(t)),
|
||||
Err(ParsingError::Unmatched) => return Err(ParsingError::Unmatched),
|
||||
};
|
||||
current_pos = next_pos;
|
||||
|
||||
@ -110,30 +110,30 @@ fn parse_param_definition<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult
|
||||
match utils::parse_token_type(tokens, current_pos, TokenType::Identifier) {
|
||||
Ok((token, next)) => (token, next),
|
||||
Err(ParsingError::Err(err)) => {
|
||||
return ParseResult::Err(err);
|
||||
return Err(ParsingError::Err(err));
|
||||
}
|
||||
// However, if we fail to parse an identifier, it's an error
|
||||
Err(ParsingError::Mismatch(_)) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected an identifier for the parameter."),
|
||||
error_start: tokens[pos].position,
|
||||
error_end: tokens[pos].get_end_position(),
|
||||
});
|
||||
}));
|
||||
}
|
||||
Err(ParsingError::Unmatched) => {
|
||||
return ParseResult::Err(SyntaxError {
|
||||
return Err(ParsingError::Err(SyntaxError {
|
||||
reason: String::from("Expected an identifier for the parameter."),
|
||||
error_start: tokens[pos].position,
|
||||
error_end: tokens[pos].get_end_position(),
|
||||
})
|
||||
}))
|
||||
}
|
||||
};
|
||||
|
||||
ParseResult::Ok(
|
||||
Ok((
|
||||
Parameter {
|
||||
identifier: &identifier.value,
|
||||
datatype: &datatype.value,
|
||||
},
|
||||
next_pos,
|
||||
)
|
||||
))
|
||||
}
|
||||
|
@ -14,23 +14,6 @@ use ast::ModuleAST;
|
||||
|
||||
use self::ast::TopLevelDeclaration;
|
||||
|
||||
#[derive(Debug)]
|
||||
pub enum ParseResult<'a, A> {
|
||||
/// The parsing was a success. The first element is the parsed construct,
|
||||
/// the second element is the position of the next token to parse
|
||||
Ok(A, usize),
|
||||
/// The parsing failed past a point of no return.
|
||||
///
|
||||
/// For example, when parsing a function declaration
|
||||
/// the `fun` token is found, but then no identifier
|
||||
Err(SyntaxError),
|
||||
/// Some special value was expected, but something else was found.
|
||||
/// The inside element is the something else found.
|
||||
Mismatch(&'a Token),
|
||||
/// This parsing didn't succeed, but it's not a fatal error.
|
||||
Unmatched,
|
||||
}
|
||||
|
||||
pub type ParsingResult<'a, A> = Result<(A, usize), ParsingError<'a>>;
|
||||
|
||||
#[derive(Debug)]
|
||||
|
@ -4,26 +4,26 @@ use super::{
|
||||
ast::{statement::Statement, Expression},
|
||||
binding,
|
||||
expression::function_call_expr,
|
||||
ParseResult,
|
||||
ParsingError, ParsingResult,
|
||||
};
|
||||
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParseResult<Statement> {
|
||||
None.or_else(|| match binding::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(b, next) => Some(ParseResult::Ok(Statement::Binding(b), next)),
|
||||
ParseResult::Err(err) => Some(ParseResult::Err(err)),
|
||||
_ => None,
|
||||
})
|
||||
.or_else(|| match function_call_expr::try_parse(tokens, pos) {
|
||||
ParseResult::Ok(f, next) => {
|
||||
let Expression::FunctionCall(f) = f else {
|
||||
return None;
|
||||
};
|
||||
Some(ParseResult::Ok(Statement::FunctionCall(f), next))
|
||||
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Statement> {
|
||||
// Try to parse a binding
|
||||
match binding::try_parse(tokens, pos) {
|
||||
Ok((b, next)) => return Ok((Statement::Binding(b), next)),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
_ => {}
|
||||
}
|
||||
ParseResult::Err(err) => Some(ParseResult::Err(err)),
|
||||
_ => None,
|
||||
})
|
||||
.unwrap_or_else(|| ParseResult::Unmatched)
|
||||
|
||||
// Try to parse a function call
|
||||
match function_call_expr::try_parse(tokens, pos) {
|
||||
Ok((Expression::FunctionCall(f), next)) => return Ok((Statement::FunctionCall(f), next)),
|
||||
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
||||
_ => {}
|
||||
};
|
||||
|
||||
// Return unmatched
|
||||
Err(ParsingError::Unmatched)
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
@ -37,7 +37,7 @@ mod tests {
|
||||
let statement = try_parse(&tokens, 0);
|
||||
|
||||
let statement = match statement {
|
||||
ParseResult::Ok(s, _) => s,
|
||||
Ok((s, _)) => s,
|
||||
_ => panic!("Expected a statement"),
|
||||
};
|
||||
|
||||
@ -54,7 +54,7 @@ mod tests {
|
||||
let statement = try_parse(&tokens, 0);
|
||||
|
||||
let statement = match statement {
|
||||
ParseResult::Ok(s, _) => s,
|
||||
Ok((s, _)) => s,
|
||||
_ => panic!("Expected a statement"),
|
||||
};
|
||||
|
||||
|
@ -54,7 +54,7 @@ pub fn parse_token_type(
|
||||
) -> ParsingResult<&Token> {
|
||||
let mut current_pos = pos;
|
||||
|
||||
// Ignore all whitespace and newlines
|
||||
// Ignore all whitespace, newlines and semicolons
|
||||
while let Some(t) = tokens.get(current_pos) {
|
||||
if t.token_type == TokenType::INDENT
|
||||
|| t.token_type == TokenType::DEDENT
|
||||
|
Loading…
Reference in New Issue
Block a user