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 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 });
|
||||||
|
@ -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()
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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)))
|
||||||
|
Loading…
Reference in New Issue
Block a user