#[cfg(feature = "timer")] use std::time::Instant; use ast::AST; use codegen::Codegen; use lexer::{Lexer, Token}; use parser::Parser; use name_resolution::Resolver; pub mod debug; pub mod error; pub mod runtime_error; pub mod lexer; pub mod macros; pub mod parser; pub mod ast; pub mod name_resolution; pub mod opcodes; pub mod codegen; pub mod vm; pub mod test; pub mod extension; pub fn run_lexer(input: String) -> Lexer { let mut lexer = Lexer::new(input); while lexer.next_token() {} lexer } pub fn run_parser(text: String, input: Vec) -> (AST, Parser) { let mut parser = Parser::new(text, input); (parser.program(), parser) } pub fn run_semantic_analysis(text: String, input: AST) -> (AST, Resolver) { let mut analyzer = Resolver::new(text); let ast = analyzer.visit(input); (ast, analyzer) } pub fn run_codegen(text: String, input: AST) -> Codegen { let mut codegen = Codegen::new(text); codegen.visit(input); codegen } // TODO: output bytecode pub fn compile(program: String) -> String { let mut output = "".to_string(); #[cfg(feature = "timer")] let program_instant = Instant::now(); #[cfg(feature = "timer")] let lexer_instant = Instant::now(); let lexer = run_lexer(program.clone()); #[cfg(feature = "timer")] { let lexer_elapsed = lexer_instant.elapsed(); println!("lexer took: {:?}", lexer_elapsed); } for error in lexer.errors.clone() { output += &error.to_string(); output += "\n"; //println!("{}", error); } #[cfg(feature = "debug")] { output += &debug_token_array(lexer.output.clone()); } if lexer.errors.len() != 0 || lexer.output.len() == 0 { return output; } #[cfg(feature = "timer")] let parser_instant = Instant::now(); let (ast, parser) = run_parser(program.clone(), lexer.output); #[cfg(feature = "timer")] { let parser_elapsed = parser_instant.elapsed(); println!("parser took: {:?}", parser_elapsed); } #[cfg(feature = "debug")] println!("{:#?}", ast); for error in parser.errors.clone() { output += &error.to_string(); output += "\n"; } if parser.errors.len() != 0 { return output; } #[cfg(feature = "timer")] let analyzer_instant = Instant::now(); let (ast, analyzer) = run_semantic_analysis(program.clone(), ast.clone()); for error in analyzer.errors.clone() { output += &error.to_string(); output += "\n"; } if analyzer.errors.len() != 0 { return output; } #[cfg(feature = "timer")] { let analyzer_elapsed = analyzer_instant.elapsed(); println!("semantic analysis took: {:?}", analyzer_elapsed); } #[cfg(feature = "timer")] let codegen_instant = Instant::now(); let codegen = run_codegen(program, ast); #[cfg(feature = "timer")] { let codegen_elapsed = codegen_instant.elapsed(); println!("codegen took: {:?}", codegen_elapsed); } #[cfg(feature = "timer")] let vm_instant = Instant::now(); let mut vm = codegen.vm; match vm.run(&mut output) { Ok(()) => {} Err(e) => output += &e.to_string(), } #[cfg(feature = "timer")] { let vm_elapsed = vm_instant.elapsed(); println!("vm took: {:?}", vm_elapsed); let program_elapsed = program_instant.elapsed(); println!("{:?}", program_elapsed); } output }