iter 22b.4a.4.5: form-a printer+parser arms for Type::Forall constraints
This commit is contained in:
@@ -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> {
|
||||
|
||||
Reference in New Issue
Block a user