Skip to content

Commit

Permalink
Started working on polymorphic function matching
Browse files Browse the repository at this point in the history
  • Loading branch information
IsaacShelton committed Nov 6, 2024
1 parent f28c9dc commit bdcb61b
Show file tree
Hide file tree
Showing 5 changed files with 103 additions and 7 deletions.
19 changes: 13 additions & 6 deletions src/resolve/function_haystack.rs
Original file line number Diff line number Diff line change
Expand Up @@ -211,8 +211,13 @@ impl FunctionHaystack {
let preferred_type = (i < parameters.required.len())
.then_some(PreferredType::of_parameter(function_ref, i));

let argument_conform =
if let Some(preferred_type) = preferred_type.map(|p| p.view(ctx.resolved_ast)) {
let argument_conforms = if let Some(preferred_type) =
preferred_type.map(|p| p.view(ctx.resolved_ast))
{
if preferred_type.kind.contains_polymorph() {
eprintln!("warning: assuming parameter type that contains polymorph matches for function argument");
true
} else {
conform_expr::<Validate>(
ctx,
argument,
Expand All @@ -221,11 +226,13 @@ impl FunctionHaystack {
ctx.adept_conform_behavior(),
source,
)
} else {
conform_expr_to_default::<Validate>(argument, ctx.c_integer_assumptions())
};
.is_ok()
}
} else {
conform_expr_to_default::<Validate>(argument, ctx.c_integer_assumptions()).is_ok()
};

if argument_conform.is_err() {
if !argument_conforms {
return false;
}
}
Expand Down
1 change: 1 addition & 0 deletions src/resolve/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ mod global_variable;
mod helper_expr;
mod initialized;
mod job;
mod polymorph;
mod stmt;
mod type_ctx;
mod type_definition;
Expand Down
63 changes: 63 additions & 0 deletions src/resolve/polymorph.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
use crate::resolved::{self, Constraint};
use derive_more::IsVariant;
use indexmap::IndexMap;
use std::collections::HashSet;

#[derive(Clone, Debug)]
pub struct PolyType {
constaints: HashSet<Constraint>,
}

#[derive(Clone, Debug)]
pub struct PolyExpr {
expr: resolved::Expr,
}

#[derive(Clone, Debug, IsVariant)]
pub enum PolyValue {
PolyType(PolyType),
PolyExpr(PolyExpr),
}

#[derive(Clone, Debug)]
pub struct PolyCatalog {
polymorphs: IndexMap<String, PolyValue>,
}

#[derive(Clone, Debug)]
pub enum PolyCatalogInsertError {
/// Cannot have a single polymorph that is both a type as well as an expression
Incongruent,
}

impl PolyCatalog {
pub fn new() -> Self {
Self {
polymorphs: IndexMap::default(),
}
}

pub fn put_type(
&mut self,
name: String,
new_constraints: impl Iterator<Item = Constraint>,
) -> Result<(), PolyCatalogInsertError> {
if let Some(existing) = self.polymorphs.get_mut(&name) {
match existing {
PolyValue::PolyType(poly_type) => {
poly_type.constaints.extend(new_constraints);
}
PolyValue::PolyExpr(_) => return Err(PolyCatalogInsertError::Incongruent),
}
} else {
self.polymorphs.insert(
name,
PolyValue::PolyType(PolyType {
constaints: HashSet::from_iter(new_constraints),
}),
);
}

Ok(())
}
}
2 changes: 1 addition & 1 deletion src/resolved/datatype/kind/constraint.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use std::fmt::Display;

#[derive(Clone, Debug, PartialEq)]
#[derive(Clone, Debug, PartialEq, Eq, Hash)]
pub enum Constraint {
Add,
}
Expand Down
25 changes: 25 additions & 0 deletions src/resolved/datatype/kind/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,31 @@ impl TypeKind {
Type { kind: self, source }
}

pub fn contains_polymorph(&self) -> bool {
match self {
TypeKind::Unresolved => {
panic!("resolved::TypeKind::contains_polymorph was called on unresolved type")
}
TypeKind::Boolean
| TypeKind::Integer(_, _)
| TypeKind::CInteger(_, _)
| TypeKind::IntegerLiteral(_)
| TypeKind::FloatLiteral(_)
| TypeKind::Floating(_) => false,
TypeKind::Pointer(inner) => inner.kind.contains_polymorph(),
TypeKind::Void => false,
TypeKind::AnonymousStruct() => todo!(),
TypeKind::AnonymousUnion() => todo!(),
TypeKind::AnonymousEnum(_) => todo!(),
TypeKind::FixedArray(fixed_array) => fixed_array.inner.kind.contains_polymorph(),
TypeKind::FunctionPointer(_) => todo!(),
TypeKind::Enum(_, _) => false,
TypeKind::Structure(_, _) => false,
TypeKind::TypeAlias(_, _) => false,
TypeKind::Polymorph(_, _) => true,
}
}

pub fn sign(&self, target: Option<&Target>) -> Option<IntegerSign> {
match self {
TypeKind::Boolean => Some(IntegerSign::Unsigned),
Expand Down

0 comments on commit bdcb61b

Please sign in to comment.