Load file contents relative to module path instead of PWD

This commit is contained in:
Sofia 2025-07-29 15:44:14 +03:00
parent 8b1d1084a6
commit baa068a371
4 changed files with 73 additions and 39 deletions

View File

@ -2,10 +2,7 @@ import std::String;
import std::print; import std::print;
fn main() -> u8 { fn main() -> u8 {
// - TODO make a type of global identifier for globls? let bytes = test_macro!("./macro_easy_file.txt");
// - TODO figure out if it is possible to map the path to the path of the
// module and not the PWD.
let bytes = test_macro!("./examples/macro_easy_file.txt");
print(String::new() + bytes.length()); print(String::new() + bytes.length());
return *bytes[0]; return *bytes[0];
} }

View File

@ -82,7 +82,7 @@ pub struct ErrorModule {
#[derive(Debug, Clone, PartialEq, Eq, Default)] #[derive(Debug, Clone, PartialEq, Eq, Default)]
pub struct ErrorModules { pub struct ErrorModules {
module_map: HashMap<mir::SourceModuleId, ErrorModule>, pub(super) module_map: HashMap<mir::SourceModuleId, ErrorModule>,
module_counter: mir::SourceModuleId, module_counter: mir::SourceModuleId,
} }

View File

@ -41,7 +41,7 @@
//! - Debug Symbols //! - Debug Symbols
//! ``` //! ```
use std::{path::PathBuf, thread, time::Duration}; use std::{collections::HashMap, path::PathBuf, thread, time::Duration};
use ast::{ use ast::{
lexer::{self, FullToken, Token}, lexer::{self, FullToken, Token},
@ -58,7 +58,7 @@ use reid_lib::{compile::CompileOutput, Context};
use crate::{ use crate::{
ast::TopLevelStatement, ast::TopLevelStatement,
mir::macros::{form_macros, MacroPass}, mir::macros::{form_macros, MacroModule, MacroPass},
}; };
mod ast; mod ast;
@ -156,7 +156,16 @@ pub fn perform_all_passes<'map>(
)); ));
} }
let state = context.pass(&mut MacroPass { macros: form_macros() })?; let mut macro_modules: HashMap<_, MacroModule> = HashMap::new();
for (k, v) in &context.modules {
macro_modules.insert(k.clone(), v.into());
}
let mut macro_pass = MacroPass {
macros: form_macros(),
module_map: macro_modules,
};
let state = context.pass(&mut macro_pass)?;
#[cfg(debug_assertions)] #[cfg(debug_assertions)]
println!("{:-^100}", "MACRO OUTPUT"); println!("{:-^100}", "MACRO OUTPUT");

View File

