2024-06-02 13:36:12 +00:00
|
|
|
use crate::error_handling::MistiError;
|
2023-03-14 21:10:43 +00:00
|
|
|
|
2023-10-01 22:43:59 +00:00
|
|
|
mod functions;
|
2024-10-02 21:25:42 +00:00
|
|
|
pub mod parseable;
|
2024-06-02 02:32:16 +00:00
|
|
|
mod parsers;
|
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
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
use crate::lexic::token::Token;
|
2023-09-09 01:28:53 +00:00
|
|
|
use ast::ModuleAST;
|
2023-01-05 23:20:58 +00:00
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
use self::parseable::{Parseable, ParsingError, ParsingResult};
|
2024-03-15 20:49:02 +00:00
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
/// Builds 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> {
|
2024-06-02 13:36:12 +00:00
|
|
|
match ModuleAST::try_parse(tokens, 0) {
|
|
|
|
Ok((module, _)) => Ok(module),
|
2024-09-30 23:37:36 +00:00
|
|
|
Err(ParsingError::Err(error)) => Err(error),
|
2024-06-02 13:36:12 +00:00
|
|
|
_ => {
|
|
|
|
// This shouldn't happen. The module parser returns an error if it finds nothing to parse.
|
|
|
|
unreachable!("Illegal state during parsing: The Module parse should always return a result or error")
|
2024-03-15 21:44:29 +00:00
|
|
|
}
|
2024-03-18 13:57:28 +00:00
|
|
|
}
|
2023-03-14 21:10:43 +00:00
|
|
|
}
|
2023-09-17 22:58:56 +00:00
|
|
|
|
|
|
|
#[cfg(test)]
|
|
|
|
mod tests {
|
|
|
|
use super::*;
|
2024-06-02 13:36:12 +00:00
|
|
|
use crate::lexic::get_tokens;
|
|
|
|
use ast::ModuleMembers;
|
|
|
|
use tests::ast::Statement;
|
2023-09-17 22:58:56 +00:00
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
// TODO: Reenable when statement parsing is rewritten
|
2023-09-17 22:58:56 +00:00
|
|
|
#[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");
|
2024-06-02 13:36:12 +00:00
|
|
|
let tokens = get_tokens(&input).unwrap();
|
|
|
|
let productions = build_ast(&tokens).unwrap().productions;
|
2023-09-17 22:58:56 +00:00
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
assert_eq!(productions.len(), 1);
|
2023-09-17 22:58:56 +00:00
|
|
|
|
2024-06-02 13:36:12 +00:00
|
|
|
match productions.get(0).unwrap() {
|
|
|
|
ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-06-02 13:36:12 +00:00
|
|
|
_ => panic!("Expected a function declaration"),
|
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-02 13:36:12 +00:00
|
|
|
ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-06-02 13:36:12 +00:00
|
|
|
_ => panic!("Expected a function declaration as first production"),
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
match declarations.get(1).unwrap() {
|
2024-06-02 13:36:12 +00:00
|
|
|
ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
|
2023-09-17 22:58:56 +00:00
|
|
|
assert!(true)
|
|
|
|
}
|
2024-06-02 13:36:12 +00:00
|
|
|
_ => panic!("Expected a function declaration as first production"),
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|
|
|
|
}
|
2024-07-28 23:18:11 +00:00
|
|
|
|
|
|
|
#[test]
|
|
|
|
fn should_fail_on_syntax_error() {
|
|
|
|
let input = String::from("fun gaa {}");
|
|
|
|
let tokens = get_tokens(&input).unwrap();
|
|
|
|
let ast = build_ast(&tokens);
|
|
|
|
|
|
|
|
match ast {
|
|
|
|
Ok(_) => panic!("Expected an Err"),
|
|
|
|
Err(_) => {}
|
|
|
|
}
|
|
|
|
}
|
2023-09-17 22:58:56 +00:00
|
|
|
}
|