#[cfg(feature = "timer")]
use std::time::Instant;
use ast::AST;
use codegen::Codegen;
use lexer::{Lexer, Token};
use name_resolution::Resolver;
use parser::Parser;
pub mod ast;
pub mod codegen;
pub mod debug;
pub mod error;
pub mod extension;
pub mod lexer;
pub mod macros;
pub mod name_resolution;
pub mod opcodes;
pub mod parser;
pub mod runtime_error;
pub mod test;
pub mod vm;
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<Token>) -> (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
}