Add importer pass, make importer import module properly

This commit is contained in:
Sofia 2025-07-14 20:33:02 +03:00
parent a71843dfe9
commit 848347e4a8
5 changed files with 39 additions and 18 deletions

View File

@ -42,7 +42,9 @@
use std::path::PathBuf; use std::path::PathBuf;
use mir::{typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs}; use mir::{
imports::ImportsPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
};
use reid_lib::Context; use reid_lib::Context;
use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream}; use crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
@ -65,7 +67,11 @@ pub enum ReidError {
TypeCheckErrors(Vec<mir::pass::Error<mir::typecheck::ErrorKind>>), TypeCheckErrors(Vec<mir::pass::Error<mir::typecheck::ErrorKind>>),
} }
pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module, ReidError> { pub fn compile_module(
source: &str,
name: String,
path: Option<PathBuf>,
) -> Result<mir::Module, ReidError> {
let tokens = lexer::tokenize(source)?; let tokens = lexer::tokenize(source)?;
dbg!(&tokens); dbg!(&tokens);
@ -80,7 +86,7 @@ pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module
} }
let ast_module = ast::Module { let ast_module = ast::Module {
name: "test".to_owned(), name,
top_level_statements: statements, top_level_statements: statements,
path, path,
}; };
@ -92,13 +98,23 @@ pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module
/// and `hello.asm` from it, which can be linked using `ld` to produce an /// and `hello.asm` from it, which can be linked using `ld` to produce an
/// executable file. /// executable file.
pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> { pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> {
let path = path.canonicalize().unwrap();
let mut mir_context = mir::Context::from( let mut mir_context = mir::Context::from(
vec![compile_module(source, Some(path.clone()))?], vec![compile_module(
source,
"main".to_owned(),
Some(path.clone()),
)?],
path.parent().unwrap().to_owned(), path.parent().unwrap().to_owned(),
); );
println!("{}", &mir_context); println!("{}", &mir_context);
let state = mir_context.pass(&mut ImportsPass);
dbg!(&state);
println!("{}", &mir_context);
let refs = TypeRefs::default(); let refs = TypeRefs::default();
let state = mir_context.pass(&mut TypeInference { refs: &refs }); let state = mir_context.pass(&mut TypeInference { refs: &refs });

View File

@ -40,7 +40,8 @@ impl Display for FunctionDefinition {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!( write!(
f, f,
"fn {}({}) -> {} ", "{}fn {}({}) -> {} ",
if self.is_pub { "pub " } else { "" },
self.name, self.name,
self.parameters self.parameters
.iter() .iter()

View File

@ -24,7 +24,7 @@ pub enum ErrorKind {
/// Struct used to implement a type-checking pass that can be performed on the /// Struct used to implement a type-checking pass that can be performed on the
/// MIR. /// MIR.
pub struct ImportsPass {} pub struct ImportsPass;
impl Pass for ImportsPass { impl Pass for ImportsPass {
type TError = ErrorKind; type TError = ErrorKind;
@ -35,13 +35,9 @@ impl Pass for ImportsPass {
modules.insert(module.name.clone(), module); modules.insert(module.name.clone(), module);
} }
let mut modules_to_process: Vec<_> = modules.values().cloned().collect(); let mut modules_to_process: Vec<Module> = modules.values().cloned().collect();
let iter = modules_to_process.iter_mut();
for module in iter {
let mut new_modules = Vec::new();
while let Some(mut module) = modules_to_process.pop() {
for import in &module.imports { for import in &module.imports {
let Import(path, _) = import; let Import(path, _) = import;
if path.len() != 2 { if path.len() != 2 {
@ -56,8 +52,10 @@ impl Pass for ImportsPass {
let imported = if let Some(module) = modules.get(module_name) { let imported = if let Some(module) = modules.get(module_name) {
module module
} else { } else {
let file_path = PathBuf::from(&context.base.clone()).join(module_name); let file_path =
PathBuf::from(&context.base.clone()).join(module_name.to_owned() + ".reid");
dbg!(&file_path);
let Ok(source) = fs::read_to_string(&file_path) else { let Ok(source) = fs::read_to_string(&file_path) else {
state.ok::<_, Infallible>( state.ok::<_, Infallible>(
Err(ErrorKind::ModuleNotFound(module_name.clone())), Err(ErrorKind::ModuleNotFound(module_name.clone())),
@ -66,10 +64,12 @@ impl Pass for ImportsPass {
continue; continue;
}; };
match compile_module(&source, Some(file_path)) { match compile_module(&source, module_name.clone(), Some(file_path)) {
Ok(m) => { Ok(m) => {
new_modules.push(m); let module_name = module.name.clone();
new_modules.last().unwrap() modules.insert(module_name.clone(), m);
modules_to_process.push(modules.get_mut(&module_name).unwrap().clone());
modules.get(&module_name).unwrap()
} }
Err(err) => { Err(err) => {
state.ok::<_, Infallible>( state.ok::<_, Infallible>(
@ -115,6 +115,10 @@ impl Pass for ImportsPass {
kind: super::FunctionDefinitionKind::Extern, kind: super::FunctionDefinitionKind::Extern,
}); });
} }
modules.insert(module.name.clone(), module);
} }
context.modules = modules.into_values().collect();
} }
} }

View File

@ -234,7 +234,7 @@ impl Module {
pass.module(self, PassState::from(state, scope)); pass.module(self, PassState::from(state, scope));
for function in &mut self.functions { for function in &mut self.functions {
function.pass(pass, state, scope); function.pass(pass, state, &mut scope.inner());
} }
} }
} }

View File

@ -92,7 +92,7 @@ impl FunctionDefinition {
let inferred = match &mut self.kind { let inferred = match &mut self.kind {
FunctionDefinitionKind::Local(block, _) => { FunctionDefinitionKind::Local(block, _) => {
state.scope.return_type_hint = Some(self.return_type.clone()); state.scope.return_type_hint = Some(self.return_type.clone());
block.typecheck(state, &hints, Some(&return_type)) block.typecheck(&mut state.inner(), &hints, Some(&return_type))
} }
FunctionDefinitionKind::Extern => { FunctionDefinitionKind::Extern => {
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))) Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))