Add importer pass, make importer import module properly
This commit is contained in:
parent
a71843dfe9
commit
848347e4a8
@ -42,7 +42,9 @@
|
||||
|
||||
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 crate::{ast::TopLevelStatement, lexer::Token, token_stream::TokenStream};
|
||||
@ -65,7 +67,11 @@ pub enum ReidError {
|
||||
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)?;
|
||||
|
||||
dbg!(&tokens);
|
||||
@ -80,7 +86,7 @@ pub fn compile_module(source: &str, path: Option<PathBuf>) -> Result<mir::Module
|
||||
}
|
||||
|
||||
let ast_module = ast::Module {
|
||||
name: "test".to_owned(),
|
||||
name,
|
||||
top_level_statements: statements,
|
||||
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
|
||||
/// executable file.
|
||||
pub fn compile(source: &str, path: PathBuf) -> Result<String, ReidError> {
|
||||
let path = path.canonicalize().unwrap();
|
||||
|
||||
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(),
|
||||
);
|
||||
|
||||
println!("{}", &mir_context);
|
||||
|
||||
let state = mir_context.pass(&mut ImportsPass);
|
||||
dbg!(&state);
|
||||
println!("{}", &mir_context);
|
||||
|
||||
let refs = TypeRefs::default();
|
||||
|
||||
let state = mir_context.pass(&mut TypeInference { refs: &refs });
|
||||
|
@ -40,7 +40,8 @@ impl Display for FunctionDefinition {
|
||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||
write!(
|
||||
f,
|
||||
"fn {}({}) -> {} ",
|
||||
"{}fn {}({}) -> {} ",
|
||||
if self.is_pub { "pub " } else { "" },
|
||||
self.name,
|
||||
self.parameters
|
||||
.iter()
|
||||
|
@ -24,7 +24,7 @@ pub enum ErrorKind {
|
||||
|
||||
/// Struct used to implement a type-checking pass that can be performed on the
|
||||
/// MIR.
|
||||
pub struct ImportsPass {}
|
||||
pub struct ImportsPass;
|
||||
|
||||
impl Pass for ImportsPass {
|
||||
type TError = ErrorKind;
|
||||
@ -35,13 +35,9 @@ impl Pass for ImportsPass {
|
||||
modules.insert(module.name.clone(), module);
|
||||
}
|
||||
|
||||
let mut modules_to_process: Vec<_> = modules.values().cloned().collect();
|
||||
|
||||
let iter = modules_to_process.iter_mut();
|
||||
|
||||
for module in iter {
|
||||
let mut new_modules = Vec::new();
|
||||
let mut modules_to_process: Vec<Module> = modules.values().cloned().collect();
|
||||
|
||||
while let Some(mut module) = modules_to_process.pop() {
|
||||
for import in &module.imports {
|
||||
let Import(path, _) = import;
|
||||
if path.len() != 2 {
|
||||
@ -56,8 +52,10 @@ impl Pass for ImportsPass {
|
||||
let imported = if let Some(module) = modules.get(module_name) {
|
||||
module
|
||||
} 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 {
|
||||
state.ok::<_, Infallible>(
|
||||
Err(ErrorKind::ModuleNotFound(module_name.clone())),
|
||||
@ -66,10 +64,12 @@ impl Pass for ImportsPass {
|
||||
continue;
|
||||
};
|
||||
|
||||
match compile_module(&source, Some(file_path)) {
|
||||
match compile_module(&source, module_name.clone(), Some(file_path)) {
|
||||
Ok(m) => {
|
||||
new_modules.push(m);
|
||||
new_modules.last().unwrap()
|
||||
let module_name = module.name.clone();
|
||||
modules.insert(module_name.clone(), m);
|
||||
modules_to_process.push(modules.get_mut(&module_name).unwrap().clone());
|
||||
modules.get(&module_name).unwrap()
|
||||
}
|
||||
Err(err) => {
|
||||
state.ok::<_, Infallible>(
|
||||
@ -115,6 +115,10 @@ impl Pass for ImportsPass {
|
||||
kind: super::FunctionDefinitionKind::Extern,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
modules.insert(module.name.clone(), module);
|
||||
}
|
||||
|
||||
context.modules = modules.into_values().collect();
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +234,7 @@ impl Module {
|
||||
pass.module(self, PassState::from(state, scope));
|
||||
|
||||
for function in &mut self.functions {
|
||||
function.pass(pass, state, scope);
|
||||
function.pass(pass, state, &mut scope.inner());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -92,7 +92,7 @@ impl FunctionDefinition {
|
||||
let inferred = match &mut self.kind {
|
||||
FunctionDefinitionKind::Local(block, _) => {
|
||||
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 => {
|
||||
Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown)))
|
||||
|
Loading…
Reference in New Issue
Block a user