diff --git a/compiler/src/lib.rs b/compiler/src/lib.rs new file mode 100644 index 0000000..c94ab1a --- /dev/null +++ b/compiler/src/lib.rs @@ -0,0 +1,74 @@ +#![feature(try_trait_v2)] + +use std::path::Path; + +use common::logging::log; + +use crate::{ + codegen::CodeGenerator, + parser::{ParseResult, Parser}, + semantic_analyser::Analyser, +}; + +mod codegen; +mod lexer; +mod parser; +mod registers; +mod semantic_analyser; + +pub fn compile_file( + input_path: &Path, + output_path: &Path, +) -> Result<(), Box> { + let input = std::fs::read_to_string(input_path).expect("Failed to read input file"); + + log("Tokenising Input..."); + + let lexer = lexer::Lexer::new(&input); + let tokens = lexer.collect::>(); + // println!("{tokens:?}"); + + log(&format!("Parsing {} Tokens...", tokens.len())); + + let mut parser = Parser::new(tokens); + let ast = match parser.parse() { + ParseResult::Accept(ast) => ast, + ParseResult::Reject(e) => { + eprintln!("Error: {e:?}"); + return Err("Parsing error".into()); + } + ParseResult::Deny => { + panic!("Parser denied parsing") + } + }; + // println!("{ast:#?}"); + + log("Analyzing AST..."); + log("Checking Type Information..."); + + let analyser = Analyser::new(); + analyser.analyse(ast.clone()).unwrap(); + + log("Generating Code..."); + + // Code Gen + let mut generator = CodeGenerator::new(ast); + let result = match generator.generate() { + Ok(code) => code, + Err(e) => { + eprintln!("Parsing error: {:?}", e); + return Err("Code generation error".into()); + } + }; + + // println!("{result}"); + std::fs::write(output_path, &result).expect("Failed to write output"); + + log(&format!( + "Compilation Successful ✅ \n\tSource: {}\n\tOutput: {}\n", + input_path.display(), + output_path.display(), + )); + + Ok(()) +}