@ -1,12 +1,16 @@
use std::{cell::RefCell, collections::HashMap, rc::Rc}; use std::{collections::HashMap, path::PathBuf};
use crate::mir::{self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, TypeKind, WhileStatement}; use crate::mir::{
self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, Module, SourceModuleId, TypeKind,
WhileStatement,
};
use super::pass::{Pass, PassResult, PassState}; use super::pass::{Pass, PassResult, PassState};
pub trait MacroFunction: std::fmt::Debug { pub trait MacroFunction: std::fmt::Debug {
fn generate<'ctx, 'a>( fn generate<'ctx, 'a>(
&self, &self,
module: &MacroModule,
params: &[mir::Literal], params: &[mir::Literal],
prefix: String, prefix: String,
) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind>; ) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind>;
@ -28,15 +32,28 @@ pub enum ErrorKind {
MacroExecutionError(String), MacroExecutionError(String),
} }
type MacroModuleMap = HashMap<SourceModuleId, MacroModule>;
/// 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 MacroPass { pub struct MacroPass {
pub(crate) macros: HashMap<String, Box<dyn MacroFunction>>, pub(crate) macros: HashMap<String, Box<dyn MacroFunction>>,
pub module_map: MacroModuleMap,
} }
pub struct MacroData {} pub struct MacroModule {
path: Option<PathBuf>,
}
type MacroPassState<'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>; impl From<&Module> for MacroModule {
fn from(value: &Module) -> Self {
MacroModule {
path: value.path.clone(),
}
}
}
type MacroPassState<'map, 'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>;
impl Pass for MacroPass { impl Pass for MacroPass {
type Data = (); type Data = ();
@ -49,7 +66,7 @@ impl Pass for MacroPass {
fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult { fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
for function in &mut module.functions { for function in &mut module.functions {
let globals = match &mut function.kind { let globals = match &mut function.kind {
mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state), mir::FunctionDefinitionKind::Local(block, _) => block.gen_macros(self, &mut state, &self.module_map),
_ => Vec::new(), _ => Vec::new(),
}; };
@ -60,36 +77,36 @@ impl Pass for MacroPass {
} }
impl mir::Block { impl mir::Block {
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState, map: &MacroModuleMap) -> Vec<GlobalValue> {
let mut globals = Vec::new(); let mut globals = Vec::new();
for statement in &mut self.statements { for statement in &mut self.statements {
globals.extend(statement.gen_macros(data, state)); globals.extend(statement.gen_macros(data, state, map));
} }
if let Some((_, Some(return_expr))) = &mut self.return_expression { if let Some((_, Some(return_expr))) = &mut self.return_expression {
globals.extend(return_expr.gen_macros(data, state)); globals.extend(return_expr.gen_macros(data, state, map));
} }
globals globals
} }
} }
impl mir::Statement { impl mir::Statement {
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState, map: &MacroModuleMap) -> Vec<GlobalValue> {
let mut globals = Vec::new(); let mut globals = Vec::new();
match &mut self.0 { match &mut self.0 {
mir::StmtKind::Let(.., expr) => { mir::StmtKind::Let(.., expr) => {
globals.extend(expr.gen_macros(data, state)); globals.extend(expr.gen_macros(data, state, map));
} }
mir::StmtKind::Set(lhs, rhs) => { mir::StmtKind::Set(lhs, rhs) => {
globals.extend(lhs.gen_macros(data, state)); globals.extend(lhs.gen_macros(data, state, map));
globals.extend(rhs.gen_macros(data, state)); globals.extend(rhs.gen_macros(data, state, map));
} }
mir::StmtKind::Import(_) => {} mir::StmtKind::Import(_) => {}
mir::StmtKind::Expression(expr) => { mir::StmtKind::Expression(expr) => {
globals.extend(expr.gen_macros(data, state)); globals.extend(expr.gen_macros(data, state, map));
} }
mir::StmtKind::While(WhileStatement { condition, block, .. }) => { mir::StmtKind::While(WhileStatement { condition, block, .. }) => {
globals.extend(condition.gen_macros(data, state)); globals.extend(condition.gen_macros(data, state, map));
globals.extend(block.gen_macros(data, state)); globals.extend(block.gen_macros(data, state, map));
} }
}; };
globals globals
@ -97,7 +114,7 @@ impl mir::Statement {
} }
impl mir::Expression { impl mir::Expression {
fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState) -> Vec<GlobalValue> { fn gen_macros(&mut self, data: &MacroPass, state: &mut MacroPassState, map: &MacroModuleMap) -> Vec<GlobalValue> {
let mut globals = Vec::new(); let mut globals = Vec::new();
match &mut self.0 { match &mut self.0 {
mir::ExprKind::FunctionCall(function_call) => { mir::ExprKind::FunctionCall(function_call) => {
@ -113,6 +130,7 @@ impl mir::Expression {
let (generated_globals, expr) = state.or_else( let (generated_globals, expr) = state.or_else(
existing_macro existing_macro
.generate( .generate(
map.get(&state.scope.module_id.unwrap()).unwrap(),
&literals, &literals,
format!( format!(
"macro.{}.{}.{}", "macro.{}.{}.{}",
@ -135,26 +153,26 @@ impl mir::Expression {
} }
mir::ExprKind::Variable(_) => {} mir::ExprKind::Variable(_) => {}
mir::ExprKind::Indexed(expression, _, expression1) => { mir::ExprKind::Indexed(expression, _, expression1) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
globals.extend(expression1.gen_macros(data, state)); globals.extend(expression1.gen_macros(data, state, map));
} }
mir::ExprKind::Accessed(expression, ..) => { mir::ExprKind::Accessed(expression, ..) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
mir::ExprKind::Array(expressions) => { mir::ExprKind::Array(expressions) => {
for expression in expressions { for expression in expressions {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
} }
mir::ExprKind::Struct(_, items) => { mir::ExprKind::Struct(_, items) => {
for item in items { for item in items {
globals.extend(item.1.gen_macros(data, state)); globals.extend(item.1.gen_macros(data, state, map));
} }
} }
mir::ExprKind::Literal(_) => {} mir::ExprKind::Literal(_) => {}
mir::ExprKind::BinOp(_, expression, expression1, _) => { mir::ExprKind::BinOp(_, expression, expression1, _) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
globals.extend(expression1.gen_macros(data, state)); globals.extend(expression1.gen_macros(data, state, map));
} }
mir::ExprKind::AssociatedFunctionCall( mir::ExprKind::AssociatedFunctionCall(
_, _,
@ -163,27 +181,27 @@ impl mir::Expression {
}, },
) => { ) => {
for expression in parameters { for expression in parameters {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
} }
mir::ExprKind::If(IfExpression(cond, lhs, rhs)) => { mir::ExprKind::If(IfExpression(cond, lhs, rhs)) => {
globals.extend(cond.gen_macros(data, state)); globals.extend(cond.gen_macros(data, state, map));
globals.extend(lhs.gen_macros(data, state)); globals.extend(lhs.gen_macros(data, state, map));
if let Some(rhs) = rhs.as_mut() { if let Some(rhs) = rhs.as_mut() {
globals.extend(rhs.gen_macros(data, state)); globals.extend(rhs.gen_macros(data, state, map));
} }
} }
mir::ExprKind::Block(block) => { mir::ExprKind::Block(block) => {
globals.extend(block.gen_macros(data, state)); globals.extend(block.gen_macros(data, state, map));
} }
mir::ExprKind::Borrow(expression, _) => { mir::ExprKind::Borrow(expression, _) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
mir::ExprKind::Deref(expression) => { mir::ExprKind::Deref(expression) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
mir::ExprKind::CastTo(expression, _) => { mir::ExprKind::CastTo(expression, _) => {
globals.extend(expression.gen_macros(data, state)); globals.extend(expression.gen_macros(data, state, map));
} }
mir::ExprKind::GlobalRef(..) => {} mir::ExprKind::GlobalRef(..) => {}
} }
@ -204,6 +222,7 @@ pub struct TestMacro;
impl MacroFunction for TestMacro { impl MacroFunction for TestMacro {
fn generate<'ctx, 'a>( fn generate<'ctx, 'a>(
&self, &self,
module: &MacroModule,
literals: &[mir::Literal], literals: &[mir::Literal],
global_name: String, global_name: String,
) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind> { ) -> Result<(Vec<GlobalValue>, mir::ExprKind), ErrorKind> {
@ -218,6 +237,15 @@ impl MacroFunction for TestMacro {
)); ));
}; };
let path = module
.path
.as_ref()
.expect("Module has no path!")
.parent()
.expect("Module path has no parent!")
.join(path);
dbg!(&path);
let contents = match std::fs::read(path) { let contents = match std::fs::read(path) {
Ok(content) => content, Ok(content) => content,
Err(e) => return Err(ErrorKind::MacroExecutionError(format!("{}", e))), Err(e) => return Err(ErrorKind::MacroExecutionError(format!("{}", e))),