Merge remote-tracking branch 'origin/trunk' into builtins-in-roc

This commit is contained in:
Folkert 2022-04-08 15:47:11 +02:00
commit 1d0f9e9192
No known key found for this signature in database
GPG key ID: 1F17F6FFD112B97C
178 changed files with 5342 additions and 3304 deletions

View file

@ -273,17 +273,13 @@ pub enum Has<'a> {
/// An ability demand is a value defining the ability; for example `hash : a -> U64 | a has Hash`
/// for a `Hash` ability.
#[derive(Debug, Clone, Copy, PartialEq)]
pub struct AbilityDemand<'a> {
pub struct AbilityMember<'a> {
pub name: Loc<Spaced<'a, &'a str>>,
pub typ: Loc<TypeAnnotation<'a>>,
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Def<'a> {
// TODO in canonicalization, validate the pattern; only certain patterns
// are allowed in annotations.
Annotation(Loc<Pattern<'a>>, Loc<TypeAnnotation<'a>>),
pub enum TypeDef<'a> {
/// A type alias. This is like a standalone annotation, except the pattern
/// must be a capitalized Identifier, e.g.
///
@ -305,8 +301,15 @@ pub enum Def<'a> {
Ability {
header: TypeHeader<'a>,
loc_has: Loc<Has<'a>>,
demands: &'a [AbilityDemand<'a>],
members: &'a [AbilityMember<'a>],
},
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum ValueDef<'a> {
// TODO in canonicalization, validate the pattern; only certain patterns
// are allowed in annotations.
Annotation(Loc<Pattern<'a>>, Loc<TypeAnnotation<'a>>),
// TODO in canonicalization, check to see if there are any newlines after the
// annotation; if not, and if it's followed by a Body, then the annotation
@ -323,6 +326,12 @@ pub enum Def<'a> {
},
Expect(&'a Loc<Expr<'a>>),
}
#[derive(Debug, Clone, Copy, PartialEq)]
pub enum Def<'a> {
Type(TypeDef<'a>),
Value(ValueDef<'a>),
// Blank Space (e.g. comments, spaces, newlines) before or after a def.
// We preserve this for the formatter; canonicalization ignores it.
@ -341,6 +350,30 @@ impl<'a> Def<'a> {
debug_assert!(!matches!(def, Def::SpaceBefore(_, _)));
(spaces, def)
}
pub fn unroll_def(&self) -> Result<&TypeDef<'a>, &ValueDef<'a>> {
let mut def = self;
loop {
match def {
Def::Type(type_def) => return Ok(type_def),
Def::Value(value_def) => return Err(value_def),
Def::SpaceBefore(def1, _) | Def::SpaceAfter(def1, _) => def = def1,
Def::NotYetImplemented(s) => todo!("{}", s),
}
}
}
}
impl<'a> From<TypeDef<'a>> for Def<'a> {
fn from(def: TypeDef<'a>) -> Self {
Self::Type(def)
}
}
impl<'a> From<ValueDef<'a>> for Def<'a> {
fn from(def: ValueDef<'a>) -> Self {
Self::Value(def)
}
}
#[derive(Debug, Copy, Clone, PartialEq)]