iter 22b.4a.4.5: form-a printer+parser arms for Type::Forall constraints

This commit is contained in:
2026-05-09 22:23:10 +02:00
parent 5852833241
commit 2a2e6b9817
2 changed files with 94 additions and 5 deletions
+36 -2
View File
@@ -85,7 +85,7 @@
//! [`ailang_core::ast::Import::alias`].
use ailang_core::ast::{
Arm, ClassDef, ClassMethod, ConstDef, Ctor, Def, FnDef, Import, InstanceDef,
Arm, ClassDef, ClassMethod, Constraint, ConstDef, Ctor, Def, FnDef, Import, InstanceDef,
InstanceMethod, Literal, Module, ParamMode, Pattern, SuperclassRef, Suppress, Term,
Type, TypeDef,
};
@@ -1149,15 +1149,49 @@ impl<'a> Parser<'a> {
vars.push(self.expect_ident("type variable")?);
}
self.expect_rparen("forall vars")?;
// optional (constraints (constraint <Class> <type>)+ )
let constraints = if let Some("constraints") = self.peek_head_ident() {
self.parse_forall_constraints_clause()?
} else {
Vec::new()
};
let body = self.parse_type()?;
self.expect_rparen("forall-type")?;
Ok(Type::Forall {
vars,
constraints: vec![],
constraints,
body: Box::new(body),
})
}
fn parse_forall_constraints_clause(&mut self) -> Result<Vec<Constraint>, ParseError> {
self.expect_lparen("forall.constraints")?;
self.expect_keyword("constraints")?;
let mut out = Vec::new();
while !matches!(self.peek(), Some(Token { tok: Tok::RParen, .. })) {
out.push(self.parse_constraint()?);
}
if out.is_empty() {
let pos = self.peek().map(|t| t.span.start).unwrap_or(0);
return Err(ParseError::Production {
production: "forall.constraints",
message: "(constraints …) clause must contain at least one (constraint …)".into(),
pos,
});
}
self.expect_rparen("forall.constraints")?;
Ok(out)
}
fn parse_constraint(&mut self) -> Result<Constraint, ParseError> {
self.expect_lparen("constraint")?;
self.expect_keyword("constraint")?;
let class = self.expect_ident("constraint class name")?;
let type_ = self.parse_type()?;
self.expect_rparen("constraint")?;
Ok(Constraint { class, type_ })
}
// ---- terms ----------------------------------------------------------
fn parse_term(&mut self) -> Result<Term, ParseError> {