Repurpose module map and rename old to ErrorModules
This commit is contained in:
parent
fa6b7bdf87
commit
f35f1ef701
@ -3,7 +3,7 @@
|
|||||||
//! used for unwrapping syntax sugar, and then be transformed into Reid MIR.
|
//! used for unwrapping syntax sugar, and then be transformed into Reid MIR.
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::token_stream::TokenRange;
|
use crate::{lexer::FullToken, token_stream::TokenRange};
|
||||||
|
|
||||||
pub mod parse;
|
pub mod parse;
|
||||||
pub mod process;
|
pub mod process;
|
||||||
@ -206,6 +206,7 @@ pub enum TopLevelStatement {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Module {
|
pub struct Module {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
|
pub tokens: Vec<FullToken>,
|
||||||
pub top_level_statements: Vec<TopLevelStatement>,
|
pub top_level_statements: Vec<TopLevelStatement>,
|
||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
pub is_main: bool,
|
pub is_main: bool,
|
||||||
|
@ -1,18 +1,25 @@
|
|||||||
use std::{path::PathBuf, process};
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
ast::{self},
|
ast::{self},
|
||||||
mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType, TypeKey},
|
mir::{
|
||||||
|
self, ModuleMap, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType,
|
||||||
|
TypeKey,
|
||||||
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
impl mir::Context {
|
impl mir::Context {
|
||||||
pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context {
|
pub fn from(modules: Vec<mir::Module>, base: PathBuf) -> mir::Context {
|
||||||
mir::Context { modules, base }
|
let mut map = ModuleMap::new();
|
||||||
|
for module in modules {
|
||||||
|
map.insert(module.module_id, module);
|
||||||
|
}
|
||||||
|
mir::Context { modules: map, base }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ast::Module {
|
impl ast::Module {
|
||||||
pub fn process(&self, module_id: SourceModuleId) -> mir::Module {
|
pub fn process(self, module_id: SourceModuleId) -> mir::Module {
|
||||||
let mut imports = Vec::new();
|
let mut imports = Vec::new();
|
||||||
let mut functions = Vec::new();
|
let mut functions = Vec::new();
|
||||||
let mut typedefs = Vec::new();
|
let mut typedefs = Vec::new();
|
||||||
@ -100,6 +107,7 @@ impl ast::Module {
|
|||||||
functions,
|
functions,
|
||||||
path: self.path.clone(),
|
path: self.path.clone(),
|
||||||
is_main: self.is_main,
|
is_main: self.is_main,
|
||||||
|
tokens: self.tokens,
|
||||||
typedefs,
|
typedefs,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ use reid_lib::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
error_raporting::ModuleMap,
|
error_raporting::ErrorModules,
|
||||||
lexer::{FullToken, Position},
|
lexer::{FullToken, Position},
|
||||||
mir::{
|
mir::{
|
||||||
self, implement::TypeCategory, Metadata, NamedVariableRef, SourceModuleId, StructField,
|
self, implement::TypeCategory, Metadata, NamedVariableRef, SourceModuleId, StructField,
|
||||||
@ -40,24 +40,10 @@ impl<'ctx> CodegenContext<'ctx> {
|
|||||||
|
|
||||||
impl mir::Context {
|
impl mir::Context {
|
||||||
/// Compile MIR [`Context`] into [`CodegenContext`] containing LLIR.
|
/// Compile MIR [`Context`] into [`CodegenContext`] containing LLIR.
|
||||||
pub fn codegen<'ctx>(
|
pub fn codegen<'ctx>(&self, context: &'ctx Context) -> CodegenContext<'ctx> {
|
||||||
&self,
|
|
||||||
context: &'ctx Context,
|
|
||||||
mod_map: &ModuleMap,
|
|
||||||
) -> CodegenContext<'ctx> {
|
|
||||||
let mut modules = Vec::new();
|
let mut modules = Vec::new();
|
||||||
for module in &self.modules {
|
for (_, module) in &self.modules {
|
||||||
modules.push(
|
modules.push(module.codegen(context));
|
||||||
module.codegen(
|
|
||||||
context,
|
|
||||||
mod_map
|
|
||||||
.module(&module.module_id)
|
|
||||||
.unwrap()
|
|
||||||
.tokens
|
|
||||||
.as_ref()
|
|
||||||
.unwrap(),
|
|
||||||
),
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
CodegenContext { context }
|
CodegenContext { context }
|
||||||
}
|
}
|
||||||
@ -198,12 +184,9 @@ impl Default for State {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl mir::Module {
|
impl mir::Module {
|
||||||
fn codegen<'ctx>(
|
fn codegen<'ctx>(&self, context: &'ctx Context) -> ModuleCodegen<'ctx> {
|
||||||
&self,
|
|
||||||
context: &'ctx Context,
|
|
||||||
tokens: &Vec<FullToken>,
|
|
||||||
) -> ModuleCodegen<'ctx> {
|
|
||||||
let mut module = context.module(&self.name, self.is_main);
|
let mut module = context.module(&self.name, self.is_main);
|
||||||
|
let tokens = &self.tokens;
|
||||||
|
|
||||||
let (debug, compile_unit) = if let Some(path) = &self.path {
|
let (debug, compile_unit) = if let Some(path) = &self.path {
|
||||||
module.create_debug_info(DebugFileData {
|
module.create_debug_info(DebugFileData {
|
||||||
@ -252,19 +235,24 @@ impl mir::Module {
|
|||||||
insert_debug!(&TypeKind::Char);
|
insert_debug!(&TypeKind::Char);
|
||||||
|
|
||||||
for typedef in &self.typedefs {
|
for typedef in &self.typedefs {
|
||||||
let type_key = TypeKey(typedef.name.clone(), self.module_id);
|
let type_key = TypeKey(typedef.name.clone(), typedef.source_module);
|
||||||
let type_value = match &typedef.kind {
|
|
||||||
TypeDefinitionKind::Struct(StructType(fields)) => {
|
let type_value = if typedef.source_module != self.module_id {
|
||||||
module.custom_type(CustomTypeKind::NamedStruct(NamedStruct(
|
todo!()
|
||||||
typedef.name.clone(),
|
} else {
|
||||||
fields
|
match &typedef.kind {
|
||||||
.iter()
|
TypeDefinitionKind::Struct(StructType(fields)) => {
|
||||||
// TODO: Reorder custom-type definitions such that
|
module.custom_type(CustomTypeKind::NamedStruct(NamedStruct(
|
||||||
// inner types get evaluated first. Otherwise this
|
typedef.name.clone(),
|
||||||
// will cause a panic!
|
fields
|
||||||
.map(|StructField(_, t, _)| t.get_type(&type_values, &types))
|
.iter()
|
||||||
.collect(),
|
// TODO: Reorder custom-type definitions such that
|
||||||
)))
|
// inner types get evaluated first. Otherwise this
|
||||||
|
// will cause a panic!
|
||||||
|
.map(|StructField(_, t, _)| t.get_type(&type_values, &types))
|
||||||
|
.collect(),
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
types.insert(type_value, typedef.clone());
|
types.insert(type_value, typedef.clone());
|
||||||
@ -891,6 +879,7 @@ impl mir::Expression {
|
|||||||
mir::ExprKind::Accessed(expression, type_kind, field) => {
|
mir::ExprKind::Accessed(expression, type_kind, field) => {
|
||||||
let struct_val = expression.codegen(scope, &state.load(false)).unwrap();
|
let struct_val = expression.codegen(scope, &state.load(false)).unwrap();
|
||||||
|
|
||||||
|
dbg!(&expression);
|
||||||
let TypeKind::CodegenPtr(inner) = &struct_val.1 else {
|
let TypeKind::CodegenPtr(inner) = &struct_val.1 else {
|
||||||
panic!("tried accessing non-pointer");
|
panic!("tried accessing non-pointer");
|
||||||
};
|
};
|
||||||
@ -1034,7 +1023,13 @@ impl mir::Expression {
|
|||||||
panic!("Variable was not a pointer?!?")
|
panic!("Variable was not a pointer?!?")
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
StackValue(v.0.derive(var_ptr_instr), *ptr_inner.clone())
|
let TypeKind::Borrow(borrow_inner, mutable) = *ptr_inner.clone() else {
|
||||||
|
panic!();
|
||||||
|
};
|
||||||
|
StackValue(
|
||||||
|
StackValueKind::mutable(mutable, var_ptr_instr),
|
||||||
|
*borrow_inner.clone(),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
@ -63,24 +63,24 @@ impl PartialOrd for ErrorKind {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq)]
|
#[derive(Debug, Clone, PartialEq, Eq)]
|
||||||
pub struct Module {
|
pub struct ErrorModule {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub tokens: Option<Vec<FullToken>>,
|
pub tokens: Option<Vec<FullToken>>,
|
||||||
pub source: Option<String>,
|
pub source: Option<String>,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
#[derive(Debug, Clone, PartialEq, Eq, Default)]
|
||||||
pub struct ModuleMap {
|
pub struct ErrorModules {
|
||||||
module_map: HashMap<mir::SourceModuleId, Module>,
|
module_map: HashMap<mir::SourceModuleId, ErrorModule>,
|
||||||
module_counter: mir::SourceModuleId,
|
module_counter: mir::SourceModuleId,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ModuleMap {
|
impl ErrorModules {
|
||||||
pub fn add_module<T: Into<String>>(&mut self, name: T) -> Option<mir::SourceModuleId> {
|
pub fn add_module<T: Into<String>>(&mut self, name: T) -> Option<mir::SourceModuleId> {
|
||||||
let id = self.module_counter.increment();
|
let id = self.module_counter.increment();
|
||||||
self.module_map.insert(
|
self.module_map.insert(
|
||||||
id,
|
id,
|
||||||
Module {
|
ErrorModule {
|
||||||
name: name.into(),
|
name: name.into(),
|
||||||
tokens: None,
|
tokens: None,
|
||||||
source: None,
|
source: None,
|
||||||
@ -101,21 +101,21 @@ impl ModuleMap {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn module(&self, id: &mir::SourceModuleId) -> Option<&Module> {
|
pub fn module(&self, id: &mir::SourceModuleId) -> Option<&ErrorModule> {
|
||||||
self.module_map.get(id)
|
self.module_map.get(id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq)]
|
#[derive(Debug, Clone, PartialEq)]
|
||||||
pub struct ReidError {
|
pub struct ReidError {
|
||||||
map: ModuleMap,
|
map: ErrorModules,
|
||||||
errors: Vec<ErrorKind>,
|
errors: Vec<ErrorKind>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl ReidError {
|
impl ReidError {
|
||||||
pub fn from_lexer<U>(
|
pub fn from_lexer<U>(
|
||||||
result: Result<U, lexer::Error>,
|
result: Result<U, lexer::Error>,
|
||||||
map: ModuleMap,
|
map: ErrorModules,
|
||||||
module: SourceModuleId,
|
module: SourceModuleId,
|
||||||
) -> Result<U, ReidError> {
|
) -> Result<U, ReidError> {
|
||||||
result.map_err(|error| {
|
result.map_err(|error| {
|
||||||
@ -136,7 +136,7 @@ impl ReidError {
|
|||||||
|
|
||||||
pub fn from_parser<U>(
|
pub fn from_parser<U>(
|
||||||
result: Result<U, token_stream::Error>,
|
result: Result<U, token_stream::Error>,
|
||||||
map: ModuleMap,
|
map: ErrorModules,
|
||||||
module: SourceModuleId,
|
module: SourceModuleId,
|
||||||
) -> Result<U, ReidError> {
|
) -> Result<U, ReidError> {
|
||||||
result.map_err(|error| {
|
result.map_err(|error| {
|
||||||
@ -155,7 +155,7 @@ impl ReidError {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn from_kind<U>(errors: Vec<ErrorKind>, map: ModuleMap) -> ReidError {
|
pub fn from_kind<U>(errors: Vec<ErrorKind>, map: ErrorModules) -> ReidError {
|
||||||
ReidError { map, errors }
|
ReidError { map, errors }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -43,7 +43,7 @@
|
|||||||
|
|
||||||
use std::path::PathBuf;
|
use std::path::PathBuf;
|
||||||
|
|
||||||
use error_raporting::{ErrorKind as ErrorRapKind, ModuleMap, ReidError};
|
use error_raporting::{ErrorKind as ErrorRapKind, ErrorModules, ReidError};
|
||||||
use lexer::FullToken;
|
use lexer::FullToken;
|
||||||
use mir::{
|
use mir::{
|
||||||
linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
|
linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs,
|
||||||
@ -64,7 +64,7 @@ mod util;
|
|||||||
pub fn parse_module<'map, T: Into<String>>(
|
pub fn parse_module<'map, T: Into<String>>(
|
||||||
source: &str,
|
source: &str,
|
||||||
name: T,
|
name: T,
|
||||||
map: &'map mut ModuleMap,
|
map: &'map mut ErrorModules,
|
||||||
) -> Result<(mir::SourceModuleId, Vec<FullToken>), ReidError> {
|
) -> Result<(mir::SourceModuleId, Vec<FullToken>), ReidError> {
|
||||||
let id = map.add_module(name.into()).unwrap();
|
let id = map.add_module(name.into()).unwrap();
|
||||||
map.set_source(id, source.to_owned());
|
map.set_source(id, source.to_owned());
|
||||||
@ -81,8 +81,8 @@ pub fn parse_module<'map, T: Into<String>>(
|
|||||||
|
|
||||||
pub fn compile_module<'map>(
|
pub fn compile_module<'map>(
|
||||||
module_id: mir::SourceModuleId,
|
module_id: mir::SourceModuleId,
|
||||||
tokens: &Vec<FullToken>,
|
tokens: Vec<FullToken>,
|
||||||
map: &'map mut ModuleMap,
|
map: &'map mut ErrorModules,
|
||||||
path: Option<PathBuf>,
|
path: Option<PathBuf>,
|
||||||
is_main: bool,
|
is_main: bool,
|
||||||
) -> Result<mir::Module, ReidError> {
|
) -> Result<mir::Module, ReidError> {
|
||||||
@ -101,8 +101,11 @@ pub fn compile_module<'map>(
|
|||||||
statements.push(statement);
|
statements.push(statement);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
drop(token_stream);
|
||||||
|
|
||||||
let ast_module = ast::Module {
|
let ast_module = ast::Module {
|
||||||
name: module.name,
|
name: module.name,
|
||||||
|
tokens: tokens,
|
||||||
top_level_statements: statements,
|
top_level_statements: statements,
|
||||||
path,
|
path,
|
||||||
is_main,
|
is_main,
|
||||||
@ -113,7 +116,7 @@ pub fn compile_module<'map>(
|
|||||||
|
|
||||||
pub fn perform_all_passes<'map>(
|
pub fn perform_all_passes<'map>(
|
||||||
context: &mut mir::Context,
|
context: &mut mir::Context,
|
||||||
module_map: &'map mut ModuleMap,
|
module_map: &'map mut ErrorModules,
|
||||||
) -> Result<(), ReidError> {
|
) -> Result<(), ReidError> {
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
dbg!(&context);
|
dbg!(&context);
|
||||||
@ -193,13 +196,13 @@ pub fn perform_all_passes<'map>(
|
|||||||
pub fn compile_and_pass<'map>(
|
pub fn compile_and_pass<'map>(
|
||||||
source: &str,
|
source: &str,
|
||||||
path: PathBuf,
|
path: PathBuf,
|
||||||
module_map: &'map mut ModuleMap,
|
module_map: &'map mut ErrorModules,
|
||||||
) -> Result<CompileOutput, ReidError> {
|
) -> Result<CompileOutput, ReidError> {
|
||||||
let path = path.canonicalize().unwrap();
|
let path = path.canonicalize().unwrap();
|
||||||
let name = path.file_name().unwrap().to_str().unwrap().to_owned();
|
let name = path.file_name().unwrap().to_str().unwrap().to_owned();
|
||||||
|
|
||||||
let (id, tokens) = parse_module(source, name, module_map)?;
|
let (id, tokens) = parse_module(source, name, module_map)?;
|
||||||
let module = compile_module(id, &tokens, module_map, Some(path.clone()), true)?;
|
let module = compile_module(id, tokens, module_map, Some(path.clone()), true)?;
|
||||||
|
|
||||||
let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned());
|
let mut mir_context = mir::Context::from(vec![module], path.parent().unwrap().to_owned());
|
||||||
|
|
||||||
@ -211,7 +214,7 @@ pub fn compile_and_pass<'map>(
|
|||||||
println!("{}", &mir_context);
|
println!("{}", &mir_context);
|
||||||
|
|
||||||
let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION")));
|
let mut context = Context::new(format!("Reid ({})", env!("CARGO_PKG_VERSION")));
|
||||||
let codegen_modules = mir_context.codegen(&mut context, &module_map);
|
let codegen_modules = mir_context.codegen(&mut context);
|
||||||
|
|
||||||
#[cfg(debug_assertions)]
|
#[cfg(debug_assertions)]
|
||||||
println!("{}", &codegen_modules.context);
|
println!("{}", &codegen_modules.context);
|
||||||
@ -221,6 +224,6 @@ pub fn compile_and_pass<'map>(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_simple(source: &str, path: PathBuf) -> Result<CompileOutput, ReidError> {
|
pub fn compile_simple(source: &str, path: PathBuf) -> Result<CompileOutput, ReidError> {
|
||||||
let mut map = ModuleMap::default();
|
let mut map = ErrorModules::default();
|
||||||
compile_and_pass(source, path, &mut map)
|
compile_and_pass(source, path, &mut map)
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@ use super::*;
|
|||||||
|
|
||||||
impl Display for Context {
|
impl Display for Context {
|
||||||
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
for module in &self.modules {
|
for (_, module) in &self.modules {
|
||||||
Display::fmt(&module, f)?;
|
Display::fmt(&module, f)?;
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -9,8 +9,7 @@ use std::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
compile_module,
|
compile_module,
|
||||||
error_raporting::{ModuleMap, ReidError},
|
error_raporting::{ErrorModules, ReidError},
|
||||||
lexer::FullToken,
|
|
||||||
mir::{SourceModuleId, TypeDefinition, TypeKey, TypeKind},
|
mir::{SourceModuleId, TypeDefinition, TypeKey, TypeKind},
|
||||||
parse_module,
|
parse_module,
|
||||||
};
|
};
|
||||||
@ -47,22 +46,21 @@ pub enum ErrorKind {
|
|||||||
FunctionIsPrivate(String, String),
|
FunctionIsPrivate(String, String),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn compile_std(
|
pub fn compile_std(module_map: &mut ErrorModules) -> Result<Module, ReidError> {
|
||||||
module_map: &mut ModuleMap,
|
|
||||||
) -> Result<(super::Module, Vec<FullToken>), ReidError> {
|
|
||||||
let (id, tokens) = parse_module(STD_SOURCE, "standard_library", module_map)?;
|
let (id, tokens) = parse_module(STD_SOURCE, "standard_library", module_map)?;
|
||||||
let module = compile_module(id, &tokens, module_map, None, false)?;
|
let module = compile_module(id, tokens, module_map, None, false)?;
|
||||||
|
|
||||||
|
let module_id = module.module_id;
|
||||||
let mut mir_context = super::Context::from(vec![module], Default::default());
|
let mut mir_context = super::Context::from(vec![module], Default::default());
|
||||||
|
|
||||||
let std_compiled = mir_context.modules.remove(0);
|
let std_compiled = mir_context.modules.remove(&module_id).unwrap();
|
||||||
Ok((std_compiled, tokens))
|
Ok(std_compiled)
|
||||||
}
|
}
|
||||||
|
|
||||||
/// 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 LinkerPass<'map> {
|
pub struct LinkerPass<'map> {
|
||||||
pub module_map: &'map mut ModuleMap,
|
pub module_map: &'map mut ErrorModules,
|
||||||
pub is_lib: bool,
|
pub is_lib: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -72,16 +70,15 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
type Data = ();
|
type Data = ();
|
||||||
type TError = ErrorKind;
|
type TError = ErrorKind;
|
||||||
fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult {
|
fn context(&mut self, context: &mut Context, mut state: LinkerPassState) -> PassResult {
|
||||||
let mains = context
|
let mains = (&mut context.modules)
|
||||||
.modules
|
.into_iter()
|
||||||
.iter_mut()
|
.filter(|(_, module)| module.is_main)
|
||||||
.filter(|m| m.is_main)
|
|
||||||
.collect::<Vec<_>>();
|
.collect::<Vec<_>>();
|
||||||
if mains.len() > 1 {
|
if mains.len() > 1 {
|
||||||
state.note_errors(&vec![ErrorKind::MultipleMainsAtStart], Metadata::default());
|
state.note_errors(&vec![ErrorKind::MultipleMainsAtStart], Metadata::default());
|
||||||
return Ok(());
|
return Ok(());
|
||||||
}
|
}
|
||||||
if let Some(main) = mains.first() {
|
if let Some((_, main)) = mains.first() {
|
||||||
if let None = main.functions.iter().find(|f| f.name == "main") {
|
if let None = main.functions.iter().find(|f| f.name == "main") {
|
||||||
if !self.is_lib {
|
if !self.is_lib {
|
||||||
state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default());
|
state.note_errors(&vec![ErrorKind::NoMainFunction], Metadata::default());
|
||||||
@ -95,26 +92,19 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
let mut modules = HashMap::<String, Rc<RefCell<_>>>::new();
|
let mut modules = HashMap::<SourceModuleId, Rc<RefCell<_>>>::new();
|
||||||
|
let mut module_ids = HashMap::<String, SourceModuleId>::new();
|
||||||
|
|
||||||
for module in context.modules.drain(..) {
|
for (mod_id, module) in context.modules.drain() {
|
||||||
let tokens = self
|
modules.insert(mod_id, Rc::new(RefCell::new(module)));
|
||||||
.module_map
|
|
||||||
.module(&module.module_id)
|
|
||||||
.unwrap()
|
|
||||||
.tokens
|
|
||||||
.clone()
|
|
||||||
.unwrap();
|
|
||||||
modules.insert(module.name.clone(), Rc::new(RefCell::new((module, tokens))));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let mut modules_to_process: Vec<Rc<RefCell<(Module, Vec<FullToken>)>>> =
|
let mut modules_to_process: Vec<Rc<RefCell<_>>> = modules.values().cloned().collect();
|
||||||
modules.values().cloned().collect();
|
|
||||||
|
|
||||||
while let Some(module) = modules_to_process.pop() {
|
while let Some(module) = modules_to_process.pop() {
|
||||||
let mut importer_module = module.borrow_mut();
|
let mut importer_module = module.borrow_mut();
|
||||||
|
|
||||||
for import in importer_module.0.imports.clone() {
|
for import in importer_module.imports.clone() {
|
||||||
let Import(path, _) = &import;
|
let Import(path, _) = &import;
|
||||||
if path.len() != 2 {
|
if path.len() != 2 {
|
||||||
state.ok::<_, Infallible>(
|
state.ok::<_, Infallible>(
|
||||||
@ -125,14 +115,18 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
|
|
||||||
let module_name = unsafe { path.get_unchecked(0) };
|
let module_name = unsafe { path.get_unchecked(0) };
|
||||||
|
|
||||||
let mut imported = if let Some(module) = modules.get_mut(module_name) {
|
let mut imported = if let Some(module) =
|
||||||
|
modules.get_mut(module_ids.get(module_name).unwrap())
|
||||||
|
{
|
||||||
module
|
module
|
||||||
} else if module_name == "std" {
|
} else if module_name == "std" {
|
||||||
|
let std = compile_std(&mut self.module_map)?;
|
||||||
modules.insert(
|
modules.insert(
|
||||||
"std".to_owned(),
|
std.module_id,
|
||||||
Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
|
Rc::new(RefCell::new(compile_std(&mut self.module_map)?)),
|
||||||
);
|
);
|
||||||
modules.get("std").unwrap()
|
module_ids.insert(std.name, std.module_id);
|
||||||
|
modules.get(&std.module_id).unwrap()
|
||||||
} else {
|
} else {
|
||||||
let file_path =
|
let file_path =
|
||||||
PathBuf::from(&context.base.clone()).join(module_name.to_owned() + ".reid");
|
PathBuf::from(&context.base.clone()).join(module_name.to_owned() + ".reid");
|
||||||
@ -160,8 +154,7 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
match compile_module(id, &tokens, &mut self.module_map, Some(file_path), false)
|
match compile_module(id, tokens, &mut self.module_map, Some(file_path), false) {
|
||||||
{
|
|
||||||
Ok(imported_module) => {
|
Ok(imported_module) => {
|
||||||
if imported_module.is_main {
|
if imported_module.is_main {
|
||||||
state.ok::<_, Infallible>(
|
state.ok::<_, Infallible>(
|
||||||
@ -170,12 +163,11 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
);
|
);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let module_name = imported_module.name.clone();
|
let module_id = imported_module.module_id;
|
||||||
modules.insert(
|
module_ids
|
||||||
module_name.clone(),
|
.insert(imported_module.name.clone(), imported_module.module_id);
|
||||||
Rc::new(RefCell::new((imported_module, tokens))),
|
modules.insert(module_id, Rc::new(RefCell::new(imported_module)));
|
||||||
);
|
let imported = modules.get_mut(&module_id).unwrap();
|
||||||
let imported = modules.get_mut(&module_name).unwrap();
|
|
||||||
modules_to_process.push(imported.clone());
|
modules_to_process.push(imported.clone());
|
||||||
imported
|
imported
|
||||||
}
|
}
|
||||||
@ -194,13 +186,9 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
.borrow_mut();
|
.borrow_mut();
|
||||||
|
|
||||||
let func_name = unsafe { path.get_unchecked(1) };
|
let func_name = unsafe { path.get_unchecked(1) };
|
||||||
let imported_mod_name = imported.0.name.clone();
|
let imported_mod_name = imported.name.clone();
|
||||||
|
|
||||||
let Some(func) = imported
|
let Some(func) = imported.functions.iter_mut().find(|f| f.name == *func_name)
|
||||||
.0
|
|
||||||
.functions
|
|
||||||
.iter_mut()
|
|
||||||
.find(|f| f.name == *func_name)
|
|
||||||
else {
|
else {
|
||||||
state.ok::<_, Infallible>(
|
state.ok::<_, Infallible>(
|
||||||
Err(ErrorKind::NoSuchFunctionInModule(
|
Err(ErrorKind::NoSuchFunctionInModule(
|
||||||
@ -228,7 +216,6 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
func.is_imported = true;
|
func.is_imported = true;
|
||||||
|
|
||||||
if let Some(existing) = importer_module
|
if let Some(existing) = importer_module
|
||||||
.0
|
|
||||||
.functions
|
.functions
|
||||||
.iter()
|
.iter()
|
||||||
.find(|f| f.name == *func_name)
|
.find(|f| f.name == *func_name)
|
||||||
@ -304,8 +291,8 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
let mut seen = HashSet::new();
|
let mut seen = HashSet::new();
|
||||||
seen.extend(imported_types.clone());
|
seen.extend(imported_types.clone());
|
||||||
|
|
||||||
let imported_mod_id = imported.0.module_id;
|
let imported_mod_id = imported.module_id;
|
||||||
let imported_mod_typedefs = &mut imported.0.typedefs;
|
let imported_mod_typedefs = &mut imported.typedefs;
|
||||||
|
|
||||||
for typekey in imported_types.clone() {
|
for typekey in imported_types.clone() {
|
||||||
let typedef = imported_mod_typedefs
|
let typedef = imported_mod_typedefs
|
||||||
@ -323,10 +310,10 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.clone();
|
.clone();
|
||||||
|
|
||||||
importer_module.0.typedefs.push(typedef.clone());
|
importer_module.typedefs.push(typedef.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
importer_module.0.functions.push(FunctionDefinition {
|
importer_module.functions.push(FunctionDefinition {
|
||||||
name: func_name,
|
name: func_name,
|
||||||
is_pub: false,
|
is_pub: false,
|
||||||
is_imported: false,
|
is_imported: false,
|
||||||
@ -337,9 +324,9 @@ impl<'map> Pass for LinkerPass<'map> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
context.modules = modules
|
let modules: Vec<Module> = modules
|
||||||
.into_values()
|
.into_values()
|
||||||
.map(|v| Rc::into_inner(v).unwrap().into_inner().0)
|
.map(|v| Rc::into_inner(v).unwrap().into_inner())
|
||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
|
@ -354,11 +354,14 @@ pub struct Module {
|
|||||||
pub functions: Vec<FunctionDefinition>,
|
pub functions: Vec<FunctionDefinition>,
|
||||||
pub typedefs: Vec<TypeDefinition>,
|
pub typedefs: Vec<TypeDefinition>,
|
||||||
pub path: Option<PathBuf>,
|
pub path: Option<PathBuf>,
|
||||||
|
pub tokens: Vec<FullToken>,
|
||||||
pub is_main: bool,
|
pub is_main: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub type ModuleMap = HashMap<SourceModuleId, Module>;
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Context {
|
pub struct Context {
|
||||||
pub modules: Vec<Module>,
|
pub modules: ModuleMap,
|
||||||
pub base: PathBuf,
|
pub base: PathBuf,
|
||||||
}
|
}
|
||||||
|
@ -277,7 +277,7 @@ impl Context {
|
|||||||
let mut state = State::new();
|
let mut state = State::new();
|
||||||
let mut scope = Scope::default();
|
let mut scope = Scope::default();
|
||||||
pass.context(self, PassState::from(&mut state, &mut scope, None))?;
|
pass.context(self, PassState::from(&mut state, &mut scope, None))?;
|
||||||
for module in &mut self.modules {
|
for (_, module) in (&mut self.modules).into_iter() {
|
||||||
module.pass(pass, &mut state, &mut scope.inner())?;
|
module.pass(pass, &mut state, &mut scope.inner())?;
|
||||||
}
|
}
|
||||||
Ok(state)
|
Ok(state)
|
||||||
|
@ -10,13 +10,10 @@ mod util;
|
|||||||
fn test(source: &str, name: &str) {
|
fn test(source: &str, name: &str) {
|
||||||
let mut map = Default::default();
|
let mut map = Default::default();
|
||||||
let (id, tokens) = assert_err(parse_module(source, name, &mut map));
|
let (id, tokens) = assert_err(parse_module(source, name, &mut map));
|
||||||
let module = assert_err(compile_module(id, &tokens, &mut map, None, true));
|
let module = assert_err(compile_module(id, tokens, &mut map, None, true));
|
||||||
|
|
||||||
assert_err(perform_all_passes(
|
assert_err(perform_all_passes(
|
||||||
&mut mir::Context {
|
&mut mir::Context::from(vec![module], Default::default()),
|
||||||
modules: vec![module],
|
|
||||||
base: Default::default(),
|
|
||||||
},
|
|
||||||
&mut map,
|
&mut map,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ fn compiles() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn passes_all_passes() {
|
fn passes_all_passes() {
|
||||||
let mut map = Default::default();
|
let mut map = Default::default();
|
||||||
let Ok((mut std, _)) = compile_std(&mut map) else {
|
let Ok(mut std) = compile_std(&mut map) else {
|
||||||
panic!()
|
panic!()
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -22,10 +22,7 @@ fn passes_all_passes() {
|
|||||||
std.is_main = true;
|
std.is_main = true;
|
||||||
|
|
||||||
assert_err(perform_all_passes(
|
assert_err(perform_all_passes(
|
||||||
&mut mir::Context {
|
&mut mir::Context::from(vec![std], Default::default()),
|
||||||
modules: vec![std],
|
|
||||||
base: Default::default(),
|
|
||||||
},
|
|
||||||
&mut map,
|
&mut map,
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user