Start adding generics-pass

This commit is contained in:
Sofia 2025-08-25 20:04:30 +03:00
parent 91fd0d4d5a
commit 6fbb26ba88
5 changed files with 171 additions and 6 deletions

View File

@ -5,8 +5,5 @@ fn test<T>(value: T) -> T {
}
fn main() -> u32 {
let value = 0b110;
let other = 0o17;
return value * other + 7 * -value;
return test<u32>(5);
}

View File

@ -8,7 +8,7 @@ use crate::{
ast::token_stream::{self, TokenRange},
codegen,
lexer::{self, Cursor, FullToken, Position},
mir::{self, macros, pass, typecheck, Metadata, SourceModuleId},
mir::{self, generics, macros, pass, typecheck, Metadata, SourceModuleId},
};
use crate::mir::typecheck::ErrorKind as TypecheckError;
@ -36,6 +36,8 @@ pub enum ErrorKind {
LinkerError(#[from] mir::pass::Error<mir::linker::ErrorKind>),
#[error("{}{}", label("(Macro) "), .0)]
MacroError(#[from] mir::pass::Error<macros::ErrorKind>),
#[error("{}{}", label("(Generics) "), .0)]
GenericsError(#[from] mir::pass::Error<generics::ErrorKind>),
#[error("{}{}", label("(Codegen) "), .0)]
CodegenError(#[from] codegen::ErrorKind),
}
@ -62,6 +64,7 @@ impl ErrorKind {
codegen::ErrorKind::Null => Default::default(),
},
ErrorKind::MacroError(error) => error.metadata,
ErrorKind::GenericsError(error) => error.metadata,
}
}
@ -74,6 +77,7 @@ impl ErrorKind {
ErrorKind::LinkerError(_) => "linker",
ErrorKind::MacroError(_) => "macro-pass",
ErrorKind::CodegenError(_) => "codegen",
ErrorKind::GenericsError(_) => "generics",
}
}
}

View File

