refactor: fix broken build, disable some tests until refactor is done

This commit is contained in:
Araozu 2024-06-02 08:36:12 -05:00
parent 1d4cec5548
commit ade1a809aa
12 changed files with 102 additions and 121 deletions

View File

@ -17,7 +17,10 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
lexic::get_tokens, lexic::get_tokens,
syntax::{ast::ModuleMembers, build_ast}, syntax::{
ast::{ModuleMembers, Statement},
build_ast,
},
}; };
#[test] #[test]
@ -28,13 +31,12 @@ mod tests {
let fun_dec = result.productions.get(0).unwrap(); let fun_dec = result.productions.get(0).unwrap();
match fun_dec { match fun_dec {
ModuleMembers::Binding(_) => panic!("Expected function declaration"), ModuleMembers::Stmt(Statement::FnDecl(fun_decl)) => {
ModuleMembers::FunctionDeclaration(fun_decl) => {
let transpiled = fun_decl.transpile(); let transpiled = fun_decl.transpile();
assert_eq!("function id() {\n\n}", transpiled); assert_eq!("function id() {\n\n}", transpiled);
} }
_ => panic!("Not implemented: Expression at top level"), _ => panic!("Expected a function declaration"),
} }
} }
} }

View File

@ -20,7 +20,7 @@ mod tests {
use super::*; use super::*;
use crate::{ use crate::{
lexic::token::{Token, TokenType}, lexic::token::{Token, TokenType},
syntax::ast::{var_binding::VariableBinding, Expression, ModuleMembers}, syntax::ast::{var_binding::VariableBinding, Expression, ModuleMembers, Statement},
}; };
#[test] #[test]
@ -40,7 +40,7 @@ mod tests {
}; };
let module = ModuleAST { let module = ModuleAST {
productions: vec![ModuleMembers::Binding(binding)], productions: vec![ModuleMembers::Stmt(Statement::Binding(binding))],
}; };
let result = module.transpile(); let result = module.transpile();

View File

@ -6,7 +6,7 @@ impl Transpilable for Statement<'_> {
fn transpile(&self) -> String { fn transpile(&self) -> String {
let stmt = match self { let stmt = match self {
Statement::FnDecl(f) => f.transpile(), Statement::FnDecl(f) => f.transpile(),
Statement::VarBinding(b) => b.transpile(), Statement::Binding(b) => b.transpile(),
}; };
format!("{stmt};") format!("{stmt};")

View File

@ -1,13 +1,13 @@
use crate::syntax::ast::ModuleMembers; use crate::syntax::ast::{ModuleMembers, Statement};
use super::Transpilable; use super::Transpilable;
impl Transpilable for ModuleMembers<'_> { impl Transpilable for ModuleMembers<'_> {
fn transpile(&self) -> String { fn transpile(&self) -> String {
match self { match self {
ModuleMembers::Binding(binding) => binding.transpile(), ModuleMembers::Stmt(Statement::Binding(b)) => b.transpile(),
ModuleMembers::FunctionDeclaration(fun) => fun.transpile(), ModuleMembers::Stmt(Statement::FnDecl(f)) => f.transpile(),
_ => panic!("Not implemented: Expression at top level"), _ => todo!("Not implemented: Transpilable for Expression"),
} }
} }
} }

View File

@ -40,7 +40,9 @@ impl SemanticCheck for FunctionDeclaration<'_> {
return Err(err); return Err(err);
} }
} }
Statement::FunctionCall(_) => panic!("FunctionCall semantic check not implemented"), Statement::FnDecl(_) => {
todo!("Function declaration: semantic check not implemented")
}
} }
} }

View File

