pub mod ast;
pub mod ast2ram;
pub mod ast_analysis;
pub mod ast_transform;
pub mod common;
pub mod error;
pub mod location;
pub mod parser;
pub mod ram;
pub mod ram2rs;
pub mod visitor;

mod syntax;

use error::CompileError;
use proc_macro2::TokenStream;

pub fn compile_file_to_rs(file_name: &str) -> Result<TokenStream, CompileError> {
  let mut ast_program = parser::parse_file(&file_name)?;
  let analysis_result = ast_analysis::analyze(&ast_program)?;
  ast_transform::transform(&mut ast_program, &analysis_result)?;
  let ram_program = ast2ram::ast2ram(&ast_program)?;
  Ok(ram2rs::ram2rs("Prog", &ram_program, &analysis_result))
}

pub fn compile_str_to_rs(s: &str) -> Result<TokenStream, CompileError> {
  let mut ast_program = parser::parse_str(s)?;
  let analysis_result = ast_analysis::analyze(&ast_program)?;
  ast_transform::transform(&mut ast_program, &analysis_result)?;
  let ram_program = ast2ram::ast2ram(&ast_program)?;
  Ok(ram2rs::ram2rs("Prog", &ram_program, &analysis_result))
}

pub fn compile_ast_to_rs(ast: &ast::Program) -> Result<TokenStream, CompileError> {
  let mut ast_program = ast.clone();
  let analysis_result = ast_analysis::analyze(&ast_program)?;
  ast_transform::transform(&mut ast_program, &analysis_result)?;
  let ram_program = ast2ram::ast2ram(&ast_program)?;
  Ok(ram2rs::ram2rs("Prog", &ram_program, &analysis_result))
}
