From 161d0430c2fcb90bea3c950e51b850b49154ab0a Mon Sep 17 00:00:00 2001 From: Michelle Date: Wed, 19 Jan 2022 13:22:12 -0500 Subject: [PATCH] PROM-12572: updating AST (#6) Co-authored-by: Chan, Michelle <6752211+michelchan@users.noreply.github.com> --- .../scala/zio/morphir/sexpr/ast/ast.scala | 70 ++++++++++++------- 1 file changed, 45 insertions(+), 25 deletions(-) diff --git a/zio-morphir-sexpr/shared/src/main/scala/zio/morphir/sexpr/ast/ast.scala b/zio-morphir-sexpr/shared/src/main/scala/zio/morphir/sexpr/ast/ast.scala index 67b3f9bd..700c8ea9 100644 --- a/zio-morphir-sexpr/shared/src/main/scala/zio/morphir/sexpr/ast/ast.scala +++ b/zio-morphir-sexpr/shared/src/main/scala/zio/morphir/sexpr/ast/ast.scala @@ -8,13 +8,17 @@ sealed trait SExpr { self => def $case: SExprCase[SExpr] def fold[Z](f: SExprCase[Z] => Z): Z = self.$case match { - case c @ BoolCase(_) => f(c) - case c @ StrCase(_) => f(c) - case c @ NumCase(_) => f(c) - case NilCase => f(NilCase) - case ConsCase(car, cdr) => f(ConsCase(car.fold(f), cdr.fold(f))) - case QuotedCase(value) => f(QuotedCase(value.fold(f))) - case VectorCase(items) => f(VectorCase(items.map(_.fold(f)))) + case c @ BoolCase(_) => f(c) + case c @ StrCase(_) => f(c) + case c @ NumCase(_) => f(c) + case MapCase(items) => + f(MapCase(items.map { case (k, v) => + (k.fold(f), v.fold(f)) + })) + case NilCase => f(NilCase) + case ConsCase(head, tail) => f(ConsCase(head.fold(f), tail.fold(f))) + case QuotedCase(get) => f(QuotedCase(get.fold(f))) + case VectorCase(items) => f(VectorCase(items.map(_.fold(f)))) } final def widen: SExpr = this @@ -43,6 +47,15 @@ object SExpr { } } + final case class SMap private[sexpr] ($case: VectorCase[SExpr]) extends SExpr + object SMap { + def apply(items: Map[SExpr, SExpr]): SMap = SMap(items) + def unapply(arg: SExpr): Option[Map[SExpr, SExpr]] = arg.$case match { + case MapCase(items: Map[SExpr, SExpr]) => Some(items) + case _ => None + } + } + case object Nil extends SExpr { val $case = NilCase } @@ -75,34 +88,41 @@ object SExpr { } } -sealed trait SExprCase[+A] { self => +sealed trait SExprCase[+Self] { self => import SExprCase._ - def map[B](f: A => B): SExprCase[B] = self match { - case BoolCase(value) => BoolCase(value) - case ConsCase(car, cdr) => ConsCase(f(car), f(cdr)) - case StrCase(value) => StrCase(value) - case NilCase => NilCase - case NumCase(value) => NumCase(value) - case QuotedCase(value) => QuotedCase(f(value)) - case VectorCase(items) => VectorCase(items.map(f)) + def map[B](f: Self => B): SExprCase[B] = self match { + case BoolCase(value) => BoolCase(value) + case ConsCase(head, tail) => ConsCase(f(head), f(tail)) + case StrCase(value) => StrCase(value) + case MapCase(items) => + MapCase(items.map { case (k, v) => + (f(k), f(v)) + }) + case NilCase => NilCase + case NumCase(value) => NumCase(value) + case QuotedCase(get) => QuotedCase(f(get)) + case VectorCase(items) => VectorCase(items.map(f)) } -} +} object SExprCase { - sealed trait AtomCase[+A] extends SExprCase[A] - sealed trait CollectionCase[+A] extends SExprCase[A] - sealed trait ListCase[+A] extends CollectionCase[A] - sealed trait SymbolCase[+A] extends AtomCase[A] + sealed trait AtomCase[+Self] extends SExprCase[Self] + sealed trait CollectionCase[+Self] extends SExprCase[Self] + sealed trait ListCase[+Self] extends CollectionCase[Self] + sealed trait SymbolBaseCase[+Self] extends AtomCase[Self] // Leaf Cases - final case class BoolCase(value: Boolean) extends SymbolCase[Nothing] + final case class BoolCase(value: Boolean) extends SymbolBaseCase[Nothing] final case class StrCase(value: String) extends AtomCase[Nothing] final case class NumCase(value: java.math.BigDecimal) extends AtomCase[Nothing] case object NilCase extends ListCase[Nothing] + final case class SymbolCase(value: String) extends SymbolBaseCase[Nothing] // Recursive Cases - final case class ConsCase[+A](car: A, cdr: A) extends ListCase[A] - final case class QuotedCase[+A](value: A) extends SExprCase[A] - final case class VectorCase[+A](items: Chunk[A]) extends CollectionCase[A] + final case class ConsCase[+Self](head: Self, tail: Self) extends ListCase[Self] + final case class MapCase[Self](items: Map[Self, Self]) extends CollectionCase[Self] + final case class QuotedCase[+Self](get: Self) extends SExprCase[Self] + final case class VectorCase[+Self](items: Chunk[Self]) extends CollectionCase[Self] + }