Implement importing of associated functions with types
This commit is contained in:
parent
5104555890
commit
dc360ef196
@ -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,
|
||||
|
@ -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
|
||||
|
@ -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())),
|
||||
|
@ -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 {
|
||||
|
@ -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(¶m_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)
|
||||
}
|
||||
_ => {}
|
||||
|
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user