@ -1,4 +1,8 @@
use crate::{semantic::impls::SemanticCheck, syntax::ast::ModuleMembers}; use crate::{
error_handling::MistiError,
semantic::{impls::SemanticCheck, symbol_table::SymbolTable},
syntax::ast::{Expression, ModuleMembers, Statement},
};
impl SemanticCheck for ModuleMembers<'_> { impl SemanticCheck for ModuleMembers<'_> {
fn check_semantics( fn check_semantics(
@ -6,9 +10,25 @@ impl SemanticCheck for ModuleMembers<'_> {
scope: &crate::semantic::symbol_table::SymbolTable, scope: &crate::semantic::symbol_table::SymbolTable,
) -> Result<(), crate::error_handling::MistiError> { ) -> Result<(), crate::error_handling::MistiError> {
match self { match self {
ModuleMembers::Binding(binding) => binding.check_semantics(scope), ModuleMembers::Stmt(statement) => statement.check_semantics(scope),
ModuleMembers::FunctionDeclaration(function) => function.check_semantics(scope), ModuleMembers::Expr(expression) => expression.check_semantics(scope),
_ => panic!("Not implemented"),
} }
} }
} }
// TODO: Move to its own file
impl SemanticCheck for Statement<'_> {
fn check_semantics(&self, scope: &SymbolTable) -> Result<(), MistiError> {
match self {
Statement::Binding(b) => b.check_semantics(scope),
Statement::FnDecl(f) => f.check_semantics(scope),
}
}
}
// TODO: Move to its own file
impl SemanticCheck for Expression<'_> {
fn check_semantics(&self, scope: &SymbolTable) -> Result<(), MistiError> {
todo!("Check semantics for expression")
}
}

View File

@ -23,7 +23,7 @@ pub enum ModuleMembers<'a> {
#[derive(Debug)] #[derive(Debug)]
pub enum Statement<'a> { pub enum Statement<'a> {
VarBinding(VariableBinding<'a>), Binding(VariableBinding<'a>),
FnDecl(FunctionDeclaration<'a>), FnDecl(FunctionDeclaration<'a>),
} }

View File

@ -72,6 +72,8 @@ mod tests {
use super::*; use super::*;
use crate::lexic::get_tokens; use crate::lexic::get_tokens;
// TODO: rewrite, refactor
/*
#[test] #[test]
fn test_parse_block() { fn test_parse_block() {
let tokens = get_tokens(&String::from("{f()}")).unwrap(); let tokens = get_tokens(&String::from("{f()}")).unwrap();
@ -112,4 +114,5 @@ mod tests {
assert_eq!(block.statements.len(), 1); assert_eq!(block.statements.len(), 1);
} }
*/
} }

View File

