Use metadata instead of names for allocator identification

This commit is contained in:
Sofia 2025-07-28 19:22:03 +03:00
parent e412a2e1d7
commit b643c13582
14 changed files with 186 additions and 127 deletions

View File

@ -196,9 +196,9 @@ pub struct FunctionSignature {
#[derive(Debug, Clone)] #[derive(Debug, Clone)]
pub enum SelfKind { pub enum SelfKind {
Owned(TypeKind), Owned(Type),
Borrow(TypeKind), Borrow(Type),
MutBorrow(TypeKind), MutBorrow(Type),
None, None,
} }

View File

@ -696,9 +696,18 @@ impl Parse for SelfParam {
}; };
if name == "self" { if name == "self" {
match kind { match kind {
SelfParamKind::BorrowMut => Ok(SelfParam(SelfKind::MutBorrow(TypeKind::Unknown))), SelfParamKind::BorrowMut => Ok(SelfParam(SelfKind::MutBorrow(Type(
SelfParamKind::Borrow => Ok(SelfParam(SelfKind::Borrow(TypeKind::Unknown))), TypeKind::Unknown,
SelfParamKind::Owned => Ok(SelfParam(SelfKind::Owned(TypeKind::Unknown))), stream.get_range_prev().unwrap(),
)))),
SelfParamKind::Borrow => Ok(SelfParam(SelfKind::Borrow(Type(
TypeKind::Unknown,
stream.get_range_prev().unwrap(),
)))),
SelfParamKind::Owned => Ok(SelfParam(SelfKind::Owned(Type(
TypeKind::Unknown,
stream.get_range_prev().unwrap(),
)))),
} }
} else { } else {
Err(stream.expected_err("self parameter")?) Err(stream.expected_err("self parameter")?)
@ -1091,9 +1100,9 @@ impl Parse for AssociatedFunctionBlock {
Some(Token::FnKeyword) | Some(Token::PubKeyword) => { Some(Token::FnKeyword) | Some(Token::PubKeyword) => {
let mut fun: FunctionDefinition = stream.parse()?; let mut fun: FunctionDefinition = stream.parse()?;
fun.0.self_kind = match fun.0.self_kind { fun.0.self_kind = match fun.0.self_kind {
SelfKind::Owned(_) => SelfKind::Owned(ty.0.clone()), SelfKind::Owned(_) => SelfKind::Owned(ty.clone()),
SelfKind::Borrow(_) => SelfKind::Borrow(ty.0.clone()), SelfKind::Borrow(_) => SelfKind::Borrow(ty.clone()),
SelfKind::MutBorrow(_) => SelfKind::MutBorrow(ty.0.clone()), SelfKind::MutBorrow(_) => SelfKind::MutBorrow(ty.clone()),
SelfKind::None => SelfKind::None, SelfKind::None => SelfKind::None,
}; };
functions.push(fun); functions.push(fun);

View File

@ -3,8 +3,8 @@ use std::path::PathBuf;
use crate::{ use crate::{
ast::{self}, ast::{self},
mir::{ mir::{
self, CustomTypeKey, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind, StructField, self, CustomTypeKey, FunctionParam, ModuleMap, NamedVariableRef, ReturnKind, SourceModuleId, StmtKind,
StructType, WhileStatement, StructField, StructType, WhileStatement,
}, },
}; };
@ -48,7 +48,11 @@ impl ast::Module {
.params .params
.iter() .iter()
.cloned() .cloned()
.map(|p| (p.0, p.1 .0.into_mir(module_id))) .map(|p| mir::FunctionParam {
name: p.0,
ty: p.1 .0.into_mir(module_id),
meta: p.1 .1.as_meta(module_id),
})
.collect(), .collect(),
kind: mir::FunctionDefinitionKind::Extern(false), kind: mir::FunctionDefinitionKind::Extern(false),
}; };
@ -88,9 +92,17 @@ impl ast::Module {
signature_range, signature_range,
}) => { }) => {
binops.push(mir::BinopDefinition { binops.push(mir::BinopDefinition {
lhs: (lhs.0.clone(), lhs.1 .0.into_mir(module_id)), lhs: mir::FunctionParam {
name: lhs.0.clone(),
ty: lhs.1 .0.into_mir(module_id),
meta: lhs.1 .1.as_meta(module_id),
},
op: op.mir(), op: op.mir(),
rhs: (rhs.0.clone(), rhs.1 .0.into_mir(module_id)), rhs: mir::FunctionParam {
name: rhs.0.clone(),
ty: rhs.1 .0.into_mir(module_id),
meta: rhs.1 .1.as_meta(module_id),
},
return_type: return_ty.0.into_mir(module_id), return_type: return_ty.0.into_mir(module_id),
fn_kind: mir::FunctionDefinitionKind::Local( fn_kind: mir::FunctionDefinitionKind::Local(
block.into_mir(module_id), block.into_mir(module_id),
@ -129,25 +141,29 @@ impl ast::FunctionDefinition {
let mut params = Vec::new(); let mut params = Vec::new();
match &signature.self_kind { match &signature.self_kind {
ast::SelfKind::Borrow(type_kind) => params.push(( ast::SelfKind::Borrow(ty) => params.push(mir::FunctionParam {
"self".to_owned(), name: "self".to_owned(),
mir::TypeKind::Borrow(Box::new(type_kind.into_mir(module_id)), false), ty: mir::TypeKind::Borrow(Box::new(ty.0.into_mir(module_id)), false),
)), meta: ty.1.as_meta(module_id),
ast::SelfKind::MutBorrow(type_kind) => params.push(( }),
"self".to_owned(), ast::SelfKind::MutBorrow(ty) => params.push(mir::FunctionParam {
mir::TypeKind::Borrow(Box::new(type_kind.into_mir(module_id)), true), name: "self".to_owned(),
)), ty: mir::TypeKind::Borrow(Box::new(ty.0.into_mir(module_id)), true),
ast::SelfKind::Owned(type_kind) => params.push(("self".to_owned(), type_kind.into_mir(module_id))), meta: ty.1.as_meta(module_id),
}),
ast::SelfKind::Owned(ty) => params.push(mir::FunctionParam {
name: "self".to_owned(),
ty: ty.0.into_mir(module_id),
meta: ty.1.as_meta(module_id),
}),
ast::SelfKind::None => {} ast::SelfKind::None => {}
} }
params.extend( params.extend(signature.params.iter().cloned().map(|p| FunctionParam {
signature name: p.0,
.params ty: p.1 .0.into_mir(module_id),
.iter() meta: p.1 .1.as_meta(module_id),
.cloned() }));
.map(|p| (p.0, p.1 .0.into_mir(module_id))),
);
mir::FunctionDefinition { mir::FunctionDefinition {
name: signature.name.clone(), name: signature.name.clone(),
linkage_name: None, linkage_name: None,

View File

@ -7,7 +7,7 @@ use reid_lib::{
use mir::{CustomTypeKey, FunctionCall, FunctionDefinitionKind, IfExpression, TypeKind, WhileStatement}; use mir::{CustomTypeKey, FunctionCall, FunctionDefinitionKind, IfExpression, TypeKind, WhileStatement};
use crate::mir; use crate::mir::{self, FunctionParam, Metadata};
#[derive(Debug)] #[derive(Debug)]
pub struct Allocator { pub struct Allocator {
@ -20,17 +20,13 @@ pub struct AllocatorScope<'ctx, 'a> {
} }
impl Allocator { impl Allocator {
pub fn from( pub fn from(func: &FunctionDefinitionKind, params: &Vec<FunctionParam>, scope: &mut AllocatorScope) -> Allocator {
func: &FunctionDefinitionKind,
params: &Vec<(String, TypeKind)>,
scope: &mut AllocatorScope,
) -> Allocator {
func.allocate(scope, params) func.allocate(scope, params)
} }
pub fn allocate(&mut self, name: &String, ty: &TypeKind) -> Option<InstructionValue> { pub fn allocate(&mut self, meta: &Metadata, ty: &TypeKind) -> Option<InstructionValue> {
let mut allocs = self.allocations.iter().cloned().enumerate(); let mut allocs = self.allocations.iter().cloned().enumerate();
let val = allocs.find(|a| a.1 .0 == *name && a.1 .1 == *ty); let val = allocs.find(|a| a.1 .0 == *meta && a.1 .1 == *ty);
if let Some((i, _)) = val { if let Some((i, _)) = val {
self.allocations.remove(i); self.allocations.remove(i);
} }
@ -39,13 +35,13 @@ impl Allocator {
} }
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
pub struct Allocation(String, TypeKind, InstructionValue); pub struct Allocation(Metadata, TypeKind, InstructionValue);
impl mir::FunctionDefinitionKind { impl mir::FunctionDefinitionKind {
fn allocate<'ctx, 'a>( fn allocate<'ctx, 'a>(
&self, &self,
scope: &mut AllocatorScope<'ctx, 'a>, scope: &mut AllocatorScope<'ctx, 'a>,
parameters: &Vec<(String, TypeKind)>, parameters: &Vec<mir::FunctionParam>,
) -> Allocator { ) -> Allocator {
let mut allocated = Vec::new(); let mut allocated = Vec::new();
match &self { match &self {
@ -54,11 +50,11 @@ impl mir::FunctionDefinitionKind {
let allocation = scope let allocation = scope
.block .block
.build_named( .build_named(
param.0.clone(), param.name.clone(),
reid_lib::Instr::Alloca(param.1.get_type(scope.type_values)), reid_lib::Instr::Alloca(param.ty.get_type(scope.type_values)),
) )
.unwrap(); .unwrap();
allocated.push(Allocation(param.0.clone(), param.1.clone(), allocation)); allocated.push(Allocation(param.meta, param.ty.clone(), allocation));
} }
allocated.extend(block.allocate(scope)); allocated.extend(block.allocate(scope));
} }
@ -103,7 +99,7 @@ impl mir::Statement {
) )
.unwrap(); .unwrap();
allocated.push(Allocation( allocated.push(Allocation(
named_variable_ref.1.clone(), named_variable_ref.2,
named_variable_ref.0.clone(), named_variable_ref.0.clone(),
allocation, allocation,
)); ));
@ -195,7 +191,7 @@ impl mir::FunctionCall {
reid_lib::Instr::Alloca(self.return_type.get_type(scope.type_values)), reid_lib::Instr::Alloca(self.return_type.get_type(scope.type_values)),
) )
.unwrap(); .unwrap();
allocated.push(Allocation(name.clone(), self.return_type.clone(), allocation)); allocated.push(Allocation(self.meta, self.return_type.clone(), allocation));
} }
allocated allocated

View File

@ -2,7 +2,10 @@ use reid_lib::{builder::InstructionValue, CmpPredicate, ConstValue, Instr, Type}
use crate::{ use crate::{
codegen::{ErrorKind, StackValueKind}, codegen::{ErrorKind, StackValueKind},
mir::{BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, TypeKind}, mir::{
BinaryOperator, BinopDefinition, CmpOperator, FunctionDefinition, FunctionDefinitionKind, FunctionParam,
TypeKind,
},
}; };
use super::scope::{Scope, StackValue}; use super::scope::{Scope, StackValue};
@ -53,7 +56,11 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
is_pub: true, is_pub: true,
is_imported: false, is_imported: false,
return_type: TypeKind::UserPtr(Box::new(ty.clone())), return_type: TypeKind::UserPtr(Box::new(ty.clone())),
parameters: vec![(String::from("size"), TypeKind::U64)], parameters: vec![FunctionParam {
name: String::from("size"),
ty: TypeKind::U64,
meta: Default::default(),
}],
kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicAlloca(ty.clone()))), kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicAlloca(ty.clone()))),
}), }),
"null" => Some(FunctionDefinition { "null" => Some(FunctionDefinition {
@ -74,9 +81,17 @@ where
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
{ {
BinopDefinition { BinopDefinition {
lhs: ("lhs".to_owned(), ty.clone()), lhs: FunctionParam {
name: "lhs".to_owned(),
ty: ty.clone(),
meta: Default::default(),
},
op, op,
rhs: ("rhs".to_owned(), ty.clone()), rhs: FunctionParam {
name: "rhs".to_owned(),
ty: ty.clone(),
meta: Default::default(),
},
return_type: ty.clone(), return_type: ty.clone(),
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
meta: Default::default(), meta: Default::default(),
@ -89,9 +104,17 @@ where
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
{ {
BinopDefinition { BinopDefinition {
lhs: ("lhs".to_owned(), lhs.clone()), lhs: FunctionParam {
name: "lhs".to_owned(),
ty: lhs.clone(),
meta: Default::default(),
},
op, op,
rhs: ("rhs".to_owned(), rhs.clone()), rhs: FunctionParam {
name: "rhs".to_owned(),
ty: rhs.clone(),
meta: Default::default(),
},
return_type: lhs.clone(), return_type: lhs.clone(),
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))), fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicSimpleInstr(fun))),
meta: Default::default(), meta: Default::default(),
@ -104,9 +127,17 @@ where
T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue, T: FnOnce(&mut Scope, InstructionValue, InstructionValue) -> InstructionValue,
{ {
BinopDefinition { BinopDefinition {
lhs: ("lhs".to_owned(), ty.clone()), lhs: FunctionParam {
name: "lhs".to_owned(),
ty: ty.clone(),
meta: Default::default(),
},
op, op,
rhs: ("rhs".to_owned(), ty.clone()), rhs: FunctionParam {
name: "rhs".to_owned(),
ty: ty.clone(),
meta: Default::default(),
},
return_type: TypeKind::Bool, return_type: TypeKind::Bool,
fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))), fn_kind: FunctionDefinitionKind::Intrinsic(Box::new(IntrinsicBooleanInstr(fun))),
meta: Default::default(), meta: Default::default(),

View File

@ -19,8 +19,8 @@ use crate::{
self, self,
implement::TypeCategory, implement::TypeCategory,
pass::{AssociatedFunctionKey, BinopKey}, pass::{AssociatedFunctionKey, BinopKey},
CustomTypeKey, FunctionCall, FunctionDefinitionKind, NamedVariableRef, SourceModuleId, StructField, StructType, CustomTypeKey, FunctionCall, FunctionDefinitionKind, FunctionParam, NamedVariableRef, SourceModuleId,
TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement, StructField, StructType, TypeDefinition, TypeDefinitionKind, TypeKind, WhileStatement,
}, },
util::try_all, util::try_all,
}; };
@ -182,7 +182,7 @@ impl mir::Module {
let param_types: Vec<Type> = function let param_types: Vec<Type> = function
.parameters .parameters
.iter() .iter()
.map(|(_, p)| p.get_type(&type_values)) .map(|FunctionParam { ty, .. }| ty.get_type(&type_values))
.collect(); .collect();
let is_main = self.is_main && function.name == "main"; let is_main = self.is_main && function.name == "main";
@ -222,7 +222,7 @@ impl mir::Module {
let param_types: Vec<Type> = function let param_types: Vec<Type> = function
.parameters .parameters
.iter() .iter()
.map(|(_, p)| p.get_type(&type_values)) .map(|FunctionParam { ty, .. }| ty.get_type(&type_values))
.collect(); .collect();
let is_main = self.is_main && function.name == "main"; let is_main = self.is_main && function.name == "main";
@ -263,11 +263,11 @@ impl mir::Module {
for binop in &self.binop_defs { for binop in &self.binop_defs {
let binop_fn_name = format!( let binop_fn_name = format!(
"binop.{}.{:?}.{}.{}", "binop.{}.{:?}.{}.{}",
binop.lhs.1, binop.op, binop.rhs.1, binop.return_type binop.lhs.ty, binop.op, binop.rhs.ty, binop.return_type
); );
binops.insert( binops.insert(
BinopKey { BinopKey {
params: (binop.lhs.1.clone(), binop.rhs.1.clone()), params: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
}, },
StackBinopDefinition { StackBinopDefinition {
@ -278,7 +278,7 @@ impl mir::Module {
let ir_function = module.function( let ir_function = module.function(
&binop_fn_name, &binop_fn_name,
binop.return_type.get_type(&type_values), binop.return_type.get_type(&type_values),
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
FunctionFlags { FunctionFlags {
is_pub: binop.exported, is_pub: binop.exported,
is_imported: binop.exported, is_imported: binop.exported,
@ -342,7 +342,7 @@ impl mir::Module {
FunctionDefinitionKind::Extern(imported) => ScopeFunctionKind::UserGenerated(module.function( FunctionDefinitionKind::Extern(imported) => ScopeFunctionKind::UserGenerated(module.function(
&binop_fn_name, &binop_fn_name,
binop.return_type.get_type(&type_values), binop.return_type.get_type(&type_values),
vec![binop.lhs.1.get_type(&type_values), binop.rhs.1.get_type(&type_values)], vec![binop.lhs.ty.get_type(&type_values), binop.rhs.ty.get_type(&type_values)],
FunctionFlags { FunctionFlags {
is_extern: true, is_extern: true,
is_imported: *imported, is_imported: *imported,
@ -482,7 +482,7 @@ impl FunctionDefinitionKind {
name: String, name: String,
is_pub: bool, is_pub: bool,
scope: &mut Scope, scope: &mut Scope,
parameters: &Vec<(String, TypeKind)>, parameters: &Vec<FunctionParam>,
return_type: &TypeKind, return_type: &TypeKind,
ir_function: &Function, ir_function: &Function,
debug_location: Option<DebugLocation>, debug_location: Option<DebugLocation>,
@ -526,25 +526,25 @@ impl FunctionDefinitionKind {
} }
// Compile actual IR part // Compile actual IR part
for (i, (p_name, p_ty)) in parameters.iter().enumerate() { for (i, p) in parameters.iter().enumerate() {
// Codegen actual parameters // Codegen actual parameters
let arg_name = format!("arg.{}", p_name); let arg_name = format!("arg.{}", p.name);
let param = scope let param = scope
.block .block
.build_named(format!("{}.get", arg_name), Instr::Param(i)) .build_named(format!("{}.get", arg_name), Instr::Param(i))
.unwrap(); .unwrap();
let alloca = scope.allocate(&p_name, &p_ty).unwrap(); let alloca = scope.allocate(&p.meta, &p.ty).unwrap();
scope scope
.block .block
.build_named(format!("{}.store", arg_name), Instr::Store(alloca, param)) .build_named(format!("{}.store", arg_name), Instr::Store(alloca, param))
.unwrap(); .unwrap();
scope.stack_values.insert( scope.stack_values.insert(
p_name.clone(), p.name.clone(),
StackValue( StackValue(
StackValueKind::mutable(p_ty.is_mutable(), alloca), StackValueKind::mutable(p.ty.is_mutable(), alloca),
TypeKind::CodegenPtr(Box::new(p_ty.clone())), TypeKind::CodegenPtr(Box::new(p.ty.clone())),
), ),
); );
} }
@ -644,11 +644,11 @@ impl mir::Statement {
}); });
match &self.0 { match &self.0 {
mir::StmtKind::Let(NamedVariableRef(ty, name, _), mutable, expression) => { mir::StmtKind::Let(NamedVariableRef(ty, name, meta), mutable, expression) => {
let value = expression.codegen(scope, &state)?.unwrap(); let value = expression.codegen(scope, &state)?.unwrap();
let alloca = scope let alloca = scope
.allocate(name, &value.1) .allocate(meta, &value.1)
.unwrap() .unwrap()
.maybe_location(&mut scope.block, location.clone()); .maybe_location(&mut scope.block, location.clone());
@ -1348,7 +1348,7 @@ fn codegen_function_call<'ctx, 'a>(
let ptr = scope let ptr = scope
.allocator .allocator
.borrow_mut() .borrow_mut()
.allocate(&call_name, &call.return_type) .allocate(&call.meta, &call.return_type)
.unwrap(); .unwrap();
scope scope
.block .block

View File

@ -10,7 +10,7 @@ use crate::{
lexer::FullToken, lexer::FullToken,
mir::{ mir::{
pass::{AssociatedFunctionKey, BinopKey}, pass::{AssociatedFunctionKey, BinopKey},
CustomTypeKey, SourceModuleId, TypeDefinition, TypeKind, CustomTypeKey, FunctionParam, Metadata, SourceModuleId, TypeDefinition, TypeKind,
}, },
}; };
@ -67,8 +67,8 @@ impl<'ctx, 'a> Scope<'ctx, 'a> {
self.type_values.get(key).and_then(|v| self.types.get(v)) self.type_values.get(key).and_then(|v| self.types.get(v))
} }
pub fn allocate(&self, name: &String, ty: &TypeKind) -> Option<InstructionValue> { pub fn allocate(&self, meta: &Metadata, ty: &TypeKind) -> Option<InstructionValue> {
self.allocator.borrow_mut().allocate(name, ty) self.allocator.borrow_mut().allocate(meta, ty)
} }
} }
@ -129,7 +129,7 @@ impl StackValueKind {
} }
pub struct StackBinopDefinition<'ctx> { pub struct StackBinopDefinition<'ctx> {
pub(super) parameters: ((String, TypeKind), (String, TypeKind)), pub(super) parameters: (FunctionParam, FunctionParam),
pub(super) return_ty: TypeKind, pub(super) return_ty: TypeKind,
pub(super) kind: ScopeFunctionKind<'ctx>, pub(super) kind: ScopeFunctionKind<'ctx>,
} }
@ -147,14 +147,14 @@ impl<'ctx> StackBinopDefinition<'ctx> {
rhs: StackValue, rhs: StackValue,
scope: &mut Scope<'ctx, 'a>, scope: &mut Scope<'ctx, 'a>,
) -> Result<StackValue, ErrorKind> { ) -> Result<StackValue, ErrorKind> {
let (lhs, rhs) = if lhs.1 == self.parameters.0 .1 && rhs.1 == self.parameters.1 .1 { let (lhs, rhs) = if lhs.1 == self.parameters.0.ty && rhs.1 == self.parameters.1.ty {
(lhs, rhs) (lhs, rhs)
} else { } else {
(rhs, lhs) (rhs, lhs)
}; };
let name = format!( let name = format!(
"binop.{}.{}.{}.call", "binop.{}.{}.{}.call",
self.parameters.0 .1, self.parameters.1 .1, self.return_ty 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)
} }

View File

@ -131,11 +131,11 @@ pub fn perform_all_passes<'map>(
binops binops
.set( .set(
mir::pass::BinopKey { mir::pass::BinopKey {
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), params: (intrinsic.lhs.ty.clone(), intrinsic.rhs.ty.clone()),
operator: intrinsic.op, operator: intrinsic.op,
}, },
mir::pass::ScopeBinopDef { mir::pass::ScopeBinopDef {
hands: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), hands: (intrinsic.lhs.ty.clone(), intrinsic.rhs.ty.clone()),
operator: intrinsic.op, operator: intrinsic.op,
return_ty: intrinsic.return_type.clone(), return_ty: intrinsic.return_type.clone(),
}, },

View File

@ -71,11 +71,11 @@ impl Display for BinopDefinition {
f, f,
"{}impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ", "{}impl binop ({}: {:#}) {} ({}: {:#}) -> {:#} ",
if self.exported { "exported " } else { "" }, if self.exported { "exported " } else { "" },
self.lhs.0, self.lhs.name,
self.lhs.1, self.lhs.ty,
self.op, self.op,
self.rhs.0, self.rhs.name,
self.rhs.1, self.rhs.ty,
self.return_type self.return_type
)?; )?;
Display::fmt(&self.fn_kind, f) Display::fmt(&self.fn_kind, f)
@ -132,7 +132,7 @@ impl Display for FunctionDefinition {
self.name, self.name,
self.parameters self.parameters
.iter() .iter()
.map(|(n, t)| format!("{}: {:#}", n, t)) .map(|FunctionParam { name, ty, .. }| format!("{}: {:#}", name, ty))
.collect::<Vec<_>>() .collect::<Vec<_>>()
.join(", "), .join(", "),
self.return_type self.return_type

View File

@ -11,8 +11,8 @@ use crate::{
compile_module, compile_module,
error_raporting::{ErrorModules, ReidError}, error_raporting::{ErrorModules, ReidError},
mir::{ mir::{
pass::BinopKey, BinopDefinition, CustomTypeKey, FunctionDefinitionKind, SourceModuleId, TypeDefinition, pass::BinopKey, BinopDefinition, CustomTypeKey, FunctionDefinitionKind, FunctionParam, SourceModuleId,
TypeKind, TypeDefinition, TypeKind,
}, },
parse_module, parse_module,
}; };
@ -220,10 +220,10 @@ impl<'map> Pass for LinkerPass<'map> {
imported_types.extend(types); imported_types.extend(types);
let mut param_tys = Vec::new(); let mut param_tys = Vec::new();
for (param_name, param_ty) in &func.parameters { for param in &func.parameters {
let types = import_type(&param_ty, false); let types = import_type(&param.ty, false);
imported_types.extend(types); imported_types.extend(types);
param_tys.push((param_name.clone(), param_ty.clone())); param_tys.push(param.clone());
} }
importer_module.functions.push(FunctionDefinition { importer_module.functions.push(FunctionDefinition {
@ -241,11 +241,11 @@ impl<'map> Pass for LinkerPass<'map> {
imported_types.push((external_key, true)); imported_types.push((external_key, true));
for binop in &mut imported.binop_defs { for binop in &mut imported.binop_defs {
if binop.lhs.1 != imported_ty && binop.rhs.1 != imported_ty { if binop.lhs.ty != imported_ty && binop.rhs.ty != imported_ty {
continue; continue;
} }
let binop_key = BinopKey { let binop_key = BinopKey {
params: (binop.lhs.1.clone(), binop.rhs.1.clone()), params: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
}; };
if already_imported_binops.contains(&binop_key) { if already_imported_binops.contains(&binop_key) {
@ -309,10 +309,10 @@ impl<'map> Pass for LinkerPass<'map> {
imported_types.extend(types); imported_types.extend(types);
let mut param_tys = Vec::new(); let mut param_tys = Vec::new();
for (param_name, param_ty) in &func.parameters { for param in &func.parameters {
let types = import_type(&param_ty, false); let types = import_type(&param.ty, false);
imported_types.extend(types); imported_types.extend(types);
param_tys.push((param_name.clone(), param_ty.clone())); param_tys.push(param.clone());
} }
importer_module.associated_functions.push(( importer_module.associated_functions.push((
@ -424,7 +424,7 @@ impl<'map> Pass for LinkerPass<'map> {
if let Some(extern_types) = extern_types { if let Some(extern_types) = extern_types {
function.return_type = function.return_type.update_imported(*extern_types, mod_id); function.return_type = function.return_type.update_imported(*extern_types, mod_id);
for param in function.parameters.iter_mut() { for param in function.parameters.iter_mut() {
param.1 = param.1.update_imported(extern_types, mod_id); param.ty = param.ty.update_imported(extern_types, mod_id);
} }
} }
} }

View File

@ -296,10 +296,17 @@ pub struct FunctionDefinition {
/// Whether this module is from an external module, and has been imported /// Whether this module is from an external module, and has been imported
pub is_imported: bool, pub is_imported: bool,
pub return_type: TypeKind, pub return_type: TypeKind,
pub parameters: Vec<(String, TypeKind)>, pub parameters: Vec<FunctionParam>,
pub kind: FunctionDefinitionKind, pub kind: FunctionDefinitionKind,
} }
#[derive(Debug, Clone, PartialEq, PartialOrd)]
pub struct FunctionParam {
pub name: String,
pub ty: TypeKind,
pub meta: Metadata,
}
pub enum SelfKind { pub enum SelfKind {
Borrow, Borrow,
MutBorrow, MutBorrow,
@ -378,9 +385,9 @@ pub enum TypeDefinitionKind {
#[derive(Debug)] #[derive(Debug)]
pub struct BinopDefinition { pub struct BinopDefinition {
pub lhs: (String, TypeKind), pub lhs: FunctionParam,
pub op: BinaryOperator, pub op: BinaryOperator,
pub rhs: (String, TypeKind), pub rhs: FunctionParam,
pub return_type: TypeKind, pub return_type: TypeKind,
pub fn_kind: FunctionDefinitionKind, pub fn_kind: FunctionDefinitionKind,
pub meta: Metadata, pub meta: Metadata,

View File

@ -187,7 +187,7 @@ impl<Data: Clone + Default> Scope<Data> {
key.clone(), key.clone(),
ScopeFunction { ScopeFunction {
ret: func.return_type, ret: func.return_type,
params: func.parameters.iter().map(|(_, p)| p.clone()).collect(), params: func.parameters.iter().map(|p| p.ty.clone()).collect(),
}, },
) )
.unwrap(); .unwrap();
@ -369,11 +369,11 @@ impl Context {
.binops .binops
.set( .set(
BinopKey { BinopKey {
params: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), params: (intrinsic.lhs.ty.clone(), intrinsic.rhs.ty.clone()),
operator: intrinsic.op, operator: intrinsic.op,
}, },
ScopeBinopDef { ScopeBinopDef {
hands: (intrinsic.lhs.1.clone(), intrinsic.rhs.1.clone()), hands: (intrinsic.lhs.ty.clone(), intrinsic.rhs.ty.clone()),
operator: intrinsic.op, operator: intrinsic.op,
return_ty: intrinsic.return_type.clone(), return_ty: intrinsic.return_type.clone(),
}, },
@ -407,11 +407,11 @@ impl Module {
.binops .binops
.set( .set(
BinopKey { BinopKey {
params: (binop.lhs.1.clone(), binop.rhs.1.clone()), params: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
}, },
ScopeBinopDef { ScopeBinopDef {
hands: (binop.lhs.1.clone(), binop.rhs.1.clone()), hands: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
return_ty: binop.return_type.clone(), return_ty: binop.return_type.clone(),
}, },
@ -426,7 +426,7 @@ impl Module {
function.name.clone(), function.name.clone(),
ScopeFunction { ScopeFunction {
ret: function.return_type.clone(), ret: function.return_type.clone(),
params: function.parameters.iter().cloned().map(|v| v.1).collect(), params: function.parameters.iter().cloned().map(|v| v.ty).collect(),
}, },
) )
.ok(); .ok();
@ -439,7 +439,7 @@ impl Module {
AssociatedFunctionKey(ty.clone(), function.name.clone()), AssociatedFunctionKey(ty.clone(), function.name.clone()),
ScopeFunction { ScopeFunction {
ret: function.return_type.clone(), ret: function.return_type.clone(),
params: function.parameters.iter().cloned().map(|v| v.1).collect(), params: function.parameters.iter().cloned().map(|v| v.ty).collect(),
}, },
) )
.ok(); .ok();
@ -466,9 +466,9 @@ impl FunctionDefinition {
scope scope
.variables .variables
.set( .set(
param.0.clone(), param.name.clone(),
ScopeVariable { ScopeVariable {
ty: param.1.clone(), ty: param.ty.clone(),
mutable: false, mutable: false,
}, },
) )

View File

@ -112,7 +112,7 @@ impl BinopDefinition {
fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result<TypeKind, ErrorKind> { fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result<TypeKind, ErrorKind> {
for param in vec![&self.lhs, &self.rhs] { for param in vec![&self.lhs, &self.rhs] {
let param_t = state.or_else( let param_t = state.or_else(
param.1.assert_known(state), param.ty.assert_known(state),
TypeKind::Vague(Vague::Unknown), TypeKind::Vague(Vague::Unknown),
self.signature(), self.signature(),
); );
@ -120,13 +120,13 @@ impl BinopDefinition {
.scope .scope
.variables .variables
.set( .set(
param.0.clone(), param.name.clone(),
ScopeVariable { ScopeVariable {
ty: param_t.clone(), ty: param_t.clone(),
mutable: param_t.is_mutable(), mutable: param_t.is_mutable(),
}, },
) )
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone()))); .or(Err(ErrorKind::VariableAlreadyDefined(param.name.clone())));
state.ok(res, self.signature()); state.ok(res, self.signature());
} }
@ -150,7 +150,7 @@ impl FunctionDefinition {
fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result<TypeKind, ErrorKind> { fn typecheck(&mut self, typerefs: &TypeRefs, state: &mut TypecheckPassState) -> Result<TypeKind, ErrorKind> {
for param in &self.parameters { for param in &self.parameters {
let param_t = state.or_else( let param_t = state.or_else(
param.1.assert_known(state), param.ty.assert_known(state),
TypeKind::Vague(Vague::Unknown), TypeKind::Vague(Vague::Unknown),
self.signature(), self.signature(),
); );
@ -158,13 +158,13 @@ impl FunctionDefinition {
.scope .scope
.variables .variables
.set( .set(
param.0.clone(), param.name.clone(),
ScopeVariable { ScopeVariable {
ty: param_t.clone(), ty: param_t.clone(),
mutable: param_t.is_mutable(), mutable: param_t.is_mutable(),
}, },
) )
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone()))); .or(Err(ErrorKind::VariableAlreadyDefined(param.name.clone())));
state.ok(res, self.signature()); state.ok(res, self.signature());
} }

View File

@ -87,16 +87,16 @@ impl<'t> Pass for TypeInference<'t> {
let mut seen_binops = HashSet::new(); let mut seen_binops = HashSet::new();
for binop in &module.binop_defs { for binop in &module.binop_defs {
let binop_key = BinopKey { let binop_key = BinopKey {
params: (binop.lhs.1.clone(), binop.rhs.1.clone()), params: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
}; };
if seen_binops.contains(&binop_key) || (binop.lhs == binop.rhs && binop.lhs.1.category().is_simple_maths()) if seen_binops.contains(&binop_key) || (binop.lhs == binop.rhs && binop.lhs.ty.category().is_simple_maths())
{ {
state.note_errors( state.note_errors(
&vec![ErrorKind::BinaryOpAlreadyDefined( &vec![ErrorKind::BinaryOpAlreadyDefined(
binop.op, binop.op,
binop.lhs.1.clone(), binop.lhs.ty.clone(),
binop.rhs.1.clone(), binop.rhs.ty.clone(),
)], )],
binop.signature(), binop.signature(),
); );
@ -107,7 +107,7 @@ impl<'t> Pass for TypeInference<'t> {
.set( .set(
binop_key, binop_key,
crate::mir::pass::ScopeBinopDef { crate::mir::pass::ScopeBinopDef {
hands: (binop.lhs.1.clone(), binop.rhs.1.clone()), hands: (binop.lhs.ty.clone(), binop.rhs.ty.clone()),
operator: binop.op, operator: binop.op,
return_ty: binop.return_type.clone(), return_ty: binop.return_type.clone(),
}, },
@ -138,20 +138,20 @@ impl BinopDefinition {
fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> { fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> {
let scope_hints = ScopeTypeRefs::from(type_refs); let scope_hints = ScopeTypeRefs::from(type_refs);
let lhs_ty = state.or_else(self.lhs.1.assert_unvague(), Vague(Unknown), self.signature()); let lhs_ty = state.or_else(self.lhs.ty.assert_unvague(), Vague(Unknown), self.signature());
state.ok( state.ok(
scope_hints scope_hints
.new_var(self.lhs.0.clone(), false, &lhs_ty) .new_var(self.lhs.name.clone(), false, &lhs_ty)
.or(Err(ErrorKind::VariableAlreadyDefined(self.lhs.0.clone()))), .or(Err(ErrorKind::VariableAlreadyDefined(self.lhs.name.clone()))),
self.signature(), self.signature(),
); );
let rhs_ty = state.or_else(self.rhs.1.assert_unvague(), Vague(Unknown), self.signature()); let rhs_ty = state.or_else(self.rhs.ty.assert_unvague(), Vague(Unknown), self.signature());
state.ok( state.ok(
scope_hints scope_hints
.new_var(self.rhs.0.clone(), false, &rhs_ty) .new_var(self.rhs.name.clone(), false, &rhs_ty)
.or(Err(ErrorKind::VariableAlreadyDefined(self.rhs.0.clone()))), .or(Err(ErrorKind::VariableAlreadyDefined(self.rhs.name.clone()))),
self.signature(), self.signature(),
); );
@ -170,10 +170,10 @@ impl FunctionDefinition {
fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> { fn infer_types(&mut self, type_refs: &TypeRefs, state: &mut TypecheckPassState) -> Result<(), ErrorKind> {
let scope_refs = ScopeTypeRefs::from(type_refs); let scope_refs = ScopeTypeRefs::from(type_refs);
for param in &self.parameters { for param in &self.parameters {
let param_t = state.or_else(param.1.assert_unvague(), Vague(Unknown), self.signature()); let param_t = state.or_else(param.ty.assert_unvague(), Vague(Unknown), self.signature());
let res = scope_refs let res = scope_refs
.new_var(param.0.clone(), false, &param_t) .new_var(param.name.clone(), false, &param_t)
.or(Err(ErrorKind::VariableAlreadyDefined(param.0.clone()))); .or(Err(ErrorKind::VariableAlreadyDefined(param.name.clone())));
state.ok(res, self.signature()); state.ok(res, self.signature());
} }