aboutsummaryrefslogtreecommitdiff
path: root/lab3/src/test
diff options
context:
space:
mode:
Diffstat (limited to 'lab3/src/test')
-rw-r--r--lab3/src/test/resources/lab3/test3004_call.ans8
-rw-r--r--lab3/src/test/resources/lab3/test3004_call.jsy2
-rw-r--r--lab3/src/test/resources/lab3/test3006_curry.ans8
-rw-r--r--lab3/src/test/resources/lab3/test3006_curry.jsy2
-rw-r--r--lab3/src/test/resources/lab3/test3008_call.ans48
-rw-r--r--lab3/src/test/resources/lab3/test3008_call.jsy2
-rw-r--r--lab3/src/test/scala/jsy/lab3/Lab3Spec.scala150
-rw-r--r--lab3/src/test/scala/jsy/tester/JavascriptyTester.scala23
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)
+ }
+ }
+}