diff --git a/reid/examples/testcodegen.rs b/reid/examples/testcodegen.rs index a8adaaf..d31c599 100644 --- a/reid/examples/testcodegen.rs +++ b/reid/examples/testcodegen.rs @@ -161,6 +161,7 @@ fn main() { let mir_context = mir::Context { modules: vec![Module { name: "test module".to_owned(), + module_id: SourceModuleId::default(), imports: vec![], functions: vec![fibonacci, main], typedefs: Vec::new(), diff --git a/reid/src/ast/process.rs b/reid/src/ast/process.rs index 4fed60a..34a6a98 100644 --- a/reid/src/ast/process.rs +++ b/reid/src/ast/process.rs @@ -2,7 +2,7 @@ use std::path::PathBuf; use crate::{ ast::{self}, - mir::{self, NamedVariableRef, StmtKind, StructField, StructType}, + mir::{self, NamedVariableRef, SourceModuleId, StmtKind, StructField, StructType}, }; impl mir::Context { @@ -12,7 +12,7 @@ impl mir::Context { } impl ast::Module { - pub fn process(&self) -> mir::Module { + pub fn process(&self, module_id: SourceModuleId) -> mir::Module { let mut imports = Vec::new(); let mut functions = Vec::new(); let mut typedefs = Vec::new(); @@ -21,7 +21,7 @@ impl ast::Module { for stmt in &self.top_level_statements { match stmt { Import(import) => { - imports.push(mir::Import(import.0.clone(), import.1.into())); + imports.push(mir::Import(import.0.clone(), import.1.as_meta(module_id))); } FunctionDefinition(ast::FunctionDefinition(signature, is_pub, block, range)) => { let def = mir::FunctionDefinition { @@ -39,7 +39,10 @@ impl ast::Module { .cloned() .map(|p| (p.0, p.1.into())) .collect(), - kind: mir::FunctionDefinitionKind::Local(block.into_mir(), (*range).into()), + kind: mir::FunctionDefinitionKind::Local( + block.into_mir(module_id), + (*range).as_meta(module_id), + ), }; functions.push(def); } @@ -75,14 +78,14 @@ impl ast::Module { StructField( s.name.clone(), s.ty.clone().into(), - s.range.into(), + s.range.as_meta(module_id), ) }) .collect(), )) } }, - meta: (*range).into(), + meta: (*range).as_meta(module_id), }; typedefs.push(def); } @@ -91,6 +94,7 @@ impl ast::Module { mir::Module { name: self.name.clone(), + module_id: module_id, imports, functions, path: self.path.clone(), @@ -101,7 +105,7 @@ impl ast::Module { } impl ast::Block { - pub fn into_mir(&self) -> mir::Block { + pub fn into_mir(&self, module_id: SourceModuleId) -> mir::Block { let mut mir_statements = Vec::new(); for statement in &self.0 { @@ -115,27 +119,31 @@ impl ast::Block { .map(|t| t.0.into()) .unwrap_or(mir::TypeKind::Vague(mir::VagueType::Unknown)), s_let.0.clone(), - s_let.4.into(), + s_let.4.as_meta(module_id), ), s_let.2, - s_let.3.process(), + s_let.3.process(module_id), ), s_let.4, ), ast::BlockLevelStatement::Set(var_ref, expression, range) => ( - StmtKind::Set(var_ref.process(), expression.process()), + StmtKind::Set(var_ref.process(module_id), expression.process(module_id)), *range, ), ast::BlockLevelStatement::Import { _i } => todo!(), - ast::BlockLevelStatement::Expression(e) => (StmtKind::Expression(e.process()), e.1), - ast::BlockLevelStatement::Return(_, e) => (StmtKind::Expression(e.process()), e.1), + ast::BlockLevelStatement::Expression(e) => { + (StmtKind::Expression(e.process(module_id)), e.1) + } + ast::BlockLevelStatement::Return(_, e) => { + (StmtKind::Expression(e.process(module_id)), e.1) + } }; - mir_statements.push(mir::Statement(kind, range.into())); + mir_statements.push(mir::Statement(kind, range.as_meta(module_id))); } let return_expression = if let Some(r) = &self.1 { - Some((r.0.into(), Box::new(r.1.process()))) + Some((r.0.into(), Box::new(r.1.process(module_id)))) } else { None }; @@ -143,7 +151,7 @@ impl ast::Block { mir::Block { statements: mir_statements, return_expression, - meta: self.2.into(), + meta: self.2.as_meta(module_id), } } } @@ -158,61 +166,67 @@ impl From for mir::ReturnKind { } impl ast::Expression { - fn process(&self) -> mir::Expression { + fn process(&self, module_id: SourceModuleId) -> mir::Expression { let kind = match &self.0 { ast::ExpressionKind::VariableName(name) => mir::ExprKind::Variable(NamedVariableRef( mir::TypeKind::Vague(mir::VagueType::Unknown), name.clone(), - self.1.into(), + self.1.as_meta(module_id), )), ast::ExpressionKind::Literal(literal) => mir::ExprKind::Literal(literal.mir()), ast::ExpressionKind::Binop(binary_operator, lhs, rhs) => mir::ExprKind::BinOp( binary_operator.mir(), - Box::new(lhs.process()), - Box::new(rhs.process()), + Box::new(lhs.process(module_id)), + Box::new(rhs.process(module_id)), ), ast::ExpressionKind::FunctionCall(fn_call_expr) => { mir::ExprKind::FunctionCall(mir::FunctionCall { name: fn_call_expr.0.clone(), return_type: mir::TypeKind::Vague(mir::VagueType::Unknown), - parameters: fn_call_expr.1.iter().map(|e| e.process()).collect(), + parameters: fn_call_expr + .1 + .iter() + .map(|e| e.process(module_id)) + .collect(), }) } - ast::ExpressionKind::BlockExpr(block) => mir::ExprKind::Block(block.into_mir()), + ast::ExpressionKind::BlockExpr(block) => { + mir::ExprKind::Block(block.into_mir(module_id)) + } ast::ExpressionKind::IfExpr(if_expression) => { - let cond = if_expression.0.process(); - let then_block = if_expression.1.into_mir(); + let cond = if_expression.0.process(module_id); + let then_block = if_expression.1.into_mir(module_id); let else_block = if let Some(el) = &if_expression.2 { - Some(el.into_mir()) + Some(el.into_mir(module_id)) } else { None }; mir::ExprKind::If(mir::IfExpression(Box::new(cond), then_block, else_block)) } ast::ExpressionKind::Array(expressions) => { - mir::ExprKind::Array(expressions.iter().map(|e| e.process()).collect()) + mir::ExprKind::Array(expressions.iter().map(|e| e.process(module_id)).collect()) } ast::ExpressionKind::Indexed(expression, idx_expr) => mir::ExprKind::Indexed( - Box::new(expression.process()), + Box::new(expression.process(module_id)), mir::TypeKind::Vague(mir::VagueType::Unknown), - Box::new(idx_expr.process()), + Box::new(idx_expr.process(module_id)), ), ast::ExpressionKind::StructExpression(struct_init) => mir::ExprKind::Struct( struct_init.name.clone(), struct_init .fields .iter() - .map(|(n, e)| (n.clone(), e.process())) + .map(|(n, e)| (n.clone(), e.process(module_id))) .collect(), ), ast::ExpressionKind::Accessed(expression, name) => mir::ExprKind::Accessed( - Box::new(expression.process()), + Box::new(expression.process(module_id)), mir::TypeKind::Vague(mir::VagueType::Unknown), name.clone(), ), }; - mir::Expression(kind, self.1.into()) + mir::Expression(kind, self.1.as_meta(module_id)) } } diff --git a/reid/src/error_raporting.rs b/reid/src/error_raporting.rs new file mode 100644 index 0000000..e69de29 diff --git a/reid/src/lib.rs b/reid/src/lib.rs index e103677..ae7f1ae 100644 --- a/reid/src/lib.rs +++ b/reid/src/lib.rs @@ -45,6 +45,7 @@ use std::path::PathBuf; use mir::{ linker::LinkerPass, typecheck::TypeCheck, typeinference::TypeInference, typerefs::TypeRefs, + SourceModuleId, }; use reid_lib::{compile::CompileOutput, Context}; @@ -75,6 +76,7 @@ pub enum ReidError { pub fn compile_module( source: &str, name: String, + module_id: SourceModuleId, path: Option, is_main: bool, ) -> Result { @@ -99,7 +101,7 @@ pub fn compile_module( is_main, }; - Ok(ast_module.process()) + Ok(ast_module.process(module_id)) } pub fn perform_all_passes(context: &mut mir::Context) -> Result<(), ReidError> { @@ -159,6 +161,7 @@ pub fn compile(source: &str, path: PathBuf) -> Result vec![compile_module( source, path.file_name().unwrap().to_str().unwrap().to_owned(), + SourceModuleId::default(), Some(path.clone()), true, )?], diff --git a/reid/src/mir/display.rs b/reid/src/mir/display.rs index 4a36ec0..4b34f16 100644 --- a/reid/src/mir/display.rs +++ b/reid/src/mir/display.rs @@ -289,7 +289,13 @@ impl Display for CmpOperator { impl Display for Metadata { fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { - write!(f, "{:?}", self.range) + write!(f, "{:?} ({})", self.range, self.source_module_id) + } +} + +impl Display for SourceModuleId { + fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result { + write!(f, "Mod {}", self.0) } } diff --git a/reid/src/mir/impl.rs b/reid/src/mir/impl.rs index 6969043..e175b68 100644 --- a/reid/src/mir/impl.rs +++ b/reid/src/mir/impl.rs @@ -1,4 +1,8 @@ -use super::{typecheck::ErrorKind, typerefs::TypeRefs, VagueType as Vague, *}; +use super::{ + typecheck::ErrorKind, + typerefs::{ScopeTypeRefs, TypeRef, TypeRefs}, + VagueType as Vague, *, +}; #[derive(Debug, Clone)] pub enum ReturnTypeOther { diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index f336f47..82fc776 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -12,7 +12,7 @@ use crate::{compile_module, ReidError}; use super::{ pass::{Pass, PassState}, r#impl::EqualsIssue, - Context, FunctionDefinition, Import, Metadata, Module, + Context, FunctionDefinition, Import, Metadata, Module, SourceModuleId, }; pub static STD_SOURCE: &str = include_str!("../../lib/std.reid"); @@ -41,8 +41,15 @@ pub enum ErrorKind { FunctionIsPrivate(String, String), } -pub fn compile_std() -> super::Module { - let module = compile_module(STD_SOURCE, "standard_library".to_owned(), None, false).unwrap(); +pub fn compile_std(module_id: SourceModuleId) -> super::Module { + let module = compile_module( + STD_SOURCE, + "standard_library".to_owned(), + module_id, + None, + false, + ) + .unwrap(); let mut mir_context = super::Context::from(vec![module], Default::default()); @@ -85,7 +92,16 @@ impl Pass for LinkerPass { modules.insert(module.name.clone(), Rc::new(RefCell::new(module))); } - modules.insert("std".to_owned(), Rc::new(RefCell::new(compile_std()))); + let mut module_counter = modules + .values() + .map(|m| m.borrow().module_id) + .max() + .unwrap(); + + modules.insert( + "std".to_owned(), + Rc::new(RefCell::new(compile_std(module_counter.increment()))), + ); let mut modules_to_process: Vec>> = modules.values().cloned().collect(); @@ -117,7 +133,13 @@ impl Pass for LinkerPass { continue; }; - match compile_module(&source, module_name.clone(), Some(file_path), false) { + match compile_module( + &source, + module_name.clone(), + module_counter.increment(), + Some(file_path), + false, + ) { Ok(imported_module) => { if imported_module.is_main { state.ok::<_, Infallible>( diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 96a9da7..be9968a 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -14,24 +14,40 @@ pub mod typecheck; pub mod typeinference; pub mod typerefs; +#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Debug, Default, Hash)] +pub struct SourceModuleId(u32); + +impl SourceModuleId { + pub fn increment(&mut self) -> SourceModuleId { + self.0 += 1; + SourceModuleId(self.0) + } +} + #[derive(Debug, Default, Clone, Copy)] pub struct Metadata { pub range: TokenRange, + pub source_module_id: SourceModuleId, } impl std::ops::Add for Metadata { type Output = Metadata; fn add(self, rhs: Self) -> Self::Output { + assert!(self.source_module_id == rhs.source_module_id); Metadata { range: self.range + rhs.range, + source_module_id: self.source_module_id, } } } -impl From for Metadata { - fn from(value: TokenRange) -> Self { - Metadata { range: value } +impl TokenRange { + pub fn as_meta(self, module: SourceModuleId) -> Metadata { + Metadata { + range: self, + source_module_id: module, + } } } @@ -240,14 +256,14 @@ pub enum FunctionDefinitionKind { impl FunctionDefinition { fn block_meta(&self) -> Metadata { match &self.kind { - FunctionDefinitionKind::Local(block, _) => block.meta, + FunctionDefinitionKind::Local(block, _) => block.meta.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(), } } fn signature(&self) -> Metadata { match &self.kind { - FunctionDefinitionKind::Local(_, metadata) => *metadata, + FunctionDefinitionKind::Local(_, metadata) => metadata.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(), } } @@ -288,6 +304,7 @@ pub enum TypeDefinitionKind { #[derive(Debug)] pub struct Module { pub name: String, + pub module_id: SourceModuleId, pub imports: Vec, pub functions: Vec, pub typedefs: Vec, diff --git a/reid/tests/e2e.rs b/reid/tests/e2e.rs index 031d217..7cc5713 100644 --- a/reid/tests/e2e.rs +++ b/reid/tests/e2e.rs @@ -15,7 +15,13 @@ pub static STRINGS: &str = include_str!("../../reid_src/strings.reid"); #[test] fn array_compiles_well() { - let module = assert_err(compile_module(ARRAY, "array".to_owned(), None, true)); + let module = assert_err(compile_module( + ARRAY, + "array".to_owned(), + Default::default(), + None, + true, + )); assert_err(perform_all_passes(&mut mir::Context { modules: vec![module], @@ -28,6 +34,7 @@ fn fibonacci_compiles_well() { let module = assert_err(compile_module( FIBONACCI, "fibonacci".to_owned(), + Default::default(), None, true, )); @@ -43,6 +50,7 @@ fn hello_world_compiles_well() { let module = assert_err(compile_module( HELLO_WORLD, "hello_world".to_owned(), + Default::default(), None, true, )); @@ -55,7 +63,13 @@ fn hello_world_compiles_well() { #[test] fn mutable_compiles_well() { - let module = assert_err(compile_module(MUTABLE, "mutable".to_owned(), None, true)); + let module = assert_err(compile_module( + MUTABLE, + "mutable".to_owned(), + Default::default(), + None, + true, + )); assert_err(perform_all_passes(&mut mir::Context { modules: vec![module], @@ -65,7 +79,13 @@ fn mutable_compiles_well() { #[test] fn strings_compiles_well() { - let module = assert_err(compile_module(STRINGS, "strings".to_owned(), None, true)); + let module = assert_err(compile_module( + STRINGS, + "strings".to_owned(), + Default::default(), + None, + true, + )); assert_err(perform_all_passes(&mut mir::Context { modules: vec![module], diff --git a/reid/tests/stdlib.rs b/reid/tests/stdlib.rs index 95afc7a..1a2af28 100644 --- a/reid/tests/stdlib.rs +++ b/reid/tests/stdlib.rs @@ -8,12 +8,12 @@ mod util; #[test] fn compiles() { - let _ = compile_std(); + let _ = compile_std(Default::default()); } #[test] fn passes_all_passes() { - let mut std = compile_std(); + let mut std = compile_std(Default::default()); // Needed to pass linker-pass std.is_main = true;