From 140d963d9b31425da5783083379517c83192ef62 Mon Sep 17 00:00:00 2001 From: sofia Date: Tue, 29 Jul 2025 00:18:50 +0300 Subject: [PATCH] Read file contents to binary within macro --- examples/macro_easy.reid | 4 ++-- reid/src/mir/macros.rs | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 32 insertions(+), 5 deletions(-) diff --git a/examples/macro_easy.reid b/examples/macro_easy.reid index 666e7e1..f82b105 100644 --- a/examples/macro_easy.reid +++ b/examples/macro_easy.reid @@ -1,4 +1,4 @@ -fn main() -> u32 { +fn main() -> u8 { // let message = String::from(include_bytes!("./macro_easy_file.txt")); - return test_macro!(); + return test_macro!("./examples/macro_easy_file.txt"); } diff --git a/reid/src/mir/macros.rs b/reid/src/mir/macros.rs index 4967dfc..e8a2189 100644 --- a/reid/src/mir/macros.rs +++ b/reid/src/mir/macros.rs @@ -1,6 +1,6 @@ use std::collections::HashMap; -use crate::mir::{self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, WhileStatement}; +use crate::mir::{self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, TypeKind, WhileStatement}; use super::pass::{Pass, PassResult, PassState}; @@ -16,6 +16,12 @@ pub enum ErrorKind { NoSuchMacro(String), #[error("Macro arguments may only be literals")] InvalidMacroArgs, + #[error("Got {0} parameters, expected {1}")] + InvalidAmountOfParams(u32, u32), + #[error("Expected argument type of {0}, got {1}")] + InvalidArgumentType(TypeKind, TypeKind), + #[error("Error executing macro: {0}")] + MacroExecutionError(String), } /// Struct used to implement a type-checking pass that can be performed on the @@ -183,11 +189,32 @@ pub fn form_macros() -> HashMap> { #[derive(Debug)] pub struct TestMacro; impl MacroFunction for TestMacro { - fn generate<'ctx, 'a>(&self, _: &[mir::Literal]) -> Result<(Vec, mir::ExprKind), ErrorKind> { + fn generate<'ctx, 'a>(&self, literals: &[mir::Literal]) -> Result<(Vec, mir::ExprKind), ErrorKind> { + if literals.len() != 1 { + return Err(ErrorKind::InvalidAmountOfParams(literals.len() as u32, 1)); + } + let literal = literals.get(0).unwrap(); + let Literal::String(path) = literal else { + return Err(ErrorKind::InvalidArgumentType( + literal.as_type(), + TypeKind::UserPtr(Box::new(TypeKind::Char)), + )); + }; + + let contents = match std::fs::read(path) { + Ok(content) => content, + Err(e) => return Err(ErrorKind::MacroExecutionError(format!("{}", e))), + }; + + let literals = contents + .iter() + .map(|c| GlobalKind::Literal(Literal::U8(*c))) + .collect::>(); + Ok(( vec![GlobalValue { name: "sometestglobalvalue".to_owned(), - kind: GlobalKind::Array(vec![GlobalKind::Literal(Literal::I16(12))]), + kind: GlobalKind::Array(literals), }], mir::ExprKind::Literal(mir::Literal::Vague(mir::VagueLiteral::Number(5))), ))