From fc2cdfbd1a6fa2ad5a9a86c8423a82bfa874aeb3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Konstantin=20L=C3=A4ufer?= Date: Sat, 30 Sep 2023 17:27:20 -0500 Subject: [PATCH] updated to newer Scala 3 syntax with fewer braces MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Signed-off-by: Konstantin Läufer --- src/main/scala/evaluate.scala | 48 ++++++++++------------------ src/test/scala/imperativeTests.scala | 23 +++++-------- src/test/scala/lawTests.scala | 3 +- 3 files changed, 26 insertions(+), 48 deletions(-) diff --git a/src/main/scala/evaluate.scala b/src/main/scala/evaluate.scala index 8e82f88..ea11fb7 100644 --- a/src/main/scala/evaluate.scala +++ b/src/main/scala/evaluate.scala @@ -53,11 +53,11 @@ object evaluate: /** Looks up a variable in memory. */ def lookup(store: Store)(name: String): Result = - store.get(name).fold { + store.get(name).fold( Failure(new NoSuchFieldException(name)): Result - } { + ) ( Success(_) - } + ) /** Evaluates the two operands and applies the operator. */ def binOp(left: Thunk, right: Thunk, op: (Int, Int) => Int): Result = @@ -73,45 +73,34 @@ object evaluate: * tree is achieved by plugging this F-algebra into the * universal catamorphism (generalized fold). */ - def evalAlgebra(store: Store): Algebra[ExprF, Thunk] = Algebra { - case Constant(value) => thunk { + def evalAlgebra(store: Store): Algebra[ExprF, Thunk] = Algebra: + case Constant(value) => thunk: Success(Cell(Num(value))) - } - case Plus(left, right) => thunk { + case Plus(left, right) => thunk: binOp(left, right, _ + _) - } - case Minus(left, right) => thunk { + case Minus(left, right) => thunk: binOp(left, right, _ - _) - } - case Times(left, right) => thunk { + case Times(left, right) => thunk: binOp(left, right, _ * _) - } - case Div(left, right) => thunk { + case Div(left, right) => thunk: binOp(left, right, _ / _) - } - case Mod(left, right) => thunk { + case Mod(left, right) => thunk: binOp(left, right, _ % _) - } - case UMinus(expr) => thunk { + case UMinus(expr) => thunk: for Cell(Num(e)) <- expr.eval yield Cell(Num(-e)) - } - case Variable(name) => thunk { + case Variable(name) => thunk: lookup(store)(name) - } - case Assign(left, right) => thunk { + case Assign(left, right) => thunk: for lvalue <- lookup(store)(left) Cell(rvalue) <- right.eval _ <- Success(lvalue.set(rvalue)) yield Cell.NULL - } - case Cond(guard, thenBranch, elseBranch) => thunk { - guard.eval match { + case Cond(guard, thenBranch, elseBranch) => thunk: + guard.eval match case Success(Cell.NULL) => elseBranch.eval case Success(_) => thenBranch.eval case f@Failure(_) => f - } - } case Block(expressions) => // TODO http://stackoverflow.com/questions/12892701/abort-early-in-a-fold // TODO https://stackoverflow.com/questions/57516234/listtryt-to-trylistt-in-scala @@ -124,9 +113,8 @@ object evaluate: case f@Failure(_) => return f Success(result) - thunk { + thunk: doSequence - } case Loop(guard, body) => def doLoop: Result = while true do @@ -136,10 +124,8 @@ object evaluate: case f@Failure(_) => return f Success(Cell.NULL) - thunk { + thunk: doLoop - } - } /** Evaluates the program by recursively applying the algebra to the tree. */ def evaluate(store: Store)(expr: Expr): Result = diff --git a/src/test/scala/imperativeTests.scala b/src/test/scala/imperativeTests.scala index b48ff0d..8eb1410 100644 --- a/src/test/scala/imperativeTests.scala +++ b/src/test/scala/imperativeTests.scala @@ -17,63 +17,56 @@ object imperativeTests extends Properties("imperativeTests"): /** Enable typesafe equality for `Result`. */ given CanEqual[Result, Success[Cell]] = CanEqual.derived - - property("don't do anything unless triggered") = Prop { + + property("don't do anything unless triggered") = Prop: val s = store() val s0 = store() val ev = scheme.cata(evalAlgebra(s)) ev(e2) s == s0 - } - property("correctly evaluate a side-effect free expression") = Prop { + property("correctly evaluate a side-effect free expression") = Prop: val s = store() val s0 = store() evaluate(s)(e1) == Success(Cell(Num(7))) && s == s0 - } - property("correctly evaluate a simple assignment") = Prop { + property("correctly evaluate a simple assignment") = Prop: val s = store() val s0 = store() evaluate(s)(e2) s - "x" == s0 - "x" && s0("x") == Cell(Num(2)) && s("x") == Cell(Num(4)) - } - property("correctly evaluate a statement block") = Prop { + property("correctly evaluate a statement block") = Prop: val s = store() val s0 = store() evaluate(s)(e3) s - "r" - "y" == s0 - "r" - "y" && s("r") == Cell(Num(2)) && s("y") == Cell(Num(2)) - } - property("correctly evaluate a conditional") = Prop { + property("correctly evaluate a conditional") = Prop: val s = store() val s0 = store() evaluate(s)(e4a) s - "r" == s0 - "r" && s("r") == Cell(Num(2)) - } - property("correctly evaluate another conditional") = Prop { + property("correctly evaluate another conditional") = Prop: val s = store() val s0 = store() evaluate(s)(e4b) s - "y" == s0 - "y" && s("y") == Cell(Num(2)) - } - property("correctly evaluate a loop") = Prop { + property("correctly evaluate a loop") = Prop: val s = store() val s0 = store() evaluate(s)(e5) s - "y" - "r" == s0 - "y" - "r" && s("r") == Cell(Num(6)) && s("y") == Cell(Num(0)) - } end imperativeTests diff --git a/src/test/scala/lawTests.scala b/src/test/scala/lawTests.scala index bf567fe..1bdb924 100644 --- a/src/test/scala/lawTests.scala +++ b/src/test/scala/lawTests.scala @@ -30,14 +30,13 @@ object lawTests extends Properties("lawTests"): def genLoop[A](g: Gen[A]) = (g, g).mapN(Loop(_, _)) def genAssign[A](f: Gen[String], g: Gen[A]) = (f, g).mapN(Assign(_, _)) - given [A](using Arbitrary[A]): Arbitrary[ExprF[A]] = Arbitrary { + given [A](using Arbitrary[A]): Arbitrary[ExprF[A]] = Arbitrary: val i = Arbitrary.arbInt.arbitrary val s = Arbitrary.arbString.arbitrary val g = Arbitrary.arbitrary[A] Gen.oneOf(genConstant(i), genVariable(s), genUMinus(g), genPlus(g), genMinus(g), genTimes(g), genDiv(g), genMod(g), genBlock(g), genCond(g), genLoop(g), genAssign(s, g)) - } include(cats.laws.discipline.FunctorTests[ExprF].functor[Int, Int, Int].all) // TODO reinclude after fixing Traverse