From d35daf61cefe80eeed989827fe975bfaca0c47f9 Mon Sep 17 00:00:00 2001 From: Bor-Yuh Evan Chang Date: Fri, 28 Apr 2017 17:12:18 -0600 Subject: [PATCH 1/3] Add a module representing memory --- build.sbt | 1 + project/Dependencies.scala | 1 + .../plv/cuanto/jsy/mutation/mem/Mem.scala | 40 +++++++++++++++++++ .../plv/cuanto/jsy/mutation/package.scala | 6 +-- 4 files changed, 43 insertions(+), 5 deletions(-) create mode 100644 src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala diff --git a/build.sbt b/build.sbt index 060ed5f..c354fde 100644 --- a/build.sbt +++ b/build.sbt @@ -52,6 +52,7 @@ lazy val root = (project in file(".")). // Dependencies libraryDependencies ++= Seq( scalaParserCombinators, + cats, scalaTest % Test, scalaCheck % Test ), diff --git a/project/Dependencies.scala b/project/Dependencies.scala index 0dd0694..bebd634 100644 --- a/project/Dependencies.scala +++ b/project/Dependencies.scala @@ -4,4 +4,5 @@ object Dependencies { lazy val scalaTest = "org.scalatest" %% "scalatest" % "3.0.1" lazy val scalaCheck = "org.scalacheck" %% "scalacheck" % "1.13.4" lazy val scalaParserCombinators = "org.scala-lang.modules" %% "scala-parser-combinators" % "1.0.5" + lazy val cats = "org.typelevel" %% "cats" % "0.9.0" } diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala new file mode 100644 index 0000000..7462b78 --- /dev/null +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala @@ -0,0 +1,40 @@ +package edu.colorado.plv.cuanto.jsy +package mutation.mem + +import cats.data.State + +/** Address. + * + * @group Intermediate AST Nodes + */ +case class A private[mem] (a: Int) extends Val + +/** Memory. + * + * Memory is a mapping from addresses to values. It enforces the invariant that + * addresses are allocated in this module. + * + * @author Bor-Yuh Evan Chang + */ +class Mem private[mem](map: Map[A, Expr], nextAddr: Int) { + def apply(key: A): Expr = map(key) + def get(key: A): Option[Expr] = map.get(key) + def +(kv: (A, Expr)): Mem = new Mem(map + kv, nextAddr) + def contains(key: A): Boolean = map.contains(key) + override def toString: String = map.toString + + private[Mem] def alloc(v: Expr): (Mem, A) = { + val fresha = A(nextAddr) + (new Mem(map + (fresha -> v), nextAddr + 1), fresha) + } +} + +object Mem { + val empty: Mem = new Mem(Map.empty, 1) + + /** Get a fresh address. */ + def alloc(v: Expr): State[Mem, A] = State.get flatMap { m => + val (mp, a) = m.alloc(v) + State.set(mp) map { _ => a } + } +} diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala index 1e9cd0d..86fa2e5 100644 --- a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala @@ -11,11 +11,7 @@ package mutation { /** @group Intermediate AST Nodes */ case object Deref extends Uop - /** Address. - * - * @group Intermediate AST Nodes - */ - case class A private (a: Int) extends Val + } From 90b42ead612ab1fce0adfb1ca204eba950bcde5e Mon Sep 17 00:00:00 2001 From: Bor-Yuh Evan Chang Date: Fri, 28 Apr 2017 17:17:40 -0600 Subject: [PATCH 2/3] Clean up package modifier --- .../edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala | 6 +++--- .../edu/colorado/plv/cuanto/jsy/mutation/package.scala | 2 -- 2 files changed, 3 insertions(+), 5 deletions(-) diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala index 7462b78..a7c6139 100644 --- a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/mem/Mem.scala @@ -7,7 +7,7 @@ import cats.data.State * * @group Intermediate AST Nodes */ -case class A private[mem] (a: Int) extends Val +case class A private (a: Int) extends Val /** Memory. * @@ -16,14 +16,14 @@ case class A private[mem] (a: Int) extends Val * * @author Bor-Yuh Evan Chang */ -class Mem private[mem](map: Map[A, Expr], nextAddr: Int) { +class Mem private (map: Map[A, Expr], nextAddr: Int) { def apply(key: A): Expr = map(key) def get(key: A): Option[Expr] = map.get(key) def +(kv: (A, Expr)): Mem = new Mem(map + kv, nextAddr) def contains(key: A): Boolean = map.contains(key) override def toString: String = map.toString - private[Mem] def alloc(v: Expr): (Mem, A) = { + private def alloc(v: Expr): (Mem, A) = { val fresha = A(nextAddr) (new Mem(map + (fresha -> v), nextAddr + 1), fresha) } diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala index 86fa2e5..7b8957b 100644 --- a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/package.scala @@ -11,8 +11,6 @@ package mutation { /** @group Intermediate AST Nodes */ case object Deref extends Uop - - } From 7070ff9ee232080e282c57e0a93d76caf572d30a Mon Sep 17 00:00:00 2001 From: Bor-Yuh Evan Chang Date: Fri, 12 May 2017 18:34:13 -0400 Subject: [PATCH 3/3] Set up parsing of imp --- .../colorado/plv/cuanto/jsy/imp/Parser.scala | 6 ++++ .../colorado/plv/cuanto/jsy/imp/package.scala | 21 +++++++++++ .../plv/cuanto/jsy/mutation/Parser.scala | 21 +++++------ .../plv/cuanto/jsy/string/package.scala | 2 +- .../plv/cuanto/jsy/imp/ImpParserSpec.scala | 35 +++++++++++++++++++ .../jsy/mutation/MutationParserSpec.scala | 16 --------- 6 files changed, 74 insertions(+), 27 deletions(-) create mode 100644 src/main/scala/edu/colorado/plv/cuanto/jsy/imp/Parser.scala create mode 100644 src/main/scala/edu/colorado/plv/cuanto/jsy/imp/package.scala create mode 100644 src/test/scala/edu/colorado/plv/cuanto/jsy/imp/ImpParserSpec.scala delete mode 100644 src/test/scala/edu/colorado/plv/cuanto/jsy/mutation/MutationParserSpec.scala diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/Parser.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/Parser.scala new file mode 100644 index 0000000..282ce5a --- /dev/null +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/Parser.scala @@ -0,0 +1,6 @@ +package edu.colorado.plv.cuanto.jsy.imp + +import edu.colorado.plv.cuanto.jsy.common.UnitOpParser +import edu.colorado.plv.cuanto.jsy.{mutation, numerical} + +object Parser extends UnitOpParser with mutation.ParserLike with numerical.ParserWithBindingLike diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/package.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/package.scala new file mode 100644 index 0000000..738aa08 --- /dev/null +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/imp/package.scala @@ -0,0 +1,21 @@ +package edu.colorado.plv.cuanto.jsy + +import edu.colorado.plv.cuanto.jsy.binding.Mode + +package imp { + + /** Mode `var`. Mutable variables. + * + * @group Abstract Syntax Nodes + */ + case object MVar extends Mode + +} + +/** The Imp subset of JavaScripty. + * + * Mixes [[numerical]] and [[mutation]]. + * + * @author Bor-Yuh Evan Chang + */ +package object imp diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/Parser.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/Parser.scala index 0b18921..8cb1999 100644 --- a/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/Parser.scala +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/mutation/Parser.scala @@ -1,14 +1,15 @@ -package edu.colorado.plv.cuanto.jsy.mutation +package edu.colorado.plv.cuanto.jsy +package mutation -import edu.colorado.plv.cuanto.jsy.common.{JsyParserLike, OpParserLike, UnitOpParser} +import edu.colorado.plv.cuanto.jsy.common.{JsyParserLike, OpParserLike} -trait ParserLike extends OpParserLike with JsyParserLike +trait ParserLike extends OpParserLike with JsyParserLike { + abstract override def opAtom: Parser[Expr] = + positioned("null" ^^^ Null) | + super.opAtom -/** - * @author Bor-Yuh Evan Chang - */ -object Parser extends UnitOpParser with ParserLike { - override val bop = ??? - override def expr = ??? - override def start = ??? + lazy val mutationBop: OpPrecedence = List( + List("=" -> Assign) + ) } + diff --git a/src/main/scala/edu/colorado/plv/cuanto/jsy/string/package.scala b/src/main/scala/edu/colorado/plv/cuanto/jsy/string/package.scala index 19b9d17..22dcd7c 100644 --- a/src/main/scala/edu/colorado/plv/cuanto/jsy/string/package.scala +++ b/src/main/scala/edu/colorado/plv/cuanto/jsy/string/package.scala @@ -17,6 +17,6 @@ package object string { /** The string concatenation operator is syntactically overloaded as * [[edu.colorado.plv.cuanto.jsy.arithmetic.Plus]]. */ - val Concat: Bop = arithmetic.Plus + val Concat = arithmetic.Plus } diff --git a/src/test/scala/edu/colorado/plv/cuanto/jsy/imp/ImpParserSpec.scala b/src/test/scala/edu/colorado/plv/cuanto/jsy/imp/ImpParserSpec.scala new file mode 100644 index 0000000..a2bd3cd --- /dev/null +++ b/src/test/scala/edu/colorado/plv/cuanto/jsy/imp/ImpParserSpec.scala @@ -0,0 +1,35 @@ +package edu.colorado.plv.cuanto.jsy +package imp + +import edu.colorado.plv.cuanto.CuantoSpec +import edu.colorado.plv.cuanto.jsy.arithmetic.N +import edu.colorado.plv.cuanto.jsy.binding._ +import edu.colorado.plv.cuanto.jsy.boolean._ +import edu.colorado.plv.cuanto.jsy.common.ParserBehaviors +import edu.colorado.plv.cuanto.jsy.mutation.Assign + +/** + * @author Bor-Yuh Evan Chang + */ +class ImpParserSpec extends CuantoSpec with ParserBehaviors { + + override lazy val positives = Table( + "concrete" -> "abstract", + """{ let x = 3 + | var y = true + | if (y) { x = 4 } else { x = 5 } + |} + """.stripMargin + -> Bind(MVar, Var("x"), N(3), + Bind(MVar, Var("y"), B(true), + If(Var("y"), + Binary(Assign, Var("x"), N(4)), + Binary(Assign, Var("x"), N(4)) + ) + ) + ) + + ) + + "jsy.imp.Parser" should behave like parser(Parser.parse) +} \ No newline at end of file diff --git a/src/test/scala/edu/colorado/plv/cuanto/jsy/mutation/MutationParserSpec.scala b/src/test/scala/edu/colorado/plv/cuanto/jsy/mutation/MutationParserSpec.scala deleted file mode 100644 index 133ffc6..0000000 --- a/src/test/scala/edu/colorado/plv/cuanto/jsy/mutation/MutationParserSpec.scala +++ /dev/null @@ -1,16 +0,0 @@ -package edu.colorado.plv.cuanto.jsy.mutation - -import edu.colorado.plv.cuanto.CuantoSpec -import edu.colorado.plv.cuanto.jsy.common.ParserBehaviors - -/** - * @author Bor-Yuh Evan Chang - */ -class MutationParserSpec extends CuantoSpec with ParserBehaviors { - - override lazy val positives = Table( - "concrete" -> "abstract" - ) - - "jsy.objects.Parser" should behave like parser(Parser.parse) -} \ No newline at end of file