@@ -799,7 +799,7 @@ object IfBodyHelpers {
799
799
final case class MatchTuple (
800
800
scrutinee : Term ,
801
801
arity : Int ,
802
- fields : List [Int -> Var ]
802
+ fields : List [Str -> Var ]
803
803
) extends Condition
804
804
final case class BooleanTest (test : Term ) extends Condition
805
805
}
@@ -904,7 +904,8 @@ object IfBodyHelpers {
904
904
abstract class MutCaseOf {
905
905
def merge
906
906
(branch : Ls [IfBodyHelpers .Condition ] -> Term )
907
- (implicit raise : Diagnostic => Unit , allowDuplicate : Boolean = false ): Unit
907
+ (implicit raise : Diagnostic => Unit ): Unit
908
+ def mergeDefault (default : Term ): Unit
908
909
def toTerm : Term
909
910
}
910
911
@@ -1008,11 +1009,10 @@ object MutCaseOf {
1008
1009
1009
1010
// A short-hand for pattern matchings with only true and false branches.
1010
1011
final case class IfThenElse (condition : Term , var whenTrue : MutCaseOf , var whenFalse : MutCaseOf ) extends MutCaseOf {
1011
- override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit , allowDuplicate : Bool ): Unit =
1012
+ override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit ): Unit =
1012
1013
branch match {
1013
1014
case Nil -> term =>
1014
1015
whenFalse match {
1015
- case Consequent (_) if allowDuplicate => ()
1016
1016
case Consequent (_) =>
1017
1017
raise(WarningReport (Message .fromStr(" duplicated else branch" ) -> N :: Nil ))
1018
1018
case MissingCase => whenFalse = Consequent (term)
@@ -1035,14 +1035,23 @@ object MutCaseOf {
1035
1035
case _ => whenFalse.merge(branch)
1036
1036
}
1037
1037
}
1038
+
1039
+ override def mergeDefault (default : Term ): Unit = {
1040
+ whenTrue.mergeDefault(default)
1041
+ whenFalse match {
1042
+ case MissingCase => whenFalse = Consequent (default)
1043
+ case _ => whenFalse.mergeDefault(default)
1044
+ }
1045
+ }
1046
+
1038
1047
override def toTerm : Term = {
1039
1048
val falseBranch = Wildcard (whenFalse.toTerm)
1040
1049
val trueBranch = Case (Var (" true" ), whenTrue.toTerm, falseBranch)
1041
1050
CaseOf (condition, trueBranch)
1042
1051
}
1043
1052
}
1044
1053
final case class Match (scrutinee : Term , val branches : Buffer [Branch ]) extends MutCaseOf {
1045
- override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit , allowDuplicate : Bool ): Unit = {
1054
+ override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit ): Unit = {
1046
1055
branch match {
1047
1056
case (Condition .MatchClass (scrutinee2, className, fields) :: tail) -> term if scrutinee2 === scrutinee =>
1048
1057
branches.find(_.matches(className)) match {
@@ -1054,25 +1063,16 @@ object MutCaseOf {
1054
1063
branch.consequent.merge(tail -> term)
1055
1064
}
1056
1065
case (Condition .MatchTuple (scrutinee2, arity, fields) :: tail) -> term if scrutinee2 === scrutinee =>
1057
- val tupleClassName = Var (s " Tuple# $arity" )
1058
- val indexFields = fields.map { case (index, alias) => index.toString -> alias }
1066
+ val tupleClassName = Var (s " Tuple# $arity" ) // TODO: Find a name known by Typer.
1059
1067
branches.find(_.matches(tupleClassName)) match {
1060
1068
case N =>
1061
- branches += Branch (S (tupleClassName -> Buffer .from(indexFields )), buildBranch(tail, term))
1069
+ branches += Branch (S (tupleClassName -> Buffer .from(fields )), buildBranch(tail, term))
1062
1070
case S (branch) =>
1063
- branch.addFields(indexFields )
1071
+ branch.addFields(fields )
1064
1072
branch.consequent.merge(tail -> term)
1065
1073
}
1066
1074
// A wild card case. We should propagate wildcard to every default positions.
1067
- case Nil -> term =>
1068
- var hasWildcard = false
1069
- branches.foreach {
1070
- case Branch (_, _ : Consequent | MissingCase ) => ()
1071
- case Branch (patternFields, consequent) =>
1072
- consequent.merge(branch)(implicitly, true )
1073
- hasWildcard &&= patternFields.isEmpty
1074
- }
1075
- if (! hasWildcard) branches += Branch (N , Consequent (term))
1075
+ case Nil -> term => mergeDefault(term)
1076
1076
case conditions -> term =>
1077
1077
// Locate the wildcard case.
1078
1078
branches.find(_.isWildcard) match {
@@ -1083,6 +1083,19 @@ object MutCaseOf {
1083
1083
}
1084
1084
}
1085
1085
}
1086
+
1087
+ override def mergeDefault (default : Term ): Unit = {
1088
+ var hasWildcard = false
1089
+ branches.foreach {
1090
+ case Branch (_, _ : Consequent | MissingCase ) => ()
1091
+ case Branch (patternFields, consequent) =>
1092
+ consequent.mergeDefault(default)
1093
+ hasWildcard &&= patternFields.isEmpty
1094
+ }
1095
+ // If this match doesn't have a default case, we make one.
1096
+ if (! hasWildcard) branches += Branch (N , Consequent (default))
1097
+ }
1098
+
1086
1099
override def toTerm : Term = {
1087
1100
def rec (xs : Ls [Branch ]): CaseBranches =
1088
1101
xs match {
@@ -1098,16 +1111,18 @@ object MutCaseOf {
1098
1111
}
1099
1112
}
1100
1113
final case class Consequent (term : Term ) extends MutCaseOf {
1101
- override def merge
1102
- (branch : Ls [Condition ] -> Term )
1103
- (implicit raise : Diagnostic => Unit , allowDuplicate : Bool ): Unit =
1114
+ override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit ): Unit =
1104
1115
raise(WarningReport (Message .fromStr(" duplicated branch" ) -> N :: Nil ))
1116
+
1117
+ override def mergeDefault (default : Term ): Unit = ()
1118
+
1105
1119
override def toTerm : Term = term
1106
1120
}
1107
1121
final case object MissingCase extends MutCaseOf {
1108
- override def merge
1109
- (branch : Ls [Condition ] -> Term )
1110
- (implicit raise : Diagnostic => Unit , allowDuplicate : Bool ): Unit = ???
1122
+ override def merge (branch : Ls [Condition ] -> Term )(implicit raise : Diagnostic => Unit ): Unit = ???
1123
+
1124
+ override def mergeDefault (default : Term ): Unit = ()
1125
+
1111
1126
override def toTerm : Term =
1112
1127
throw new IfDesugaringException (" missing a default branch" )
1113
1128
}
0 commit comments