1pub mod abstractions;
33pub mod components;
34pub mod processes;
35pub mod utils;
36
37pub use abstractions::*;
39pub use components::context::config::Environment;
40pub use components::context::Context;
41pub use components::error_message::typr_error::TypRError;
42pub use components::language::Lang;
43pub use components::r#type::Type;
44
45pub use processes::parsing;
47pub use processes::transpiling;
48pub use processes::type_checking::{typing, typing_with_errors, TypingResult};
49
50pub struct Compiler<S: SourceProvider> {
52 source_provider: S,
53 context: Context,
54}
55
56impl<S: SourceProvider> Compiler<S> {
57 pub fn new(source_provider: S) -> Self {
59 Self {
60 source_provider,
61 context: Context::default(),
62 }
63 }
64
65 pub fn new_wasm(source_provider: S) -> Self {
72 use components::context::config::Config;
73
74 let config = Config::default().set_environment(Environment::Wasm);
75 Self {
76 source_provider,
77 context: config.to_context(),
78 }
79 }
80
81 pub fn with_context(source_provider: S, context: Context) -> Self {
83 Self {
84 source_provider,
85 context,
86 }
87 }
88
89 pub fn get_context(&self) -> Context {
91 self.context.clone()
92 }
93
94 pub fn parse(&self, filename: &str) -> Result<Lang, CompileError> {
96 let source = self
97 .source_provider
98 .get_source(filename)
99 .ok_or_else(|| CompileError::FileNotFound(filename.to_string()))?;
100
101 Ok(parsing::parse_from_string(&source, filename))
102 }
103
104 pub fn type_check(&self, ast: &Lang) -> TypingResult {
106 typing_with_errors(&self.context, ast)
107 }
108
109 pub fn transpile(&self, ast: &Lang) -> TranspileResult {
111 use processes::type_checking::type_checker::TypeChecker;
112
113 let type_checker = TypeChecker::new(self.context.clone()).typing(ast);
114 let r_code = type_checker.clone().transpile();
115 let context = type_checker.get_context();
116
117 TranspileResult {
118 r_code,
119 type_annotations: context.get_type_anotations(),
120 generic_functions: context
121 .get_all_generic_functions()
122 .iter()
123 .map(|(var, _)| var.get_name())
124 .filter(|x| !x.contains("<-"))
125 .collect(),
126 }
127 }
128
129 pub fn compile(&self, filename: &str) -> Result<CompileOutput, CompileError> {
131 let ast = self.parse(filename)?;
132 let typing_result = self.type_check(&ast);
133
134 if typing_result.has_errors() {
135 return Err(CompileError::TypeErrors(typing_result.get_errors().clone()));
136 }
137
138 let transpile_result = self.transpile(&ast);
139
140 Ok(CompileOutput {
141 ast,
142 r_code: transpile_result.r_code,
143 type_annotations: transpile_result.type_annotations,
144 generic_functions: transpile_result.generic_functions,
145 })
146 }
147
148 pub fn get_completions(&self, _source: &str, _position: usize) -> Vec<String> {
150 vec![]
152 }
153
154 pub fn get_hover(&self, _source: &str, _position: usize) -> Option<String> {
156 None
158 }
159}
160
161#[derive(Debug, Clone)]
163pub struct TranspileResult {
164 pub r_code: String,
165 pub type_annotations: String,
166 pub generic_functions: Vec<String>,
167}
168
169#[derive(Debug, Clone)]
171pub struct CompileOutput {
172 pub ast: Lang,
173 pub r_code: String,
174 pub type_annotations: String,
175 pub generic_functions: Vec<String>,
176}
177
178#[derive(Debug, Clone)]
180pub enum CompileError {
181 FileNotFound(String),
182 ParseError(String),
183 TypeErrors(Vec<TypRError>),
184}
185
186impl std::fmt::Display for CompileError {
187 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
188 match self {
189 CompileError::FileNotFound(name) => write!(f, "File not found: {}", name),
190 CompileError::ParseError(msg) => write!(f, "Parse error: {}", msg),
191 CompileError::TypeErrors(errors) => {
192 write!(f, "Type errors:\n")?;
193 for err in errors {
194 write!(f, " - {:?}\n", err)?;
195 }
196 Ok(())
197 }
198 }
199 }
200}
201
202impl std::error::Error for CompileError {}