Skip to content

Commit

Permalink
Engine: Use enum and variant svalues' enum and variant s rank (digita…
Browse files Browse the repository at this point in the history
…l-asset#5068)

CHANGELOG_BEGIN
CHANGELOG_END

We use the rank recently introduced in the enum and variant svalues for:
* pattern matchin
* value hashCode
* value ordering (so the oredering match the DAML-LF spec)
* value equality
  • Loading branch information
remyhaemmerle-da authored Mar 18, 2020
1 parent 7b9932a commit 3cbba8a
Showing 7 changed files with 31 additions and 22 deletions.
Original file line number Diff line number Diff line change
@@ -382,12 +382,22 @@ final case class Compiler(packages: PackageId PartialFunction Package) {
case CaseAlt(pat, expr) =>
pat match {
case CPVariant(tycon, variant, binder) =>
val variantDef = lookupVariantDefinition(tycon).getOrElse(
throw CompileError(s"variant $tycon not found"))
withBinders(binder) { _ =>
SCaseAlt(SCPVariant(tycon, variant), translate(expr))
SCaseAlt(
SCPVariant(tycon, variant, variantDef.constructorRank(variant)),
translate(expr),
)
}

case CPEnum(tycon, constructor) =>
SCaseAlt(SCPEnum(tycon, constructor), translate(expr))
val enumDef = lookupEnumDefinition(tycon).getOrElse(
throw CompileError(s"enum $tycon not found"))
SCaseAlt(
SCPEnum(tycon, constructor, enumDef.constructorRank(constructor)),
translate(expr),
)

case CPNil =>
SCaseAlt(SCPNil, translate(expr))
Original file line number Diff line number Diff line change
@@ -452,9 +452,9 @@ object Pretty {
case SCPNil => (text("nil"), index)
case SCPCons => (text("cons"), index + 2)
case SCPDefault => (text("default"), index)
case SCPVariant(_, v) =>
case SCPVariant(_, v, _) =>
(text("var") + char('(') + str(v) + char(')'), index + 1)
case SCPEnum(_, v) =>
case SCPEnum(_, v, _) =>
(text("enum") + char('(') + str(v) + char(')'), index)
case SCPPrimCon(pc) =>
pc match {
Original file line number Diff line number Diff line change
@@ -217,10 +217,10 @@ object SExpr {
sealed trait SCasePat

/** Match on a variant. On match the value is unboxed and pushed to environment. */
final case class SCPVariant(id: Identifier, variant: Name) extends SCasePat
final case class SCPVariant(id: Identifier, variant: Name, constructorRank: Int) extends SCasePat

/** Match on a variant. On match the value is unboxed and pushed to environment. */
final case class SCPEnum(id: Identifier, constructor: Name) extends SCasePat
final case class SCPEnum(id: Identifier, constructor: Name, constructorRank: Int) extends SCasePat

/** Match on a primitive constructor, that is on true, false or unit. */
final case class SCPPrimCon(pc: PrimCon) extends SCasePat
Original file line number Diff line number Diff line change
@@ -477,22 +477,21 @@ object Speedy {
case _ => false
}
}
case SVariant(_, con1, _, arg) =>
case SVariant(_, _, rank1, arg) =>
alts.find { alt =>
alt.pattern match {
case SCPVariant(_, con2) if con1 == con2 =>
case SCPVariant(_, _, rank2) if rank1 == rank2 =>
machine.kont.add(KPop(1))
machine.env.add(arg)
true
case SCPDefault => true
case _ => false
}
}
case SEnum(_, con1, _) =>
case SEnum(_, _, rank1) =>
alts.find { alt =>
alt.pattern match {
case SCPEnum(_, con2) =>
con1 == con2
case SCPEnum(_, _, rank2) => rank1 == rank2
case SCPDefault => true
case _ => false
}
Original file line number Diff line number Diff line change
@@ -32,13 +32,13 @@ private[lf] object Equality {
tuple match {
case (x: SPrimLit, y: SPrimLit) =>
x == y && equality(stack)
case (SEnum(tyCon1, con1, _), SEnum(tyCon2, con2, _)) =>
tyCon1 == tyCon2 && con1 == con2 && equality(stack)
case (SEnum(tyCon1, _, rank1), SEnum(tyCon2, _, rank2)) =>
tyCon1 == tyCon2 && rank1 == rank2 && equality(stack)
case (SRecord(tyCon1, fields1, args1), SRecord(tyCon2, fields2, args2)) =>
tyCon1 == tyCon2 && (fields1 sameElements fields2) &&
equality(zipAndPush(args1.iterator().asScala, args2.iterator().asScala, stack))
case (SVariant(tyCon1, con1, _, arg1), SVariant(tyCon2, con2, _, arg2)) =>
tyCon1 == tyCon2 && con1 == con2 && equality((arg1, arg2) +: stack)
case (SVariant(tyCon1, _, rank1, arg1), SVariant(tyCon2, _, rank2, arg2)) =>
tyCon1 == tyCon2 && rank1 == rank2 && equality((arg1, arg2) +: stack)
case (SList(lst1), SList(lst2)) =>
lst1.length == lst2.length &&
equality(zipAndPush(lst1.iterator, lst2.iterator, stack))
Original file line number Diff line number Diff line change
@@ -64,12 +64,12 @@ private[speedy] object Hasher {
loop(cmdsRest, cid.hashCode :: stack)
case STypeRep(t) =>
loop(cmdsRest, t.hashCode() :: stack)
case SEnum(_, constructor, _) =>
loop(cmdsRest, constructor.hashCode :: stack)
case SEnum(_, _, rank) =>
loop(cmdsRest, rank :: stack)
case SRecord(_, _, values) =>
loop(pushOrderedValues(values.size, values.iterator().asScala, cmdsRest), stack)
case SVariant(_, variant, _, value) =>
loop(Value(value) :: Mix(variant.hashCode) :: cmdsRest, stack)
case SVariant(_, _, rank, value) =>
loop(Value(value) :: Mix(rank) :: cmdsRest, stack)
case SStruct(_, values) =>
loop(pushOrderedValues(values.size, values.iterator().asScala, cmdsRest), stack)
case SOptional(opt) =>
Original file line number Diff line number Diff line change
@@ -199,11 +199,11 @@ object Ordering extends scala.math.Ordering[SValue] {
case SRecord(_, _, args2) =>
0 -> (args1.iterator().asScala zip args2.iterator().asScala).to[ImmArray]
}
case SVariant(_, con1, _, arg1) => {
case SVariant(_, con2, _, arg2) =>
case SVariant(_, _, rank1, arg1) => {
case SVariant(_, _, rank2, arg2) =>
// FIXME https://github.com/digital-asset/daml/issues/2256
// should not compare constructor syntactically
(con1 compareTo con2) -> ImmArray((arg1, arg2))
(rank1 compareTo rank2) -> ImmArray((arg1, arg2))
}
case SList(FrontStack()) => {
case SList(l2) =>

0 comments on commit 3cbba8a

Please sign in to comment.