From 6fdb212b9d5268633373312c25d61f324f86179c Mon Sep 17 00:00:00 2001 From: Yann Hamdaoui Date: Wed, 14 Feb 2024 09:40:55 +0100 Subject: [PATCH] Implement compilation of enum patterns --- core/src/term/pattern/compile.rs | 62 ++++++++++++++++++++++++++++++-- 1 file changed, 60 insertions(+), 2 deletions(-) diff --git a/core/src/term/pattern/compile.rs b/core/src/term/pattern/compile.rs index db3a696de4..7d7a651e4a 100644 --- a/core/src/term/pattern/compile.rs +++ b/core/src/term/pattern/compile.rs @@ -376,8 +376,66 @@ impl CompilePart for RecordPattern { } impl CompilePart for EnumPattern { - fn compile_part(&self, _value_id: LocIdent, _bindings_id: LocIdent) -> RichTerm { - todo!() + fn compile_part(&self, value_id: LocIdent, bindings_id: LocIdent) -> RichTerm { + // %enum_get_tag% value_id == ' + let tag_matches = make::op2( + BinaryOp::Eq(), + make::op1(UnaryOp::EnumGetTag(), Term::Var(value_id)), + Term::Enum(self.tag), + ); + + if let Some(pat) = &self.pattern { + // if %enum_is_variant% value_id && %enum_get_tag% value_id == ' then + // let value_id = %enum_unwrap_variant% value_id in + // + // else + // null + + // %enum_is_variant% value_id && + let if_condition = mk_app!( + make::op1( + UnaryOp::BoolAnd(), + make::op1(UnaryOp::EnumIsVariant(), Term::Var(value_id)), + ), + tag_matches + ); + + make::if_then_else( + if_condition, + make::let_in( + value_id, + make::op1(UnaryOp::EnumUnwrapVariant(), Term::Var(value_id)), + pat.compile_part(value_id, bindings_id), + ), + Term::Null, + ) + } else { + // if %typeof% value_id == 'Enum && !(%enum_is_variant% value_id) && then + // bindings_id + // else + // null + + // %typeof% value_id == 'Enum + let is_enum = make::op2( + BinaryOp::Eq(), + make::op1(UnaryOp::Typeof(), Term::Var(value_id)), + Term::Enum("Enum".into()), + ); + + // !(%enum_is_variant% value_id) + let is_enum_tag = make::op1( + UnaryOp::BoolNot(), + make::op1(UnaryOp::EnumIsVariant(), Term::Var(value_id)), + ); + + // && && + let if_condition = mk_app!( + make::op1(UnaryOp::BoolAnd(), is_enum,), + mk_app!(make::op1(UnaryOp::BoolAnd(), is_enum_tag,), tag_matches) + ); + + make::if_then_else(if_condition, Term::Var(bindings_id), Term::Null) + } } }