pub mod abstractions;
pub mod components;
pub mod processes;
pub mod utils;
pub use abstractions::*;
pub use components::context::config::Environment;
pub use components::context::Context;
pub use components::error_message::typr_error::TypRError;
pub use components::language::Lang;
pub use components::r#type::Type;
pub use processes::parsing;
pub use processes::transpiling;
pub use processes::type_checking::{typing, typing_with_errors, TypingResult};
pub struct Compiler<S: SourceProvider> {
source_provider: S,
context: Context,
}
impl<S: SourceProvider> Compiler<S> {
pub fn new(source_provider: S) -> Self {
Self {
source_provider,
context: Context::default(),
}
}
pub fn new_wasm(source_provider: S) -> Self {
use components::context::config::Config;
let config = Config::default().set_environment(Environment::Wasm);
Self {
source_provider,
context: config.to_context(),
}
}
pub fn get_context(&self) -> Context {
self.context.clone()
}
pub fn parse(&self, filename: &str) -> Result<Lang, CompileError> {
let source = self
.source_provider
.get_source(filename)
.ok_or_else(|| CompileError::FileNotFound(filename.to_string()))?;
Ok(parsing::parse_from_string(&source, filename))
}
pub fn type_check(&self, ast: &Lang) -> TypingResult {
typing_with_errors(&self.context, ast)
}
pub fn transpile(&self, ast: &Lang) -> TranspileResult {
use processes::type_checking::type_checker::TypeChecker;
let type_checker = TypeChecker::new(self.context.clone()).typing(ast);
let r_code = type_checker.clone().transpile();
let context = type_checker.get_context();
TranspileResult {
r_code,
type_annotations: context.get_type_anotations(),
generic_functions: context
.get_all_generic_functions()
.iter()
.map(|(var, _)| var.get_name())
.filter(|x| !x.contains("<-"))
.collect(),
}
}
}
#[derive(Debug, Clone)]
pub struct TranspileResult {
pub r_code: String,
pub type_annotations: String,
pub generic_functions: Vec<String>,
}
#[derive(Debug, Clone)]
pub enum CompileError {
FileNotFound(String),
TypeErrors(Vec<TypRError>),
}
impl std::fmt::Display for CompileError {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
CompileError::FileNotFound(name) => write!(f, "File not found: {}", name),
CompileError::TypeErrors(errors) => {
writeln!(f, "Type errors:")?;
for err in errors {
writeln!(f, " - {:?}", err)?;
}
Ok(())
}
}
}
}
impl std::error::Error for CompileError {}