Add module_id for modules and metadata

This commit is contained in:
Sofia 2025-07-17 14:56:41 +03:00
parent e2dc1a3f85
commit 64e34ecf13
10 changed files with 135 additions and 48 deletions

View File

@ -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(),

View File

@ -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<ast::ReturnType> 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))
}
}

View File

View File

@ -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<PathBuf>,
is_main: bool,
) -> Result<mir::Module, ReidError> {
@ -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<CompileOutput, ReidError>
vec![compile_module(
source,
path.file_name().unwrap().to_str().unwrap().to_owned(),
SourceModuleId::default(),
Some(path.clone()),
true,
)?],

View File

@ -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)
}
}

View File

@ -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 {

View File

@ -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<Rc<RefCell<Module>>> = 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>(

View File

@ -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<TokenRange> 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<Import>,
pub functions: Vec<FunctionDefinition>,
pub typedefs: Vec<TypeDefinition>,

View File

@ -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],

View File

@ -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;