diff options
Diffstat (limited to 'lab3/src/test')
-rw-r--r-- | lab3/src/test/resources/lab3/test3004_call.ans | 8 | ||||
-rw-r--r-- | lab3/src/test/resources/lab3/test3004_call.jsy | 2 | ||||
-rw-r--r-- | lab3/src/test/resources/lab3/test3006_curry.ans | 8 | ||||
-rw-r--r-- | lab3/src/test/resources/lab3/test3006_curry.jsy | 2 | ||||
-rw-r--r-- | lab3/src/test/resources/lab3/test3008_call.ans | 48 | ||||
-rw-r--r-- | lab3/src/test/resources/lab3/test3008_call.jsy | 2 | ||||
-rw-r--r-- | lab3/src/test/scala/jsy/lab3/Lab3Spec.scala | 150 | ||||
-rw-r--r-- | lab3/src/test/scala/jsy/tester/JavascriptyTester.scala | 23 |
8 files changed, 243 insertions, 0 deletions
diff --git a/lab3/src/test/resources/lab3/test3004_call.ans b/lab3/src/test/resources/lab3/test3004_call.ans new file mode 100644 index 0000000..cedff5b --- /dev/null +++ b/lab3/src/test/resources/lab3/test3004_call.ans @@ -0,0 +1,8 @@ +# Stepping ... +## 0: ConstDecl(w,Fun(None,y,Binary(Minus,Var(y),N(7.0))),Print(Call(Var(w),N(4.3)))) +## 1: Print(Call(Fun(None,y,Binary(Minus,Var(y),N(7.0))),N(4.3))) +## 2: Print(Binary(Minus,N(4.3),N(7.0))) +## 3: Print(N(-2.7)) +-2.7 +## 4: Undefined +undefined diff --git a/lab3/src/test/resources/lab3/test3004_call.jsy b/lab3/src/test/resources/lab3/test3004_call.jsy new file mode 100644 index 0000000..4054060 --- /dev/null +++ b/lab3/src/test/resources/lab3/test3004_call.jsy @@ -0,0 +1,2 @@ +const w = function (y) { return y - 7 } +console.log(w(4.3)) diff --git a/lab3/src/test/resources/lab3/test3006_curry.ans b/lab3/src/test/resources/lab3/test3006_curry.ans new file mode 100644 index 0000000..8a00bc5 --- /dev/null +++ b/lab3/src/test/resources/lab3/test3006_curry.ans @@ -0,0 +1,8 @@ +# Stepping ... +## 0: ConstDecl(g,Fun(None,x,Fun(None,y,Binary(And,Var(x),Var(y)))),Binary(Plus,Call(Call(Var(g),N(1.0)),N(0.0)),N(0.1))) +## 1: Binary(Plus,Call(Call(Fun(None,x,Fun(None,y,Binary(And,Var(x),Var(y)))),N(1.0)),N(0.0)),N(0.1)) +## 2: Binary(Plus,Call(Fun(None,y,Binary(And,N(1.0),Var(y))),N(0.0)),N(0.1)) +## 3: Binary(Plus,Binary(And,N(1.0),N(0.0)),N(0.1)) +## 4: Binary(Plus,N(0.0),N(0.1)) +## 5: N(0.1) +0.1 diff --git a/lab3/src/test/resources/lab3/test3006_curry.jsy b/lab3/src/test/resources/lab3/test3006_curry.jsy new file mode 100644 index 0000000..2e87562 --- /dev/null +++ b/lab3/src/test/resources/lab3/test3006_curry.jsy @@ -0,0 +1,2 @@ +const g = function(x) { return function(y) { return x && y } }; +g(1)(0) + 0.1 diff --git a/lab3/src/test/resources/lab3/test3008_call.ans b/lab3/src/test/resources/lab3/test3008_call.ans new file mode 100644 index 0000000..3e34395 --- /dev/null +++ b/lab3/src/test/resources/lab3/test3008_call.ans @@ -0,0 +1,48 @@ +# Stepping ... +## 0: ConstDecl(f,Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Plus,Call(Var(f),N(8.0)),N(0.1))) +## 1: Binary(Plus,Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(8.0)),N(0.1)) +## 2: Binary(Plus,If(Binary(Eq,N(8.0),N(0.0)),N(1.0),Binary(Times,N(8.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(8.0),N(1.0))))),N(0.1)) +## 3: Binary(Plus,If(B(false),N(1.0),Binary(Times,N(8.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(8.0),N(1.0))))),N(0.1)) +## 4: Binary(Plus,Binary(Times,N(8.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(8.0),N(1.0)))),N(0.1)) +## 5: Binary(Plus,Binary(Times,N(8.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(7.0))),N(0.1)) +## 6: Binary(Plus,Binary(Times,N(8.0),If(Binary(Eq,N(7.0),N(0.0)),N(1.0),Binary(Times,N(7.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(7.0),N(1.0)))))),N(0.1)) +## 7: Binary(Plus,Binary(Times,N(8.0),If(B(false),N(1.0),Binary(Times,N(7.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(7.0),N(1.0)))))),N(0.1)) +## 8: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(7.0),N(1.0))))),N(0.1)) +## 9: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(6.0)))),N(0.1)) +## 10: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),If(Binary(Eq,N(6.0),N(0.0)),N(1.0),Binary(Times,N(6.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(6.0),N(1.0))))))),N(0.1)) +## 11: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),If(B(false),N(1.0),Binary(Times,N(6.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(6.0),N(1.0))))))),N(0.1)) +## 12: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(6.0),N(1.0)))))),N(0.1)) +## 13: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(5.0))))),N(0.1)) +## 14: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),If(Binary(Eq,N(5.0),N(0.0)),N(1.0),Binary(Times,N(5.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(5.0),N(1.0)))))))),N(0.1)) +## 15: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),If(B(false),N(1.0),Binary(Times,N(5.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(5.0),N(1.0)))))))),N(0.1)) +## 16: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(5.0),N(1.0))))))),N(0.1)) +## 17: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(4.0)))))),N(0.1)) +## 18: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),If(Binary(Eq,N(4.0),N(0.0)),N(1.0),Binary(Times,N(4.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(4.0),N(1.0))))))))),N(0.1)) +## 19: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),If(B(false),N(1.0),Binary(Times,N(4.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(4.0),N(1.0))))))))),N(0.1)) +## 20: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(4.0),N(1.0)))))))),N(0.1)) +## 21: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(3.0))))))),N(0.1)) +## 22: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),If(Binary(Eq,N(3.0),N(0.0)),N(1.0),Binary(Times,N(3.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(3.0),N(1.0)))))))))),N(0.1)) +## 23: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),If(B(false),N(1.0),Binary(Times,N(3.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(3.0),N(1.0)))))))))),N(0.1)) +## 24: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(3.0),N(1.0))))))))),N(0.1)) +## 25: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(2.0)))))))),N(0.1)) +## 26: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),If(Binary(Eq,N(2.0),N(0.0)),N(1.0),Binary(Times,N(2.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(2.0),N(1.0))))))))))),N(0.1)) +## 27: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),If(B(false),N(1.0),Binary(Times,N(2.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(2.0),N(1.0))))))))))),N(0.1)) +## 28: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(2.0),N(1.0)))))))))),N(0.1)) +## 29: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(1.0))))))))),N(0.1)) +## 30: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),If(Binary(Eq,N(1.0),N(0.0)),N(1.0),Binary(Times,N(1.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(1.0),N(1.0)))))))))))),N(0.1)) +## 31: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),If(B(false),N(1.0),Binary(Times,N(1.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(1.0),N(1.0)))))))))))),N(0.1)) +## 32: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Binary(Times,N(1.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(1.0),N(1.0))))))))))),N(0.1)) +## 33: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Binary(Times,N(1.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),N(0.0)))))))))),N(0.1)) +## 34: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Binary(Times,N(1.0),If(Binary(Eq,N(0.0),N(0.0)),N(1.0),Binary(Times,N(0.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(0.0),N(1.0))))))))))))),N(0.1)) +## 35: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Binary(Times,N(1.0),If(B(true),N(1.0),Binary(Times,N(0.0),Call(Fun(Some(f),x,If(Binary(Eq,Var(x),N(0.0)),N(1.0),Binary(Times,Var(x),Call(Var(f),Binary(Minus,Var(x),N(1.0)))))),Binary(Minus,N(0.0),N(1.0))))))))))))),N(0.1)) +## 36: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),Binary(Times,N(1.0),N(1.0))))))))),N(0.1)) +## 37: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),Binary(Times,N(2.0),N(1.0)))))))),N(0.1)) +## 38: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),Binary(Times,N(3.0),N(2.0))))))),N(0.1)) +## 39: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),Binary(Times,N(4.0),N(6.0)))))),N(0.1)) +## 40: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),Binary(Times,N(5.0),N(24.0))))),N(0.1)) +## 41: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),Binary(Times,N(6.0),N(120.0)))),N(0.1)) +## 42: Binary(Plus,Binary(Times,N(8.0),Binary(Times,N(7.0),N(720.0))),N(0.1)) +## 43: Binary(Plus,Binary(Times,N(8.0),N(5040.0)),N(0.1)) +## 44: Binary(Plus,N(40320.0),N(0.1)) +## 45: N(40320.1) +40320.1 diff --git a/lab3/src/test/resources/lab3/test3008_call.jsy b/lab3/src/test/resources/lab3/test3008_call.jsy new file mode 100644 index 0000000..0ec8239 --- /dev/null +++ b/lab3/src/test/resources/lab3/test3008_call.jsy @@ -0,0 +1,2 @@ +const f = function f(x) { return x === 0 ? 1 : x * f(x - 1) }; +f(8) + 0.1 diff --git a/lab3/src/test/scala/jsy/lab3/Lab3Spec.scala b/lab3/src/test/scala/jsy/lab3/Lab3Spec.scala new file mode 100644 index 0000000..1b40c01 --- /dev/null +++ b/lab3/src/test/scala/jsy/lab3/Lab3Spec.scala @@ -0,0 +1,150 @@ +package jsy.lab3 + +import org.scalatest.flatspec.AnyFlatSpec +import Parser.parse +import ast._ +import Lab3._ + +class Lab3StudentSpec extends AnyFlatSpec { + + "StudentSpec" should "evaluate a higher order function" in { + val jsyStr: String = + "(function f(g) { return g(g)}) (function g(x) { return x }) (5);" + val answer: Either[DynamicTypeError, Expr] = Right(N(5)) + assert(answer === iterateStep(parse(jsyStr))) + } + + it should "evaluate a recursive function" in { + val jsyStr: String = + "(function f(x) { return x <= 1 ? 1 : x * f(x - 1)}) (3);" + val answer: Either[DynamicTypeError, Expr] = Right(N(6)) + assert(answer === iterateStep(parse(jsyStr))) + } + + it should "evaluate your test case" in { + val jsyStr: String = "1 + 1" + val answer: Either[DynamicTypeError, Expr] = Right(N(2)) + assert(answer === iterateStep(parse(jsyStr))) + } + +} + +class Lab3Spec extends AnyFlatSpec { + + "substitute" should "perform syntatic substitution respecting shadowing" in { + val xplus1 = parse("x + 1") + val twoplus1 = parse("2 + 1") + assert(substitute(N(2), "x", xplus1) === twoplus1) + val constx3 = parse("const x = 3; x") + val shadowx = Binary(Plus, constx3, Var("x")) + assert(substitute(N(2), "x", shadowx) === Binary(Plus, constx3, N(2))) + } + + "iterateBasic" should "work for sumTo(100)" in { + def sumTo(n: Int) = { + iterateBasic(0) { case (acc, i) => + require(n >= 0) + if (i > n) None + else Some(acc + i) + } + } + + assertResult(5050) { sumTo(100) } + } + + { + def sumTo(n: Int): Either[String, Int] = { + iterate(0) { case (acc, i) => + if (n < 0) Some(Left("requirement failed")) + else if (i > n) None + else Some(Right(acc + i)) + } + } + + "iterate" should "work for sumTo(100)" in { + assertResult(Right(5050)) { sumTo(100) } + } + + "iterate" should "work for sumTo(-1)" in { + assertResult(Left("requirement failed")) { sumTo(-1) } + } + + val one = parse("1") + + it should "stop if the callback body returns None" in { + assertResult(Right(one)) { + iterate(one) { (_, _) => None } + } + } + + it should "increment the loop counter on each iteration and use e if the callback body returns Some(e)" in { + assertResult(Right(parse("--1"))) { + iterate(one) { (e: Expr, n: Int) => + if (n == 2) None else Some(Right(Unary(Neg, e))) + } + } + } + } + + "step/call" should "evaluate a function using small-step semantics" in { + val f = "f" + val x = "x" + val e1 = Fun(None, x, Binary(Plus, Var(x), N(1))) + val e2 = N(2) + val e3 = iterateStep(Call(e1, e2)) + assert(e3 === Right(N(3))) + } + + it should "handle recursive functions using small-step semantics" in { + val f = "f" + val x = "x" + val fbody = If( + Binary(Eq, Var(x), N(0)), + Var(x), + Binary(Plus, Var(x), Call(Var(f), Binary(Minus, Var(x), N(1)))) + ) + val e1 = Fun(Some(f), x, fbody) + val e2 = N(3) + val e3 = iterateStep(Call(e1, e2)) + assert(e3 === Right(N(6))) + } + + /* Some tests based on rules */ + + { + val xval = N(2) + val varx = Var("x") + + val e1 = parse("2 - 1 - 1") + val e1p = parse("1 - 1") + val e2 = parse("3 - 1 - 1") + val e2p = parse("2 - 1") + val v1 = N(0) + val v2 = N(1) + + val vidfunction = parse("function (x) { return x }") + + "DoNeg" should "perform DoNeg" in { + val np = -0 + assertResult(Right(N(np))) { + step(Unary(Neg, v1)) + } + } + + "SearchUnary" should "perform SearchUnary" in { + assertResult(Right(Unary(Neg, e1p))) { + step(Unary(Neg, e1)) + } + } + + val e_callerror = Call(N(1), N(2)) + + "TypeErrorCall" should "perform TypeErrorCall" in { + assertResult(Left(DynamicTypeError(e_callerror))) { + step(e_callerror) + } + } + } +} + +class Lab3JsyTests extends jsy.tester.JavascriptyTester(None, "lab3", Lab3) diff --git a/lab3/src/test/scala/jsy/tester/JavascriptyTester.scala b/lab3/src/test/scala/jsy/tester/JavascriptyTester.scala new file mode 100644 index 0000000..48e789c --- /dev/null +++ b/lab3/src/test/scala/jsy/tester/JavascriptyTester.scala @@ -0,0 +1,23 @@ +package jsy.tester +import java.io.File +import jsy.util.JsyApplication +import org.scalatest._ +import flatspec._ + +/* + * A ScalaTest interface for running system tests. + */ +class JavascriptyTester(rootPrefix: Option[String], testDirectory: String, jsy: JsyApplication) extends AnyFlatSpec { + val testResources = s"src${File.separator}test${File.separator}resources" + val testPrefix = rootPrefix match { + case None => testResources + case Some(p) => s"${p}${File.separator}${testResources}" + } + val testPath = s"${testPrefix}${File.separator}${testDirectory}" + jsy.test(new File(testPath)) { case (in,ans,assertion) => + s"eval on ${in}" should s"match ${ans}" in { + val (b: Boolean, msg: String) = assertion + assert(b, msg) + } + } +} |