@ -70,6 +70,7 @@ use reid_lib::{compile::CompileOutput, Context};
use crate::{
ast::TopLevelStatement,
mir::{
generics::GenericsPass,
macros::{form_macros, MacroModule, MacroPass},
SourceModuleId,
},
@ -177,6 +178,24 @@ pub fn perform_all_passes<'map>(
is_lib: true,
})?;
#[cfg(debug_assertions)]
log::trace!("{:-^100}", "LINKER OUTPUT");
#[cfg(debug_assertions)]
log::trace!("{:#}", &context);
#[cfg(debug_assertions)]
log::trace!("{:#?}", &state);
if !state.errors.is_empty() {
return Err(ReidError::from_kind(
state.errors.iter().map(|e| e.clone().into()).collect(),
module_map.clone(),
));
}
let state = context.pass(&mut GenericsPass {
function_map: HashMap::new(),
})?;
for module in &mut context.modules {
for intrinsic in form_intrinsics() {
module.1.functions.insert(0, intrinsic);
@ -184,7 +203,7 @@ pub fn perform_all_passes<'map>(
}
#[cfg(debug_assertions)]
log::trace!("{:-^100}", "LINKER OUTPUT");
log::trace!("{:-^100}", "GENERICS OUTPUT");
#[cfg(debug_assertions)]
log::trace!("{:#}", &context);
#[cfg(debug_assertions)]

144
reid/src/mir/generics.rs Normal file
View File

@ -0,0 +1,144 @@
use std::{collections::HashMap, path::PathBuf};
use crate::mir::{
self, FunctionCall, GlobalKind, GlobalValue, IfExpression, Literal, Module, SourceModuleId, TypeKind,
WhileStatement,
};
use super::pass::{Pass, PassResult, PassState};
#[derive(thiserror::Error, Debug, Clone, PartialEq, Eq, PartialOrd, Ord)]
pub enum ErrorKind {
#[error("Should never be encountered!")]
Null,
}
type Calls = Vec<Vec<TypeKind>>;
pub struct GenericsPass {
pub function_map: HashMap<SourceModuleId, HashMap<String, Vec<TypeKind>>>,
}
type GenericsPassState<'map, 'st, 'sc> = PassState<'st, 'sc, (), ErrorKind>;
impl Pass for GenericsPass {
type Data = ();
type TError = ErrorKind;
fn context(&mut self, context: &mut mir::Context, mut _state: PassState<Self::Data, Self::TError>) -> PassResult {
for module in &context.modules {
let mut calls = HashMap::new();
let mut assoc_calls = HashMap::new();
for function in &module.1.associated_functions {
match &function.1.kind {
mir::FunctionDefinitionKind::Local(block, _) => block.find_calls(&mut calls, &mut assoc_calls),
mir::FunctionDefinitionKind::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {}
}
}
for function in &module.1.functions {
match &function.kind {
mir::FunctionDefinitionKind::Local(block, _) => block.find_calls(&mut calls, &mut assoc_calls),
mir::FunctionDefinitionKind::Extern(_) => {}
mir::FunctionDefinitionKind::Intrinsic(_) => {}
}
}
dbg!(&calls);
dbg!(&assoc_calls);
}
Ok(())
}
fn module(&mut self, module: &mut mir::Module, mut state: PassState<Self::Data, Self::TError>) -> PassResult {
Ok(())
}
}
impl mir::Block {
fn find_calls(&self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
for statement in &self.statements {
statement.find_calls(calls, assoc_calls);
}
if let Some((_, Some(e))) = &self.return_expression {
e.find_calls(calls, assoc_calls);
}
}
}
impl mir::Statement {
fn find_calls(&self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
match &self.0 {
mir::StmtKind::Let(_, _, expression) => expression.find_calls(calls, assoc_calls),
mir::StmtKind::Set(expression, expression1) => {
expression.find_calls(calls, assoc_calls);
expression1.find_calls(calls, assoc_calls);
}
mir::StmtKind::Import(_) => {}
mir::StmtKind::Expression(expression) => expression.find_calls(calls, assoc_calls),
mir::StmtKind::While(WhileStatement { condition, block, .. }) => {
condition.find_calls(calls, assoc_calls);
block.find_calls(calls, assoc_calls);
}
}
}
}
impl mir::Expression {
fn find_calls(&self, calls: &mut HashMap<String, Calls>, assoc_calls: &mut HashMap<(TypeKind, String), Calls>) {
match &self.0 {
mir::ExprKind::Variable(_) => {}
mir::ExprKind::Indexed(expression, _, expression1) => {
expression.find_calls(calls, assoc_calls);
expression1.find_calls(calls, assoc_calls);
}
mir::ExprKind::Accessed(expression, _, _, _) => {
expression.find_calls(calls, assoc_calls);
}
mir::ExprKind::Array(expressions) => {
for expression in expressions {
expression.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Struct(_, items) => {
for item in items {
item.1.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Literal(_) => todo!(),
mir::ExprKind::BinOp(_, lhs, rhs, _) => {
lhs.find_calls(calls, assoc_calls);
rhs.find_calls(calls, assoc_calls);
}
mir::ExprKind::FunctionCall(function_call) => {
if let Some(calls) = calls.get_mut(&function_call.name) {
calls.push(function_call.generics.clone());
} else {
calls.insert(function_call.name.clone(), vec![function_call.generics.clone()]);
}
}
mir::ExprKind::AssociatedFunctionCall(ty, function_call) => {
if let Some(calls) = assoc_calls.get_mut(&(ty.clone(), function_call.name.clone())) {
calls.push(function_call.generics.clone());
} else {
assoc_calls.insert(
(ty.clone(), function_call.name.clone()),
vec![function_call.generics.clone()],
);
}
}
mir::ExprKind::If(IfExpression(cond, then_e, else_e)) => {
cond.find_calls(calls, assoc_calls);
then_e.find_calls(calls, assoc_calls);
if let Some(else_e) = else_e.as_ref() {
else_e.find_calls(calls, assoc_calls);
}
}
mir::ExprKind::Block(block) => block.find_calls(calls, assoc_calls),
mir::ExprKind::Borrow(expression, _) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::Deref(expression) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::CastTo(expression, _) => expression.find_calls(calls, assoc_calls),
mir::ExprKind::GlobalRef(_, _) => {}
}
}
}

View File

@ -11,6 +11,7 @@ use crate::{
};
mod fmt;
pub mod generics;
pub mod implement;
pub mod linker;
pub mod macros;