ast: add gens for ty and impl, raw ptr types, make fn return value non-optional

This commit is contained in:
2025-07-18 05:25:35 -04:00
parent 6ba62ac1c4
commit 148ef34a01
19 changed files with 242 additions and 147 deletions

View File

@@ -28,6 +28,11 @@ impl fmt::Display for Entry<'_, '_> {
let h_id = self.with_id(id);
write_name_or(h_id, f)
}
&TypeKind::Ptr(id) => {
f.write_str("*")?;
let h_id = self.with_id(id);
write_name_or(h_id, f)
}
TypeKind::Slice(id) => {
write_name_or(self.with_id(*id), &mut f.delimit_with("[", "]"))
}
@@ -66,10 +71,7 @@ fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
let mut variants = variants.iter();
separate(", ", || {
variants.next().map(|(name, def)| {
move |f: &mut Delimit<_>| {
write!(f, "{name}: ")?;
write_name_or(h.with_id(*def), f)
}
move |f: &mut Delimit<_>| write!(f, "{name}: {}", h.with_id(*def))
})
})(f.delimit_with("enum {", "}"))
}
@@ -77,20 +79,14 @@ fn write_adt(adt: &Adt, h: &Entry, f: &mut impl Write) -> fmt::Result {
let mut members = members.iter();
separate(", ", || {
let (name, vis, id) = members.next()?;
Some(move |f: &mut Delimit<_>| {
write!(f, "{vis}{name}: ")?;
write_name_or(h.with_id(*id), f)
})
Some(move |f: &mut Delimit<_>| write!(f, "{vis}{name}: {}", h.with_id(*id)))
})(f.delimit_with("struct {", "}"))
}
Adt::TupleStruct(members) => {
let mut members = members.iter();
separate(", ", || {
let (vis, def) = members.next()?;
Some(move |f: &mut Delimit<_>| {
write!(f, "{vis}")?;
write_name_or(h.with_id(*def), f)
})
Some(move |f: &mut Delimit<_>| write!(f, "{vis}{}", h.with_id(*def)))
})(f.delimit_with("struct (", ")"))
}
Adt::UnitStruct => write!(f, "struct"),

View File

@@ -70,7 +70,7 @@ fn import_tree<'a>(
UseTree::Path(part, rest) => {
let source = table
.nav(src, slice::from_ref(part))
.ok_or_else(|| Error::NotFound(src, part.clone()))?;
.ok_or(Error::NotFound(src, *part))?;
import_tree(table, source, dst, rest, seen)
}
UseTree::Alias(src_name, dst_name) => {

View File

@@ -496,6 +496,7 @@ impl<'table, 'a> InferenceEngine<'table, 'a> {
todo!()
}
(TypeKind::Ref(a), TypeKind::Ref(b)) => self.unify(*a, *b),
(TypeKind::Ptr(a), TypeKind::Ptr(b)) => self.unify(*a, *b),
(TypeKind::Slice(a), TypeKind::Slice(b)) => self.unify(*a, *b),
// Slice unifies with array
(TypeKind::Array(a, _), TypeKind::Slice(b)) => self.unify(*a, *b),

View File

@@ -121,7 +121,7 @@ impl<'a> Table<'a> {
self.impls.push(item);
}
pub fn handle_iter(&mut self) -> impl Iterator<Item = Handle> + use<> {
pub fn handle_iter(&self) -> impl Iterator<Item = Handle> + use<> {
self.kinds.keys()
}

View File

@@ -2,7 +2,7 @@
//! construct type bindings in a [Table]'s typing context.
use crate::{handle::Handle, table::Table, type_kind::TypeKind};
use cl_ast::{PathPart, Ty, TyArray, TyFn, TyKind, TyRef, TySlice, TyTuple};
use cl_ast::{PathPart, Sym, Ty, TyArray, TyFn, TyKind, TyPtr, TyRef, TySlice, TyTuple};
#[derive(Clone, Debug, PartialEq, Eq)] // TODO: impl Display and Error
pub enum Error {
@@ -48,6 +48,7 @@ impl TypeExpression for TyKind {
TyKind::Slice(s) => s.evaluate(table, node),
TyKind::Tuple(t) => t.evaluate(table, node),
TyKind::Ref(r) => r.evaluate(table, node),
TyKind::Ptr(r) => r.evaluate(table, node),
TyKind::Fn(f) => f.evaluate(table, node),
}
}
@@ -68,6 +69,15 @@ impl TypeExpression for [PathPart] {
}
}
impl TypeExpression for Sym {
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
let path = [PathPart::Ident(*self)];
table
.nav(node, &path)
.ok_or_else(|| Error::BadPath { parent: node, path: path.to_vec() })
}
}
impl TypeExpression for TyArray {
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
let Self { ty, count } = self;
@@ -107,15 +117,21 @@ impl TypeExpression for TyRef {
}
}
impl TypeExpression for TyPtr {
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
let Self { to } = self;
let mut t = to.evaluate(table, node)?;
t = table.anon_type(TypeKind::Ptr(t));
Ok(t)
}
}
impl TypeExpression for TyFn {
fn evaluate(&self, table: &mut Table, node: Handle) -> Result<Handle, Error> {
let Self { args, rety } = self;
let kind = TypeKind::FnSig {
args: args.evaluate(table, node)?,
rety: match rety {
Some(ty) => ty.evaluate(table, node)?,
None => TyKind::Empty.evaluate(table, node)?,
},
rety: rety.evaluate(table, node)?,
};
Ok(table.anon_type(kind))
}

View File

@@ -22,6 +22,8 @@ pub enum TypeKind {
Adt(Adt),
/// A reference to an already-defined type: &T
Ref(Handle),
/// A raw pointer to an already-defined type: &T
Ptr(Handle),
/// A contiguous view of dynamically sized memory
Slice(Handle),
/// A contiguous view of statically sized memory
@@ -67,6 +69,7 @@ pub enum Primitive {
Integer, Float, // Inferred int and float
Bool, // boolean value
Char, // Unicode codepoint
Str, // UTF-8 string
}
#[rustfmt::skip]
@@ -117,6 +120,7 @@ impl FromStr for Primitive {
"fsize" => Primitive::Fsize,
"bool" => Primitive::Bool,
"char" => Primitive::Char,
"str" => Primitive::Str,
_ => Err(())?,
})
}

View File

@@ -14,6 +14,7 @@ impl Display for TypeKind {
TypeKind::Primitive(i) => i.fmt(f),
TypeKind::Adt(a) => a.fmt(f),
TypeKind::Ref(def) => write!(f, "&{def}"),
TypeKind::Ptr(def) => write!(f, "*{def}"),
TypeKind::Slice(def) => write!(f, "slice [#{def}]"),
TypeKind::Array(def, size) => write!(f, "array [#{def}; {size}]"),
TypeKind::Tuple(defs) => {
@@ -92,6 +93,7 @@ impl Display for Primitive {
Primitive::Float => f.write_str("{float}"),
Primitive::Bool => f.write_str("bool"),
Primitive::Char => f.write_str("char"),
Primitive::Str => f.write_str("str"),
}
}
}