From 2e153922f1dfd31c065a4f52ee3858429eb4e1d8 Mon Sep 17 00:00:00 2001 From: sofia Date: Mon, 28 Jul 2025 21:54:51 +0300 Subject: [PATCH] Start adding macros --- reid/src/codegen/allocator.rs | 1 + reid/src/codegen/intrinsics.rs | 6 +++++- reid/src/codegen/mod.rs | 25 +++++++++++++++++++++++-- reid/src/codegen/scope.rs | 16 +++++++++++++++- reid/src/mir/fmt.rs | 1 + reid/src/mir/implement.rs | 1 + reid/src/mir/linker.rs | 1 + reid/src/mir/mod.rs | 7 ++++++- reid/src/mir/pass.rs | 5 +++++ reid/src/mir/typecheck/mod.rs | 2 ++ reid/src/mir/typecheck/typecheck.rs | 13 ++++++++++++- reid/src/mir/typecheck/typeinference.rs | 4 ++++ 12 files changed, 76 insertions(+), 6 deletions(-) diff --git a/reid/src/codegen/allocator.rs b/reid/src/codegen/allocator.rs index 44aa43b..10f274f 100644 --- a/reid/src/codegen/allocator.rs +++ b/reid/src/codegen/allocator.rs @@ -61,6 +61,7 @@ impl mir::FunctionDefinitionKind { } mir::FunctionDefinitionKind::Extern(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {} + mir::FunctionDefinitionKind::Macro(_) => {} } Allocator { allocations: allocated } diff --git a/reid/src/codegen/intrinsics.rs b/reid/src/codegen/intrinsics.rs index cb1cac3..12f4ced 100644 --- a/reid/src/codegen/intrinsics.rs +++ b/reid/src/codegen/intrinsics.rs @@ -3,7 +3,7 @@ use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type} use crate::{ codegen::{ErrorKind, StackValueKind}, mir::{ - BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, FunctionParam, + self, BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, FunctionParam, TypeKind, }, }; @@ -309,6 +309,10 @@ pub trait IntrinsicFunction: std::fmt::Debug { fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[StackValue]) -> Result; } +pub trait MacroFunction: std::fmt::Debug { + fn codegen<'ctx, 'a>(&self, scope: &mut Scope<'ctx, 'a>, params: &[mir::Literal]) -> Result; +} + macro_rules! intrinsic_debug { ($kind:ty, $name:literal) => { impl std::fmt::Debug for $kind diff --git a/reid/src/codegen/mod.rs b/reid/src/codegen/mod.rs index a6257a1..e92fb8f 100644 --- a/reid/src/codegen/mod.rs +++ b/reid/src/codegen/mod.rs @@ -237,6 +237,7 @@ impl mir::Module { }, )), mir::FunctionDefinitionKind::Intrinsic(_) => None, + mir::FunctionDefinitionKind::Macro(_) => None, }; if let Some(func) = func { @@ -288,6 +289,7 @@ impl mir::Module { }, )), mir::FunctionDefinitionKind::Intrinsic(_) => None, + mir::FunctionDefinitionKind::Macro(_) => None, }; if let Some(func) = func { @@ -374,6 +376,7 @@ impl mir::Module { } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, + FunctionDefinitionKind::Macro(_) => None, }, ) .unwrap(); @@ -394,6 +397,7 @@ impl mir::Module { FunctionDefinitionKind::Intrinsic(intrinsic_function) => { ScopeFunctionKind::Intrinsic(intrinsic_function) } + FunctionDefinitionKind::Macro(macro_function) => ScopeFunctionKind::Macro(macro_function), }, }, ); @@ -450,6 +454,7 @@ impl mir::Module { } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, + FunctionDefinitionKind::Macro(macro_function) => None, }, ) .unwrap(); @@ -510,6 +515,7 @@ impl mir::Module { } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, + FunctionDefinitionKind::Macro(_) => None, }, ) .unwrap(); @@ -616,6 +622,7 @@ impl FunctionDefinitionKind { } mir::FunctionDefinitionKind::Extern(_) => {} mir::FunctionDefinitionKind::Intrinsic(_) => {} + FunctionDefinitionKind::Macro(_) => {} }; Ok(()) } @@ -1379,7 +1386,14 @@ fn codegen_function_call<'ctx, 'a>( .or(intrinsic.as_ref()) .expect(&format!("Function {} does not exist!", call_name)); callee - .codegen(&call_name, params.as_slice(), &call.return_type, location, scope) + .codegen( + &call_name, + params.as_slice(), + &call.parameters, + &call.return_type, + location, + scope, + ) .unwrap() } else { let callee = scope @@ -1388,7 +1402,14 @@ fn codegen_function_call<'ctx, 'a>( .expect(&format!("Function {} does not exist!", call_name)); callee - .codegen(&call_name, params.as_slice(), &call.return_type, location, scope) + .codegen( + &call_name, + params.as_slice(), + &call.parameters, + &call.return_type, + location, + scope, + ) .unwrap() }; diff --git a/reid/src/codegen/scope.rs b/reid/src/codegen/scope.rs index 19f20b5..842fdae 100644 --- a/reid/src/codegen/scope.rs +++ b/reid/src/codegen/scope.rs @@ -7,8 +7,10 @@ use reid_lib::{ }; use crate::{ + codegen::intrinsics::MacroFunction, lexer::FullToken, mir::{ + self, pass::{AssociatedFunctionKey, BinopKey}, CustomTypeKey, FunctionParam, Metadata, SourceModuleId, TypeDefinition, TypeKind, }, @@ -138,6 +140,7 @@ pub enum ScopeFunctionKind<'ctx> { UserGenerated(Function<'ctx>), Intrinsic(&'ctx Box), IntrinsicOwned(Box), + Macro(&'ctx Box), } impl<'ctx> StackBinopDefinition<'ctx> { @@ -156,7 +159,7 @@ impl<'ctx> StackBinopDefinition<'ctx> { "binop.{}.{}.{}.call", self.parameters.0.ty, self.parameters.1.ty, self.return_ty ); - self.kind.codegen(&name, &[lhs, rhs], &self.return_ty, None, scope) + self.kind.codegen(&name, &[lhs, rhs], &[], &self.return_ty, None, scope) } } @@ -165,6 +168,7 @@ impl<'ctx> ScopeFunctionKind<'ctx> { &self, name: &str, params: &[StackValue], + param_exprs: &[mir::Expression], return_ty: &TypeKind, location: Option, scope: &mut Scope<'ctx, 'a>, @@ -189,6 +193,16 @@ impl<'ctx> ScopeFunctionKind<'ctx> { } ScopeFunctionKind::Intrinsic(fun) => fun.codegen(scope, params), ScopeFunctionKind::IntrinsicOwned(fun) => fun.codegen(scope, params), + ScopeFunctionKind::Macro(fun) => fun.codegen( + scope, + ¶m_exprs + .iter() + .map(|e| match &e.0 { + crate::mir::ExprKind::Literal(lit) => lit.clone(), + _ => panic!(), + }) + .collect::>(), + ), } } } diff --git a/reid/src/mir/fmt.rs b/reid/src/mir/fmt.rs index 90c0c36..51650a9 100644 --- a/reid/src/mir/fmt.rs +++ b/reid/src/mir/fmt.rs @@ -151,6 +151,7 @@ impl Display for FunctionDefinitionKind { FunctionDefinitionKind::Extern(true) => write!(f, ""), FunctionDefinitionKind::Extern(false) => write!(f, ""), FunctionDefinitionKind::Intrinsic(_) => write!(f, ""), + FunctionDefinitionKind::Macro(_) => write!(f, ""), } } } diff --git a/reid/src/mir/implement.rs b/reid/src/mir/implement.rs index bcf2b65..3615df0 100644 --- a/reid/src/mir/implement.rs +++ b/reid/src/mir/implement.rs @@ -615,6 +615,7 @@ impl FunctionDefinition { } } FunctionDefinitionKind::Intrinsic(_) => Err(EqualsIssue::ExistsAsIntrinsic), + FunctionDefinitionKind::Macro(_) => Err(EqualsIssue::ExistsAsIntrinsic), } } } diff --git a/reid/src/mir/linker.rs b/reid/src/mir/linker.rs index 8016110..1059861 100644 --- a/reid/src/mir/linker.rs +++ b/reid/src/mir/linker.rs @@ -269,6 +269,7 @@ impl<'map> Pass for LinkerPass<'map> { } FunctionDefinitionKind::Extern(_) => {} FunctionDefinitionKind::Intrinsic(_) => {} + FunctionDefinitionKind::Macro(_) => {} } } diff --git a/reid/src/mir/mod.rs b/reid/src/mir/mod.rs index 7867a15..38d99d9 100644 --- a/reid/src/mir/mod.rs +++ b/reid/src/mir/mod.rs @@ -6,7 +6,7 @@ use std::{collections::HashMap, path::PathBuf}; use crate::{ ast::token_stream::TokenRange, - codegen::intrinsics::IntrinsicFunction, + codegen::intrinsics::{IntrinsicFunction, MacroFunction}, lexer::{FullToken, Position}, }; @@ -322,6 +322,8 @@ pub enum FunctionDefinitionKind { Extern(bool), /// Intrinsic definition, defined within the compiler Intrinsic(Box), + /// Macro function, executed entirely on the compiler + Macro(Box), } impl FunctionDefinition { @@ -330,6 +332,7 @@ impl FunctionDefinition { FunctionDefinitionKind::Local(block, _) => block.meta.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(), FunctionDefinitionKind::Intrinsic(_) => Metadata::default(), + FunctionDefinitionKind::Macro(_) => Metadata::default(), } } @@ -338,6 +341,7 @@ impl FunctionDefinition { FunctionDefinitionKind::Local(_, metadata) => metadata.clone(), FunctionDefinitionKind::Extern(_) => Metadata::default(), FunctionDefinitionKind::Intrinsic(_) => Metadata::default(), + FunctionDefinitionKind::Macro(_) => Metadata::default(), } } } @@ -402,6 +406,7 @@ impl BinopDefinition { FunctionDefinitionKind::Local(block, _) => Some(block.meta), FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, + FunctionDefinitionKind::Macro(_) => None, } } diff --git a/reid/src/mir/pass.rs b/reid/src/mir/pass.rs index d272f58..4cf17f0 100644 --- a/reid/src/mir/pass.rs +++ b/reid/src/mir/pass.rs @@ -188,6 +188,7 @@ impl Scope { ScopeFunction { ret: func.return_type, params: func.parameters.iter().map(|p| p.ty.clone()).collect(), + is_macro: matches!(func.kind, FunctionDefinitionKind::Macro(_)), }, ) .unwrap(); @@ -202,6 +203,7 @@ impl Scope { pub struct ScopeFunction { pub ret: TypeKind, pub params: Vec, + pub is_macro: bool, } #[derive(Clone, Debug)] @@ -427,6 +429,7 @@ impl Module { ScopeFunction { ret: function.return_type.clone(), params: function.parameters.iter().cloned().map(|v| v.ty).collect(), + is_macro: matches!(function.kind, FunctionDefinitionKind::Macro(_)), }, ) .ok(); @@ -440,6 +443,7 @@ impl Module { ScopeFunction { ret: function.return_type.clone(), params: function.parameters.iter().cloned().map(|v| v.ty).collect(), + is_macro: matches!(function.kind, FunctionDefinitionKind::Macro(_)), }, ) .ok(); @@ -484,6 +488,7 @@ impl FunctionDefinition { } FunctionDefinitionKind::Extern(_) => {} FunctionDefinitionKind::Intrinsic(..) => {} + FunctionDefinitionKind::Macro(_) => {} }; Ok(()) } diff --git a/reid/src/mir/typecheck/mod.rs b/reid/src/mir/typecheck/mod.rs index c2a8390..37c0693 100644 --- a/reid/src/mir/typecheck/mod.rs +++ b/reid/src/mir/typecheck/mod.rs @@ -88,6 +88,8 @@ pub enum ErrorKind { InvalidBinop(BinaryOperator, TypeKind, TypeKind), #[error("Could not infer type for {0:?}. Try adding type annotations.")] CouldNotInferType(String), + #[error("Arguments for a macro-function may only contain literals")] + MacroMustBeLiterals, } #[derive(Clone, Debug, PartialEq, Eq)] diff --git a/reid/src/mir/typecheck/typecheck.rs b/reid/src/mir/typecheck/typecheck.rs index 4e44fae..4525e4c 100644 --- a/reid/src/mir/typecheck/typecheck.rs +++ b/reid/src/mir/typecheck/typecheck.rs @@ -193,7 +193,8 @@ impl FunctionDefinitionKind { block.typecheck(&mut state.inner(), &typerefs, hint.into()) } FunctionDefinitionKind::Extern(_) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), - FunctionDefinitionKind::Intrinsic(..) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), + FunctionDefinitionKind::Intrinsic(intrinsic) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), + FunctionDefinitionKind::Macro(_) => Ok((ReturnKind::Soft, TypeKind::Vague(Vague::Unknown))), } } } @@ -471,6 +472,16 @@ impl Expression { ); } + if f.is_macro { + for param in &function_call.parameters { + match ¶m.0 { + ExprKind::Literal(_) => {} + _ => return Err(ErrorKind::Null), + } + } + return Ok(function_call.return_type.clone()); + } + let true_params_iter = f .params .into_iter() diff --git a/reid/src/mir/typecheck/typeinference.rs b/reid/src/mir/typecheck/typeinference.rs index 4bb0264..df3501a 100644 --- a/reid/src/mir/typecheck/typeinference.rs +++ b/reid/src/mir/typecheck/typeinference.rs @@ -56,6 +56,7 @@ impl<'t> Pass for TypeInference<'t> { FunctionDefinitionKind::Local(..) => ErrorTypedefKind::Local, FunctionDefinitionKind::Extern(..) => ErrorTypedefKind::Extern, FunctionDefinitionKind::Intrinsic(..) => ErrorTypedefKind::Intrinsic, + FunctionDefinitionKind::Macro(..) => ErrorTypedefKind::Intrinsic, }, ); } @@ -79,6 +80,7 @@ impl<'t> Pass for TypeInference<'t> { FunctionDefinitionKind::Local(..) => ErrorTypedefKind::Local, FunctionDefinitionKind::Extern(..) => ErrorTypedefKind::Extern, FunctionDefinitionKind::Intrinsic(..) => ErrorTypedefKind::Intrinsic, + FunctionDefinitionKind::Macro(..) => ErrorTypedefKind::Intrinsic, }, ); } @@ -191,6 +193,7 @@ impl FunctionDefinition { } FunctionDefinitionKind::Extern(_) => {} FunctionDefinitionKind::Intrinsic(_) => {} + FunctionDefinitionKind::Macro(_) => {} }; let return_ty = self .kind @@ -223,6 +226,7 @@ impl FunctionDefinitionKind { } FunctionDefinitionKind::Extern(_) => None, FunctionDefinitionKind::Intrinsic(_) => None, + FunctionDefinitionKind::Macro(_) => todo!(), }) } }