@ -1,4 +1,4 @@
use crate::error_handling::{MistiError, SyntaxError}; use crate::error_handling::MistiError;
mod binding; mod binding;
mod block; mod block;
@ -11,97 +11,48 @@ mod utils;
pub mod ast; pub mod ast;
use crate::lexic::token::{Token, TokenType}; use crate::lexic::token::Token;
use ast::ModuleAST; use ast::ModuleAST;
use self::ast::ModuleMembers; use self::parseable::{Parseable, ParsingError, ParsingResult};
use self::parseable::{ParsingError, ParsingResult};
/// Constructs the Misti AST from a vector of tokens /// Builds the Misti AST from a vector of tokens
pub fn build_ast<'a>(tokens: &'a Vec<Token>) -> Result<ModuleAST, MistiError> { pub fn build_ast<'a>(tokens: &'a Vec<Token>) -> Result<ModuleAST, MistiError> {
let mut top_level_declarations = Vec::new(); match ModuleAST::try_parse(tokens, 0) {
let token_amount = tokens.len(); Ok((module, _)) => Ok(module),
let mut current_pos = 0; Err(ParsingError::Err(error)) => Err(MistiError::Syntax(error)),
// 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) {
Ok((module, next_pos)) => {
top_level_declarations.push(module);
current_pos = next_pos;
}
Err(ParsingError::Err(err)) => return Err(MistiError::Syntax(err)),
_ => { _ => {
return Err(MistiError::Syntax(SyntaxError { // This shouldn't happen. The module parser returns an error if it finds nothing to parse.
reason: String::from("PARSER couldn't parse any construction"), unreachable!("Illegal state during parsing: The Module parse should always return a result or error")
// FIXME: This should get the position of the _token_ that current_pos points to
error_start: current_pos,
error_end: current_pos,
}));
} }
} }
} }
Ok(ModuleAST {
productions: top_level_declarations,
})
}
fn next_construct<'a>(tokens: &'a Vec<Token>, current_pos: usize) -> ParsingResult<ModuleMembers> {
todo!();
// Try to parse a function declaration
match functions::function_declaration::try_parse(tokens, current_pos) {
Ok((declaration, next_pos)) => {
return Ok((ModuleMembers::Stmt(FnDecl(declaration), next_pos)))
}
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
_ => {}
}
// Try to parse a binding
match binding::try_parse(tokens, current_pos) {
Ok((binding, next_pos)) => return Ok((ModuleMembers::Binding(binding), next_pos)),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
_ => {}
}
// Try to parse an expression
match expression::try_parse(tokens, current_pos) {
Ok((expression, next_pos)) => return Ok((ModuleMembers::Expr(expression), next_pos)),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
_ => {}
}
// No top level construct was found, return unmatched
Err(ParsingError::Unmatched)
}
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use super::*; use super::*;
use crate::lexic::get_tokens;
use ast::ModuleMembers;
use tests::ast::Statement;
// TODO: Reenable when statement parsing is rewritten
/*
#[test] #[test]
fn should_parse_top_level_construct_with_trailing_newline() { fn should_parse_top_level_construct_with_trailing_newline() {
let input = String::from(" fun f1(){}\n"); let input = String::from(" fun f1(){}\n");
let tokens = crate::lexic::get_tokens(&input).unwrap(); let tokens = get_tokens(&input).unwrap();
let declarations = build_ast(&tokens).unwrap().productions; let productions = build_ast(&tokens).unwrap().productions;
assert_eq!(declarations.len(), 1); assert_eq!(productions.len(), 1);
match declarations.get(0).unwrap() { match productions.get(0).unwrap() {
ModuleMembers::Binding(_) => panic!("Expected a function declaration"), ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
ModuleMembers::FunctionDeclaration(_f) => {
assert!(true) assert!(true)
} }
_ => panic!("Not implemented: Expression at top level"), _ => panic!("Expected a function declaration"),
} }
} }
*/
#[test] #[test]
fn should_parse_2_top_level_construct() { fn should_parse_2_top_level_construct() {
@ -112,19 +63,17 @@ mod tests {
assert_eq!(declarations.len(), 2); assert_eq!(declarations.len(), 2);
match declarations.get(0).unwrap() { match declarations.get(0).unwrap() {
ModuleMembers::Binding(_) => panic!("Expected a function declaration"), ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
ModuleMembers::FunctionDeclaration(_f) => {
assert!(true) assert!(true)
} }
_ => panic!("Not implemented: Expression at top level"), _ => panic!("Expected a function declaration as first production"),
} }
match declarations.get(1).unwrap() { match declarations.get(1).unwrap() {
ModuleMembers::Binding(_) => panic!("Expected a function declaration"), ModuleMembers::Stmt(Statement::FnDecl(_f)) => {
ModuleMembers::FunctionDeclaration(_f) => {
assert!(true) assert!(true)
} }
_ => panic!("Not implemented: Expression at top level"), _ => panic!("Expected a function declaration as first production"),
} }
} }
} }

View File

