@@ -10,7 +10,7 @@ import utils.*
10
10
11
11
import hkmc2 .Message .MessageContext
12
12
13
- import semantics .*
13
+ import semantics .* , ucs . FlatPattern
14
14
import hkmc2 .{semantics => sem }
15
15
import semantics .{Term => st }
16
16
import semantics .Term .{Throw => _ , * }
@@ -184,7 +184,9 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
184
184
blockImpl(stats, res)(k)
185
185
case cls : ClassLikeDef =>
186
186
reportAnnotations(cls, cls.extraAnnotations)
187
- val (mtds, publicFlds, privateFlds, ctor) = gatherMembers(cls.body)
187
+ val (mtds, publicFlds, privateFlds, ctor) = cls match
188
+ case pd : PatternDef => compilePatternMethods(pd)
189
+ case _ => gatherMembers(cls.body)
188
190
cls.ext match
189
191
case N =>
190
192
Define (ClsLikeDefn (cls.owner, cls.sym, cls.bsym, cls.kind, cls.paramsOpt, cls.auxParams, N ,
@@ -341,7 +343,9 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
341
343
case _ : sem.BuiltinSymbol => true
342
344
case sym : sem.BlockMemberSymbol =>
343
345
sym.trmImplTree.fold(sym.clsTree.isDefined)(_.k is syntax.Fun )
344
- case _ => false
346
+ // Do not perform safety check on `MatchResult` and `MatchFailure`.
347
+ case sym => (sym is State .matchResultClsSymbol) ||
348
+ (sym is State .matchFailureClsSymbol)
345
349
def conclude (fr : Path ) =
346
350
arg match
347
351
case Tup (fs) =>
@@ -506,8 +510,8 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
506
510
End ()
507
511
)
508
512
pat match
509
- case Pattern .Lit (lit) => mkMatch(Case .Lit (lit) -> go(tail, topLevel = false ))
510
- case Pattern .ClassLike (ctor, argsOpt, _mode, _refined) =>
513
+ case FlatPattern .Lit (lit) => mkMatch(Case .Lit (lit) -> go(tail, topLevel = false ))
514
+ case FlatPattern .ClassLike (ctor, argsOpt, _mode, _refined) =>
511
515
/** Make a continuation that creates the match. */
512
516
def k (ctorSym : ClassLikeSymbol , clsParams : Ls [TermSymbol ])(st : Path ): Block =
513
517
val args = argsOpt.map(_.map(_.scrutinee)).getOrElse(Nil )
@@ -537,8 +541,8 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
537
541
// resolves to a class or module. Branches with unresolved
538
542
// constructors should have been removed.
539
543
lastWords(" Pattern.ClassLike: constructor is neither a class nor a module" )
540
- case Pattern .Tuple (len, inf) => mkMatch(Case .Tup (len, inf) -> go(tail, topLevel = false ))
541
- case Pattern .Record (entries) =>
544
+ case FlatPattern .Tuple (len, inf) => mkMatch(Case .Tup (len, inf) -> go(tail, topLevel = false ))
545
+ case FlatPattern .Record (entries) =>
542
546
val objectSym = ctx.builtins.Object
543
547
mkMatch( // checking that we have an object
544
548
Case .Cls (objectSym, Value .Ref (BuiltinSymbol (objectSym.nme, false , false , true , false ))),
@@ -565,7 +569,7 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
565
569
val normalized = tl.scoped(" ucs:normalize" ):
566
570
normalize(iftrm.desugared)
567
571
tl.scoped(" ucs:normalized" ):
568
- tl.log(s " Normalized: \n ${Split .display( normalized) }" )
572
+ tl.log(s " Normalized: \n ${normalized.prettyPrint }" )
569
573
570
574
if k.isInstanceOf [TailOp ] && isIf then go(normalized, topLevel = true )
571
575
else
@@ -683,8 +687,8 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
683
687
def setupSymbol (symbol : Local )(k : Result => Block )(using Subst ): Block =
684
688
k(Instantiate (mut = false , Value .Ref (State .termSymbol).selSN(" Symbol" ), Value .Lit (Tree .StrLit (symbol.nme)) :: Nil ))
685
689
686
- def quotePattern (p : Pattern )(k : Result => Block )(using Subst ): Block = p match
687
- case Pattern .Lit (lit) => setupTerm(" LitPattern" , Value .Lit (lit) :: Nil )(k)
690
+ def quotePattern (p : FlatPattern )(k : Result => Block )(using Subst ): Block = p match
691
+ case FlatPattern .Lit (lit) => setupTerm(" LitPattern" , Value .Lit (lit) :: Nil )(k)
688
692
case _ => // TODO
689
693
fail :
690
694
ErrorReport (
@@ -819,6 +823,21 @@ class Lowering()(using Config, TL, Raise, State, Ctx):
819
823
case t => t
820
824
(mtds, publicFlds, privateFlds, ctor)
821
825
826
+ /** Compile the pattern definition into `unapply` and `unapplyStringPrefix`
827
+ * methods using the `NaiveCompiler`, which transliterate the pattern into
828
+ * UCS splits that backtrack without any optimizations. */
829
+ def compilePatternMethods (defn : PatternDef )(using Subst ):
830
+ // The return type is intended to be consistent with `gatherMembers`
831
+ (Ls [FunDefn ], Ls [BlockMemberSymbol -> TermSymbol ], Ls [TermSymbol ], Block ) =
832
+ val compiler = new ups.NaiveCompiler
833
+ val methods = compiler.compilePattern(defn)
834
+ val mtds = methods
835
+ .flatMap: td =>
836
+ td.body.map: bod =>
837
+ val (paramLists, bodyBlock) = setupFunctionDef(td.params, bod, S (td.sym.nme))
838
+ FunDefn (td.owner, td.sym, paramLists, bodyBlock)
839
+ (mtds, Nil , Nil , End ())
840
+
822
841
def args (elems : Ls [Elem ])(k : Ls [Arg ] => Block )(using Subst ): Block =
823
842
val as = elems.map:
824
843
case sem.Fld (sem.FldFlags .benign(), value, N ) => R (N -> value)
0 commit comments