Implement importing of associated functions with types

This commit is contained in:
Sofia 2025-07-27 23:28:24 +03:00
parent 5104555890
commit dc360ef196
6 changed files with 72 additions and 7 deletions

View File

@ -14,7 +14,7 @@ struct String {
impl String {
pub fn new() -> String {
String {
inner: char::alloca(0),
inner: allocate(0),
length: 0,
max_length: 0,
must_be_freed: true,

View File

@ -36,6 +36,7 @@ impl ast::Module {
ExternFunction(signature) => {
let def = mir::FunctionDefinition {
name: signature.name.clone(),
linkage_name: None,
is_pub: false,
is_imported: false,
return_type: signature
@ -149,6 +150,7 @@ impl ast::FunctionDefinition {
);
mir::FunctionDefinition {
name: signature.name.clone(),
linkage_name: None,
is_pub: *is_pub,
is_imported: false,
return_type: signature

View File

@ -40,6 +40,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
match name {
"sizeof" => Some(FunctionDefinition {
name: "sizeof".to_owned(),
linkage_name: None,
is_pub: true,
is_imported: false,
return_type: TypeKind::U64,
@ -48,6 +49,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
}),
"alloca" => Some(FunctionDefinition {
name: "alloca".to_owned(),
linkage_name: None,
is_pub: true,
is_imported: false,
return_type: TypeKind::UserPtr(Box::new(ty.clone())),
@ -56,6 +58,7 @@ pub fn get_intrinsic_assoc_func(ty: &TypeKind, name: &str) -> Option<FunctionDef
}),
"null" => Some(FunctionDefinition {
name: "null".to_owned(),
linkage_name: None,
is_pub: true,
is_imported: false,
return_type: TypeKind::UserPtr(Box::new(ty.clone())),

View File

@ -187,7 +187,7 @@ impl mir::Module {
let is_main = self.is_main && function.name == "main";
let func = match &function.kind {
mir::FunctionDefinitionKind::Local(_, _) => Some(module.function(
&function.name,
&function.linkage_name.clone().unwrap_or(function.name.clone()),
function.return_type.get_type(&type_values),
param_types,
FunctionFlags {
@ -198,7 +198,7 @@ impl mir::Module {
},
)),
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
&function.name,
&function.linkage_name.clone().unwrap_or(function.name.clone()),
function.return_type.get_type(&type_values),
param_types,
FunctionFlags {
@ -238,7 +238,7 @@ impl mir::Module {
},
)),
mir::FunctionDefinitionKind::Extern(imported) => Some(module.function(
&function.name,
&function.linkage_name.clone().unwrap_or(function.name.clone()),
function.return_type.get_type(&type_values),
param_types,
FunctionFlags {

View File

@ -227,7 +227,8 @@ impl<'map> Pass for LinkerPass<'map> {
}
importer_module.functions.push(FunctionDefinition {
name: func_name,
name: func_name.clone(),
linkage_name: None,
is_pub: false,
is_imported: false,
return_type,
@ -268,6 +269,66 @@ impl<'map> Pass for LinkerPass<'map> {
FunctionDefinitionKind::Intrinsic(_) => {}
}
}
for (ty, func) in &mut imported.associated_functions {
if *ty != imported_ty {
continue;
}
let func_name = func.name.clone();
dbg!(&func_name);
if !func.is_pub {
state.ok::<_, Infallible>(
Err(ErrorKind::FunctionIsPrivate(module_name.clone(), func_name.clone())),
import.1,
);
continue;
}
func.is_imported = true;
if let Some((_, existing)) = importer_module
.associated_functions
.iter()
.find(|(ty, f)| *ty == imported_ty && f.name == *func_name)
{
if let Err(e) = existing.equals_as_imported(func) {
state.ok::<_, Infallible>(
Err(ErrorKind::FunctionImportIssue(
module_name.clone(),
func_name.clone(),
e,
)),
import.1,
);
}
}
let types = import_type(&func.return_type, false);
let return_type = func.return_type.clone();
imported_types.extend(types);
let mut param_tys = Vec::new();
for (param_name, param_ty) in &func.parameters {
let types = import_type(&param_ty, false);
imported_types.extend(types);
param_tys.push((param_name.clone(), param_ty.clone()));
}
importer_module.associated_functions.push((
ty.clone(),
FunctionDefinition {
name: func_name.clone(),
linkage_name: Some(format!("{}::{}", ty, func_name)),
is_pub: false,
is_imported: false,
return_type,
parameters: param_tys,
kind: super::FunctionDefinitionKind::Extern(true),
},
));
}
} else {
state.ok::<_, Infallible>(
Err(ErrorKind::ImportDoesNotExist(module_name.clone(), import_name.clone())),
@ -405,8 +466,6 @@ impl<'map> Pass for LinkerPass<'map> {
super::ExprKind::Deref(..) => {}
super::ExprKind::CastTo(_, type_kind) => *type_kind = type_kind.update_imported(extern_types, mod_id),
super::ExprKind::AssociatedFunctionCall(type_kind, _) => {
dbg!(&type_kind);
dbg!(extern_types);
*type_kind = type_kind.update_imported(extern_types, mod_id)
}
_ => {}

View File

@ -284,6 +284,7 @@ pub struct FunctionCall {
#[derive(Debug)]
pub struct FunctionDefinition {
pub name: String,
pub linkage_name: Option<String>,
/// Whether this function is visible to outside modules
pub is_pub: bool,
/// Whether this module is from an external module, and has been imported