Start adding generics-pass
This commit is contained in:
parent
91fd0d4d5a
commit
6fbb26ba88
@ -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);
|
||||
}
|
@ -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",
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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
144
reid/src/mir/generics.rs
Normal 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(_, _) => {}
|
||||
}
|
||||
}
|
||||
}
|
@ -11,6 +11,7 @@ use crate::{
|
||||
};
|
||||
|
||||
mod fmt;
|
||||
pub mod generics;
|
||||
pub mod implement;
|
||||
pub mod linker;
|
||||
pub mod macros;
|
||||
|
Loading…
Reference in New Issue
Block a user