2023-04-15 22:17:27 +00:00
|
|
|
use crate::error_handling::{MistiError, SyntaxError};
|
2023-03-14 21:10:43 +00:00
|
|
|
|
2023-02-15 21:17:50 +00:00
|
|
|
mod binding;
|
2023-09-21 00:53:46 +00:00
|
|
|
mod block;
|
2023-03-14 21:10:43 +00:00
|
|
|
mod expression;
|
2023-10-01 22:43:59 +00:00
|
|
|
mod functions;
|
2023-10-05 11:56:21 +00:00
|
|
|
mod statement;
|
2023-10-06 01:26:47 +00:00
|
|
|
mod utils;
|
2023-09-09 01:17:46 +00:00
|
|
|
|
2023-09-08 01:50:51 +00:00
|
|
|
pub mod ast;
|
2023-09-08 01:46:11 +00:00
|
|
|
|
2023-09-17 22:58:56 +00:00
|
|
|
use crate::lexic::token::{Token, TokenType};
|
2023-09-09 01:28:53 +00:00
|
|
|
use ast::ModuleAST;
|
2023-01-05 23:20:58 +00:00
|
|
|
|
2024-06-01 23:57:10 +00:00
|
|
|
use self::ast::ModuleMembers;
|
2023-01-08 23:09:06 +00:00
|
|
|
|
2024-03-15 21:07:28 +00:00
|
|
|
pub type ParsingResult<'a, A> = Result<(A, usize), ParsingError<'a>>;
|
2024-03-15 20:49:02 +00:00
|
|
|
|
2024-03-15 21:44:29 +00:00
|
|
|
#[derive(Debug)]
|
2024-03-15 21:07:28 +00:00
|
|
|
pub enum ParsingError<'a> {
|
|
|
|
/// Some other token was found than the expected one
|
|
|
|
Mismatch(&'a Token),
|
|
|
|
/// The parsing didn't succeed, but it's not a fatal error
|
|
|
|
Unmatched,
|
|
|
|
/// 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),
|
|
|
|
}
|
2024-03-15 20:49:02 +00:00
|
|
|
|
2022-11-28 23:33:34 +00:00
|
|
|
/// Constructs the Misti AST from a vector of tokens
|
2024-06-01 23:57:10 +00:00
|
|
|
pub fn build_ast<'a>(tokens: &'a Vec<Token>) -> Result<ModuleAST, MistiError> {
|
2023-09-17 22:58:56 +00:00
|
|
|
let mut top_level_declarations = Vec::new();
|
|
|
|
let token_amount = tokens.len();
|
|
|
|
let mut current_pos = 0;
|
|
|
|
|
|
|
|
// Minus one because the last token is always EOF
|
|
|
|
while current_pos < token_amount - 1 {
|
|
|
|
// Ignore newlines
|
|
|
|
if tokens[current_pos].token_type == TokenType::NewLine {
|
|
|
|
current_pos += 1;
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
match next_construct(tokens, current_pos) {
|
2024-03-15 21:44:29 +00:00
|
|
|
Ok((module, next_pos)) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
top_level_declarations.push(module);
|
|
|
|
current_pos = next_pos;
|
|
|
|
}
|
2024-03-15 21:44:29 +00:00
|
|
|
Err(ParsingError::Err(err)) => return Err(MistiError::Syntax(err)),
|
2023-09-22 01:34:51 +00:00
|
|
|
_ => {
|
2023-09-17 22:58:56 +00:00
|
|
|
return Err(MistiError::Syntax(SyntaxError {
|
|
|
|
reason: String::from("PARSER couldn't parse any construction"),
|
|
|
|
// FIXME: This should get the position of the _token_ that current_pos points to
|
|
|
|
error_start: current_pos,
|
|
|
|
error_end: current_pos,
|
|
|
|
}));
|
|
|
|
}
|
|
|
|
}
|
2023-01-17 13:04:11 +00:00
|
|
|
}
|
2023-09-17 22:58:56 +00:00
|
|
|
|
|
|
|
Ok(ModuleAST {
|
2024-06-01 23:57:10 +00:00
|
|
|
productions: top_level_declarations,
|
2023-09-17 22:58:56 +00:00
|
|
|
})
|
2022-11-21 21:58:51 +00:00
|
|
|
}
|
2023-01-05 23:20:58 +00:00
|
|
|
|
2024-06-01 23:57:10 +00:00
|
|
|
fn next_construct<'a>(tokens: &'a Vec<Token>, current_pos: usize) -> ParsingResult<ModuleMembers> {
|
2024-03-15 21:44:29 +00:00
|
|
|
// Try to parse a function declaration
|
|
|
|
match functions::function_declaration::try_parse(tokens, current_pos) {
|
|
|
|
Ok((declaration, next_pos)) => {
|
2024-06-01 23:57:10 +00:00
|
|
|
return Ok((ModuleMembers::FunctionDeclaration(declaration), next_pos))
|
2024-03-15 21:44:29 +00:00
|
|
|
}
|
|
|
|
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
2024-03-18 13:57:28 +00:00
|
|
|
// Try to parse a binding
|
|
|
|
match binding::try_parse(tokens, current_pos) {
|
2024-06-01 23:57:10 +00:00
|
|
|
Ok((binding, next_pos)) => return Ok((ModuleMembers::Binding(binding), next_pos)),
|
2024-03-18 13:57:28 +00:00
|
|
|
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Try to parse an expression
|
|
|
|
match expression::try_parse(tokens, current_pos) {
|
2024-06-01 23:57:10 +00:00
|
|
|
Ok((expression, next_pos)) => return Ok((ModuleMembers::Expression(expression), next_pos)),
|
2024-03-18 13:57:28 +00:00
|
|
|
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
|
|
|
|
_ => {}
|
|
|
|
}
|
|
|
|
|
2024-03-15 21:44:29 +00:00
|
|
|
// No top level construct was found, return unmatched
|
|
|
|
Err(ParsingError::Unmatched)
|
2023-03-14 21:10:43 +00:00
|
|
|
}
|
2023-09-17 22:58:56 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_parse_top_level_construct_with_trailing_newline() {
|
2024-03-15 21:44:29 +00:00
|
|
|
let input = String::from(" fun f1(){}\n");
|
2023-09-17 22:58:56 +00:00
|
|
|
let tokens = crate::lexic::get_tokens(&input).unwrap();
|
2024-06-01 23:57:10 +00:00
|
|
|
let declarations = build_ast(&tokens).unwrap().productions;
|
2023-09-17 22:58:56 +00:00
|
|
|
|
|
|
|
assert_eq!(declarations.len(), 1);
|
|
|
|
|
|
|
|
match declarations.get(0).unwrap() {
|
2024-06-01 23:57:10 +00:00
|
|
|
ModuleMembers::Binding(_) => panic!("Expected a function declaration"),
|
|
|
|
ModuleMembers::FunctionDeclaration(_f) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-03-15 20:49:02 +00:00
|
|
|
_ => panic!("Not implemented: Expression at top level"),
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_parse_2_top_level_construct() {
|
|
|
|
let input = String::from("fun f1(){} fun f2() {}");
|
|
|
|
let tokens = crate::lexic::get_tokens(&input).unwrap();
|
2024-06-01 23:57:10 +00:00
|
|
|
let declarations = build_ast(&tokens).unwrap().productions;
|
2023-09-17 22:58:56 +00:00
|
|
|
|
|
|
|
assert_eq!(declarations.len(), 2);
|
|
|
|
|
|
|
|
match declarations.get(0).unwrap() {
|
2024-06-01 23:57:10 +00:00
|
|
|
ModuleMembers::Binding(_) => panic!("Expected a function declaration"),
|
|
|
|
ModuleMembers::FunctionDeclaration(_f) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-03-15 20:49:02 +00:00
|
|
|
_ => panic!("Not implemented: Expression at top level"),
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
match declarations.get(1).unwrap() {
|
2024-06-01 23:57:10 +00:00
|
|
|
ModuleMembers::Binding(_) => panic!("Expected a function declaration"),
|
|
|
|
ModuleMembers::FunctionDeclaration(_f) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-03-15 20:49:02 +00:00
|
|
|
_ => panic!("Not implemented: Expression at top level"),
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|