@ -39,7 +39,6 @@ impl<'a> Parseable<'a> for ModuleAST<'a> {
}; };
// Attempt to parse an expression // Attempt to parse an expression
// If this fails the whole thing fails
match Expression::try_parse(tokens, current_pos) { match Expression::try_parse(tokens, current_pos) {
Ok((prod, next_pos)) => { Ok((prod, next_pos)) => {
productions.push(ModuleMembers::Expr(prod)); productions.push(ModuleMembers::Expr(prod));
@ -53,7 +52,7 @@ impl<'a> Parseable<'a> for ModuleAST<'a> {
} }
// If we reached this point we didn't match any productions and fail // If we reached this point we didn't match any productions and fail
let t = tokens[current_pos]; let t = &tokens[current_pos];
return Err(ParsingError::Err(SyntaxError { return Err(ParsingError::Err(SyntaxError {
error_start: t.position, error_start: t.position,

View File

@ -1,4 +1,6 @@
use crate::syntax::{ast::Statement, parseable::Parseable}; use crate::syntax::{
ast::Statement, binding, functions::function_declaration, parseable::Parseable,
};
impl<'a> Parseable<'a> for Statement<'a> { impl<'a> Parseable<'a> for Statement<'a> {
type Item = Statement<'a>; type Item = Statement<'a>;
@ -7,6 +9,29 @@ impl<'a> Parseable<'a> for Statement<'a> {
tokens: &'a Vec<crate::lexic::token::Token>, tokens: &'a Vec<crate::lexic::token::Token>,
current_pos: usize, current_pos: usize,
) -> crate::syntax::parseable::ParsingResult<'a, Self::Item> { ) -> crate::syntax::parseable::ParsingResult<'a, Self::Item> {
todo!() // Try to parse a variable binding
// TODO: Rewrite function_declaration to use Parseable
match binding::try_parse(tokens, current_pos) {
Ok((prod, next)) => {
return Ok((Statement::Binding(prod), next));
}
Err(_) => {
// TODO
}
}
// Try to parse a function declaration
// TODO: Rewrite function_declaration to use Parseable
match function_declaration::try_parse(tokens, current_pos) {
Ok((prod, next)) => {
return Ok((Statement::FnDecl(prod), next));
}
Err(_) => {
// TODO
}
}
// Here nothing was parsed. Should fail
todo!("Nothing was parsed. Should fail")
} }
} }

View File

@ -1,11 +1,6 @@
use crate::lexic::token::Token; use crate::lexic::token::Token;
use super::{ use super::{ast::Statement, binding, ParsingError, ParsingResult};
ast::{Expression, Statement},
binding,
expression::function_call_expr,
ParsingError, ParsingResult,
};
pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Statement> { pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Statement> {
// Try to parse a binding // Try to parse a binding
@ -15,12 +10,15 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Statem
_ => {} _ => {}
} }
// A function call is an expression, not a statement. Remove
// Try to parse a function call // Try to parse a function call
/*
match function_call_expr::try_parse(tokens, pos) { match function_call_expr::try_parse(tokens, pos) {
Ok((Expression::FunctionCall(f), next)) => return Ok((Statement::FunctionCall(f), next)), Ok((Expression::FunctionCall(f), next)) => return Ok((Statement::FunctionCall(f), next)),
Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)), Err(ParsingError::Err(err)) => return Err(ParsingError::Err(err)),
_ => {} _ => {}
}; };
*/
// Return unmatched // Return unmatched
Err(ParsingError::Unmatched) Err(ParsingError::Unmatched)
@ -30,23 +28,6 @@ pub fn try_parse<'a>(tokens: &'a Vec<Token>, pos: usize) -> ParsingResult<Statem
mod tests { mod tests {
use super::*; use super::*;
#[test]
fn should_parse_function_call() {
let input = String::from("f1()");
let tokens = crate::lexic::get_tokens(&input).unwrap();
let statement = try_parse(&tokens, 0);
let statement = match statement {
Ok((s, _)) => s,
_ => panic!("Expected a statement"),
};
match statement {
Statement::FunctionCall(_) => assert!(true),
_ => panic!("Expected a function call"),
}
}
#[test] #[test]
fn should_parse_binding() { fn should_parse_binding() {
let input = String::from("val identifier = 20"); let input = String::from("val identifier = 20");