--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,3 @@
+// for testing compilation
+import $file.cw02
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c1.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,5 @@
+// for testing compilation
+import $file.cw02
+import cw02._
+
+assert(tokenise("read n;") == List(T_KEYWORD("read"), T_ID("n"), T_SEMI))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c1a.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,5 @@
+// for testing compilation
+import $file.cw02
+import cw02._
+
+print(s" ${tokenise("read n;")}")
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c2.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,36 @@
+// for testing compilation
+import $file.cw02
+import cw02._
+
+val ufile = """
+// Collatz series
+//
+// needs writing of strings and numbers; comments
+
+bnd := 1;
+while bnd < 101 do {
+ write bnd;
+ write ": ";
+ n := bnd;
+ cnt := 0;
+
+ while n > 1 do {
+ write n;
+ write ",";
+
+ if n % 2 == 0
+ then n := n / 2
+ else n := 3 * n+1;
+
+ cnt := cnt + 1
+ };
+
+ write " => ";
+ write cnt;
+ write "\n";
+ bnd := bnd + 1
+}
+"""
+
+
+println(tokenise(ufile))
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c3.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,24 @@
+// for testing tokenisation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw023_add
+import cw023_add._
+
+// programs to test (and number of toplevel definitions)
+val uprogs = List("collatz.while",
+ "collatz2.while",
+ "factors.while",
+ "fib.while",
+ "loops.while",
+ "primes.while")
+
+for (file <- uprogs) {
+
+ print(s" Testing lexing with ${file.padTo(16, ' ')} ")
+ val str = os.read(os.pwd / file)
+
+ Try(test_string(str)) match {
+ case Success(v) => println(s"--> Success. Generated ${v.toString.take(30)}...")
+ case Failure(e) => println(s"--> FAIL. Exception raised.") ; throw(e)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c3_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,7 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ tks
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c4.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,123 @@
+// for testing tokenisation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw024_add
+import cw024_add._
+
+def listcmp[A](xs: List[A], ys: List[A]): List[A] = (xs, ys) match {
+ case (Nil, Nil) => Nil
+ case (x::xs, y::ys) => if (x == y) listcmp(xs, ys) else (x::xs)
+ case _ => xs
+}
+
+
+// some students eliminated "..." therefore a specific comparison function
+def lsteq(xs: List[Token], ys: List[Token]): Boolean = (xs, ys) match {
+ case (Nil, Nil) => true
+ case (T_STRING(s1)::xs, T_STRING(s2)::ys) =>
+ (s1 == s2 || s2.drop(1).dropRight(1) == s1) && lsteq(xs, ys)
+ case (x::xs, y::ys) => x == y && lsteq(xs, ys)
+ case _ => false
+}
+
+// some students kept string T_Num
+import scala.language.implicitConversions
+given Conversion[Int, String] = (n => n.toString)
+given Conversion[String,Char] = (s => s.head)
+
+// programs to test (and number of toplevel definitions)
+//val uregs = List((RECD("x", PLUS(CHAR('a'))), "aaa"))
+
+val tks =
+ List(T_ID("bnd"),
+ T_OP(":="),
+ T_NUM(1),
+ T_SEMI,
+ T_KEYWORD("while"),
+ T_ID("bnd"),
+ T_OP("<"),
+ T_NUM(101),
+ T_KEYWORD("do"),
+ T_PAREN("{"),
+ T_KEYWORD("write"),
+ T_ID("bnd"),
+ T_SEMI,
+ T_KEYWORD("write"),
+ T_STRING("\": \""),
+ T_SEMI,
+ T_ID("n"),
+ T_OP(":="),
+ T_ID("bnd"),
+ T_SEMI,
+ T_ID("cnt"),
+ T_OP(":="),
+ T_NUM(0),
+ T_SEMI,
+ T_KEYWORD("while"),
+ T_ID("n"),
+ T_OP(">"),
+ T_NUM(1),
+ T_KEYWORD("do"),
+ T_PAREN("{"),
+ T_KEYWORD("write"),
+ T_ID("n"),
+ T_SEMI,
+ T_KEYWORD("write"),
+ T_STRING("\",\""),
+ T_SEMI,
+ T_KEYWORD("if"),
+ T_ID("n"),
+ T_OP("%"),
+ T_NUM(2),
+ T_OP("=="),
+ T_NUM(0),
+ T_KEYWORD("then"),
+ T_ID("n"),
+ T_OP(":="),
+ T_ID("n"),
+ T_OP("/"),
+ T_NUM(2),
+ T_KEYWORD("else"),
+ T_ID("n"),
+ T_OP(":="),
+ T_NUM(3),
+ T_OP("*"),
+ T_ID("n"),
+ T_OP("+"),
+ T_NUM(1),
+ T_SEMI,
+ T_ID("cnt"),
+ T_OP(":="),
+ T_ID("cnt"),
+ T_OP("+"),
+ T_NUM(1),
+ T_PAREN("}"),
+ T_SEMI,
+ T_KEYWORD("write"),
+ T_STRING("\" => \""),
+ T_SEMI,
+ T_KEYWORD("write"),
+ T_ID("cnt"),
+ T_SEMI,
+ T_KEYWORD("write"),
+ T_STRING("\"\\n\""),
+ T_SEMI,
+ T_ID("bnd"),
+ T_OP(":="),
+ T_ID("bnd"),
+ T_OP("+"),
+ T_NUM(1),
+ T_PAREN("}"))
+
+
+
+ //print(s" Testing lexing of ${file.padTo(16, ' ')} ")
+val str = os.read(os.pwd / "collatz2.while")
+
+Try(test_string(str)) match {
+ case Success(v) if lsteq(v, tks)
+ => println(s" Generated the correct token sequence.")
+ case Success(v) => println(s" Generated $v\n instead of\n $tks\n\n${listcmp(v, tks)}).") ; throw new Exception("Different")
+ case Failure(e) => println(s" Exception raised.") ; throw(e)
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c4_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,7 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ tks
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/c5.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,23 @@
+// for primitive definitions
+import $file.cw02
+import cw02._
+
+def sz(r: Rexp): Int = r match {
+ case ZERO => 1
+ case ONE => 1
+ case CHAR(_) => 1
+ case ALT(r1, r2) => 1 + sz(r1) + sz (r2)
+ case SEQ(r1, r2) => 1 + sz(r1) + sz (r2)
+ case STAR(r1) => 1 + sz(r1)
+ case PLUS(r1) => 1 + sz(r1)
+ case NTIMES(r1, n) => 1 + sz(r1)
+ case OPTIONAL(r1) => 1 + sz(r1)
+ case RECD(_, r1) => 1 + sz(r1)
+ case RANGE(_) => 1
+}
+
+assert(sz(RANGE("abc")) != 1)
+
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw2_marking/cw2_test.sh Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,143 @@
+#!/bin/zsh
+
+# to make the script fail safely
+set -euo pipefail
+
+
+out=${1:-output}
+
+echo -e "" > $out
+
+echo `date` | tee -a $out
+echo "" >> $out
+echo "Below is the feedback and provisional marks for your CW 2 submission." >> $out
+echo "Please note all marks are provisional until ratified by the" >> $out
+echo "assessment board -- this is not an official results transcript." >> $out
+echo "" >> $out
+
+echo "The feedback for your submission for cw02.sc" >> $out
+echo "" >> $out
+
+# marks for CW 2
+marks=$(( 0.0 ))
+
+# compilation tests
+
+function scala_compile {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" amm -s "$1" 2> c$out 1> c$out)
+}
+
+# functional tests
+
+function scala_assert {
+ rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 2> /dev/null ;
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+function scala_fail {
+ #rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 2> /dev/null ;
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1") # 1>> $out 2>> $out)
+}
+
+
+
+### compilation test
+
+echo -e "0) cw02.sc compiles?\n" | tee -a $out
+
+if (scala_compile "c.sc")
+then
+ echo -e " --> yes cw02.sc compiles\n" | tee -a $out
+ tsts=$(( 0 ))
+else
+ echo -e " --> AMM DID NOT compile cw02.sc\n" | tee -a $out
+ cat c$out | tee -a $out
+ echo -e "\n\n" >> $out
+ tsts=$(( 1 ))
+fi
+
+echo >> $out
+
+### "read n;" test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "1) Tokenise string from Question 2:\n" | tee -a $out
+ echo -e " tokenise(\"read n;\") == List(T_KEYWORD(read), T_ID(n), T_SEMI) ?\n" | tee -a $out
+ if (scala_assert "c1.sc")
+ then
+ echo -e " --> success (+ 3.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 3.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ echo -e " instead it generates:\n" | tee -a $out
+ (scala_fail "c1a.sc" || true) | tee -a $out
+ echo -e "\n\n" >> $out
+ fi
+fi
+
+### tokenise test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "2) Tokenise test with example files (does it raise an exception):\n" | tee -a $out
+ cat cw02.sc c3_add.sc > cw023_add.sc
+ if (scala_assert "c3.sc")
+ then
+ echo -e " --> success (+ 3.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 3.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ #cat $out | tee -a $out
+ fi
+fi
+
+### tokenise test for collatz2.while
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "3) Check tokens for collatz2.while:\n" | tee -a $out
+ cat cw02.sc c4_add.sc > cw024_add.sc
+ if (scala_assert "c4.sc")
+ then
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 2.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ #cat $out | tee -a $out
+ fi
+fi
+
+### are constructors primitive
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "4) Are regex constructors all primitive?\n" | tee -a $out
+ echo -e " For example, RANGE.toString == \"RANGE\"\n" | tee -a $out
+ if (scala_assert "c5.sc")
+ then
+ echo -e " --> FAILED\n" | tee -a $out
+ tail -25 $out | pr -to10
+ echo -e "\n\n" >> $out
+ else
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 2.0 ))
+ fi
+fi
+
+
+## final marks
+echo >> $out
+echo "Overall mark for CW 2" | tee -a $out
+printf " %0.2f\n" $marks | tee -a $out
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,3 @@
+// for testing compilation
+import $file.cw03
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c3.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,25 @@
+// for testing parsing
+
+import scala.util.{Try, Success, Failure}
+import $file.cw033_add
+import cw033_add._
+
+// programs to test (and number of toplevel definitions)
+val uprogs = List("collatz.while",
+ "collatz2.while",
+ "factors.while",
+ "fib.while",
+ "loops.while",
+ "primes.while")
+
+for (file <- uprogs) {
+
+ print(s" Testing parsing with ${file.padTo(16, ' ')} ")
+ val str = os.read(os.pwd / file)
+
+ Try(test_string(str)) match {
+ case Success(v) => println(s"--> Success. Generated AST ${v.toString.take(30)}...")
+ case Failure(e) => println(s"--> FAIL. Exception raised.") ; throw(e)
+ }
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c3_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,8 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ val ast = Stmts.parse_all(tks).head
+ ast
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c4.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,19 @@
+// for testing evaluation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw034_add
+import cw034_add._
+
+val str = os.read(os.pwd / "primes.while")
+val resmap = Map("end" -> 100, "n" -> 100, "f" -> 4, "tmp" -> 1)
+
+def mapeq[A, B](m1: Map[A, B], m2: Map[A, B]) : Boolean = {
+ m1.keySet.forall(k => m1(k) == m2(k))
+}
+
+
+Try(test_string(str)) match {
+ case Success(v) if mapeq(resmap, v) => Console.println(s" Generated the correct result $v")
+ case Success(v) => Console.println(s" Generated $v\n instead of\n $resmap\n.") ; throw new Exception("Different")
+ case Failure(e) => Console.println(s" Exception raised.") ; throw(e)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c4_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,8 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ val ast = Stmts.parse_all(tks).head
+ eval(ast)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c4_pre.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,7 @@
+var urban : String = ""
+
+def print[A](s: A) = urban = urban + s.toString
+def println[A](s: A) = urban = urban + s.toString + "\n"
+def println() = urban + "\n"
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/c5.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,14 @@
+// for testing evaluation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw034_add
+import cw034_add._
+
+val str = os.read(os.pwd / "test.while")
+val output = "1\n"
+
+Try(test_string(str)) match {
+ case Success(v) if urban == output => Console.println(s"Generated the correct output\n\"\"\"$urban\"\"\"")
+ case Success(v) => Console.println(s"Generated\n\"\"\"$urban\"\"\"\ninstead of\n\"\"\"$output\"\"\"") ; throw new Exception("Different")
+ case Failure(e) => Console.println(s"Exception raised.") ; throw(e)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw3_marking/cw3_test.sh Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,121 @@
+#!/bin/zsh
+
+# to make the script fail safely
+set -euo pipefail
+
+
+out=${1:-output}
+
+echo -e "" > $out
+
+echo `date` | tee -a $out
+echo "" >> $out
+echo "Below is the feedback and provisional marks for your CW 3 submission." >> $out
+echo "Please note all marks are provisional until ratified by the" >> $out
+echo "assessment board -- this is not an official results transcript." >> $out
+echo "" >> $out
+
+echo "The feedback for your submission for cw03.sc" >> $out
+echo "" >> $out
+
+# marks for CW 3
+marks=$(( 0.0 ))
+
+# compilation tests
+
+function scala_compile {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" amm -s "$1" 2> c$out 1> c$out)
+}
+
+# functional tests
+
+function scala_assert {
+ rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 2> /dev/null ;
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+function scala_fail {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+
+
+### compilation test
+
+echo -e "0) cw03.sc compiles?\n" | tee -a $out
+
+if (scala_compile "c.sc")
+then
+ echo -e " --> yes cw03.sc compiles\n" | tee -a $out
+ tsts=$(( 0 ))
+else
+ echo -e " --> AMM DID NOT compile cw03.sc\n" | tee -a $out
+ cat c$out | tee -a $out
+ echo -e "\n\n" >> $out
+ tsts=$(( 1 ))
+fi
+
+### parsing test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "1) Parsing test with example files (does it raise an exception):\n" | tee -a $out
+ cat cw03.sc c3_add.sc > cw033_add.sc
+ if (scala_assert "c3.sc")
+ then
+ echo -e " --> success (+ 6.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 6.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ #cat $out | tee -a $out
+ fi
+fi
+
+### eval test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "2) Evaluation of primes.while:\n" | tee -a $out
+ cat c4_pre.sc cw03.sc c4_add.sc > cw034_add.sc
+ if (scala_assert "c4.sc")
+ then
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 2.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ #cat $out | tee -a $out
+ fi
+fi
+
+### print test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "3) Testing of what is printed with the program:\n" | tee -a $out
+ echo -e "\"\"\"" >> $out
+ cat "test.while" >> $out
+ echo -e "\"\"\"\n" >> $out
+ if (scala_assert "c5.sc")
+ then
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 2.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ tail -25 $out | pr -to10
+ fi
+fi
+
+
+## final marks
+echo >> $out
+echo "Overall mark for CW 3" | tee -a $out
+printf " %0.2f\n" $marks | tee -a $out
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/br.while Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,8 @@
+for i := 2 upto 6 do {
+ if i > 4 then break else skip;
+ write i
+};
+
+write "67";
+break;
+write "XXX"
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,3 @@
+// for testing compilation
+import $file.cw04
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c1.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,12 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+import $file.cw041_add
+import cw041_add._
+
+val ffile = os.read(os.pwd / "for.while")
+
+Try(test_string(ffile, "for")) match {
+ case Success(v) => Console.println(s" Generated a j-file.")
+ case Failure(e) => Console.println(s" Exception raised.") ; throw(e)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c1_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,13 @@
+
+
+
+def test_string(prog: String, cname: String) = {
+ val tks = tokenise(prog)
+ //println(tks)
+ val ast = Stmts.parse_all(tks).head
+ //println(ast)
+ val code = compile(ast, cname)
+ //println(code)
+ os.write.over(os.pwd / (cname ++ ".j"), code)
+ //println(eval(ast))
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c2.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,59 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+
+val res = {
+ if (os.exists(os.pwd / "for.class"))
+ os.proc("java", "for").call(cwd = os.pwd)
+ else if (os.exists(os.pwd / "for" / "for.class"))
+ os.proc("java", "for.for").call(cwd = os.pwd)
+ else throw new Exception("No CLASS file found")
+}
+
+/*
+Try(test_string(ffile, "for")) match {
+ case Success(v) => Console.println(s" Generated a j-file.")
+ case Failure(e) => Console.println(s" Exception raised.") ; throw(e)
+}
+*/
+
+if (res.exitCode != 0) {
+ throw new Exception("Unsuccessful call")
+}
+
+Try(res.out.text().replace("\n", "") == "234") match {
+ case Success(v) => Console.println(s" Success. Printed ${res.out.text().replace("\n", "")}.")
+ case Failure(e) => Console.println(s" Fail. Printed ${res.out.text()} instead of \"2,3,4\"\n") ; throw(e)
+}
+
+
+//println(res.out.text())
+
+
+/*
+
+
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+import $file.cw041_add
+import cw041_add._
+
+val res =
+ if (os.exists(os.pwd / "for.class")) {
+
+ } else if (os.exists(os.pwd / for" / "for.class")) {
+
+ } else
+
+
+
+val ffile = os.read(os.pwd / "for.while")
+
+Try(test_string(ffile, "for")) match {
+ case Success(v) => Console.println(s" Generated a j-file.")
+ case Failure(e) => Console.println(s" Exception raised.") ; throw(e)
+}
+
+
+*/
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c3.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,12 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+import $file.cw041_add
+import cw041_add._
+
+val ffile = os.read(os.pwd / "br.while")
+
+Try(test_string(ffile, "br")) match {
+ case Success(v) => Console.println(s" Generated a j-file.")
+ case Failure(e) => Console.println(s" Exception raised.") ; throw(e)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/c4.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,21 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+
+val res = {
+ if (os.exists(os.pwd / "br.class"))
+ os.proc("java", "br").call(cwd = os.pwd)
+ else if (os.exists(os.pwd / "br" / "br.class"))
+ os.proc("java", "br.br").call(cwd = os.pwd)
+ else throw new Exception("No CLASS file found")
+}
+
+if (res.exitCode != 0) {
+ throw new Exception("Unsuccessful call")
+}
+
+Try(res.out.text().replace("\n", "") == "23467") match {
+ case Success(v) => Console.println(s" Success. Printed ${res.out.text().replace("\n", "")}.")
+ case Failure(e) => Console.println(s" Fail. Printed ${res.out.text()} instead of \"2,3,4,6,7\"\n") ; throw(e)
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/cw4_test.sh Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,220 @@
+#!/bin/zsh
+
+# to make the script fail safely
+set -euo pipefail
+
+
+out=${1:-output}
+
+echo -e "" > $out
+
+echo `date` | tee -a $out
+echo "" >> $out
+echo "Below is the feedback and provisional marks for your CW 4 submission." >> $out
+echo "Please note all marks are provisional until ratified by the" >> $out
+echo "assessment board -- this is not an official results transcript." >> $out
+echo "" >> $out
+
+echo "The feedback for your submission for cw04.sc" >> $out
+echo "" >> $out
+
+# marks for CW 4
+marks=$(( 0.0 ))
+
+# compilation tests
+
+function scala_compile {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" amm -s "$1" 2> c$out 1> c$out)
+}
+
+# functional tests
+
+function scala_assert {
+ rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 2> /dev/null ;
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+function scala_fail {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+
+### compilation test
+
+echo -e "0) cw04.sc compiles?" | tee -a $out
+
+if (scala_compile "c.sc")
+then
+ echo -e " --> yes cw04.sc compiles\n" | tee -a $out
+ tsts=$(( 0 ))
+else
+ echo -e " --> AMM DID NOT compile cw04.sc\n" | tee -a $out
+ cat c$out | tee -a $out
+ tsts=$(( 1 ))
+fi
+
+### fib.j test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "1.1) fib.j is not empty?" | tee -a $out
+
+ if [ -s fib.j ]
+ then
+ echo -e " --> success" | tee -a $out
+ tstsA=$(( 0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ tstsA=$(( 1 ))
+ fi
+fi
+
+echo >> $out
+
+if [ $tstsA -eq 0 ]
+then
+ echo -e "1.2) Generating a class-file for fib.j:" | tee -a $out
+ echo -e " java -jar jasmin.jar fib.j\n" | tee -a $out
+
+ java -jar /Users/cu/jasmin.jar fib.j 1> /dev/null 2> outj
+
+ if [ -s outj ]
+ then
+ echo -e " --> The jasmin assembler generated the following error message:\n" | tee -a $out
+ cat outj >> $out
+ else
+ echo -e " --> success (+ 5.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 5.0 ))
+ fi
+fi
+
+### for test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "2.1) Generating j-file for the file:\n" | tee -a $out
+ cat "for.while" | pr -to10 >> $out
+ echo >> $out
+ cat cw04.sc c1_add.sc > cw041_add.sc
+
+ if (scala_assert "c1.sc")
+ then
+ echo -e " --> success" | tee -a $out
+ tstsB=$(( 0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ cat c$out >> $out
+ tail -25 $out | pr -to10
+ tstsB=$(( 1 ))
+ fi
+fi
+
+echo >> $out
+
+if [ $tstsB -eq 0 ]
+then
+ echo -e "2.2) Generating a class-file for this file:" | tee -a $out
+ echo -e " java -jar jasmin.jar for.j\n" | tee -a $out
+ java -jar /Users/cu/jasmin.jar for.j 1> /dev/null 2> outj
+
+ if [ -s outj ]
+ then
+ echo -e " --> The jasmin assembler generated the following error message:\n" | tee -a $out
+ cat outj >> $out
+ tstsB=$(( 1 ))
+ else
+ echo -e " --> success\n" | tee -a $out
+ tstsB=$(( 0 ))
+ fi
+fi
+
+if [ $tstsB -eq 0 ]
+then
+ echo -e "2.3) Running for.j" | tee -a $out
+ if (scala_assert "c2.sc")
+ then
+ echo -e " --> success (+ 5.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 5.0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ tail -25 $out | pr -to10
+ cat c$out >> $out
+ fi
+fi
+
+##############################
+
+### break test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "3.1) Generating j-file for the file:\n" | tee -a $out
+ cat "br.while" | pr -to10 >> $out
+ echo >> $out
+ cat cw04.sc c1_add.sc > cw041_add.sc
+
+ if (scala_assert "c3.sc")
+ then
+ echo -e " --> success" | tee -a $out
+ tstsC=$(( 0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ cat c$out >> $out
+ tail -25 $out | pr -to10
+ tstsC=$(( 1 ))
+ fi
+fi
+
+echo >> $out
+
+if [ $tstsC -eq 0 ]
+then
+ echo -e "3.2) Generating a class-file for this file:" | tee -a $out
+ echo -e " java -jar jasmin.jar br.j\n" | tee -a $out
+ java -jar /Users/cu/jasmin.jar br.j 1> /dev/null 2> outj
+
+ if [ -s outj ]
+ then
+ echo -e " --> The jasmin assembler generated the following error message:\n" | tee -a $out
+ cat outj >> $out
+ tstsC=$(( 1 ))
+ else
+ echo -e " --> success\n" | tee -a $out
+ tstsC=$(( 0 ))
+ fi
+fi
+
+if [ $tstsC -eq 0 ]
+then
+ echo -e "3.3) Running br.j" | tee -a $out
+ if (scala_assert "c4.sc")
+ then
+ echo -e " --> success (+ 5.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 5.0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ tail -25 $out | pr -to10
+ cat c$out >> $out
+ fi
+fi
+
+
+
+
+
+
+echo >> $out
+
+## final marks
+echo >> $out
+echo "Overall mark for CW 4" | tee -a $out
+printf " %0.2f\n" $marks | tee -a $out
+
+
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw4_marking/for.while Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,3 @@
+for i := 2 upto 4 do {
+ write i
+}
\ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,3 @@
+// for testing compilation
+import $file.cw05
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c1.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,24 @@
+// for testing tokenisation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw05_add
+import cw05_add._
+
+// programs to tokenise (and how many tokens)
+val uprogs = List(("fact.fun", 113),
+ ("hanoi.fun", 92),
+ ("mand.fun", 226),
+ ("mand2.fun", 245),
+ ("sqr.fun", 78))
+
+for ((file, no) <- uprogs) {
+
+ print(s"Testing tokenisation of $file ")
+ val str = os.read(os.pwd / file)
+
+ Try(test_string(str)) match {
+ case Success(v) => println(s"--> Success. Lexed tokens.")
+ //case Success(v) => println(s"--> Success? Lexed ${v.length} tokens (should be $no).\n $v") ; throw new Exception("Different")
+ case Failure(e) => println(s"--> FAIL. Exception raised.") ; throw(e)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c1_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,8 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ tks
+ //println(tks)
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c2.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,24 @@
+// for testing tokenisation
+
+import scala.util.{Try, Success, Failure}
+import $file.cw05_add
+import cw05_add._
+
+// programs to test (and number of toplevel definitions)
+val uprogs = List(("fact.fun", 5),
+ ("hanoi.fun", 2),
+ ("mand.fun", 11),
+ ("sqr.fun", 4))
+
+for ((file, no) <- uprogs) {
+
+ print(s"Testing Parsing of $file ")
+ val str = os.read(os.pwd / file)
+
+
+ Try(test_string(str).length) match {
+ case Success(v) if v == no => println(s"--> Success. Parsed $no top-level definitions.")
+ case Success(v) => println(s"--> Success? Parsed $v top-level definitions (should be $no).")// ; throw new Exception("Different")
+ case Failure(e) => println(s"--> FAIL. Exception raised.") ; throw(e)
+ }
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c2_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,8 @@
+
+
+
+def test_string(prog: String) = {
+ val tks = tokenise(prog)
+ val ast = Prog.parse_all(tks).head
+ ast
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c3.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,9 @@
+// for testing compilation
+
+import $file.cw051_add
+import cw051_add._
+
+val mand = os.read(os.pwd / "mand.fun")
+
+test_string(mand, "mand")
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c3_add.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,13 @@
+
+
+
+def test_string(prog: String, cname: String) = {
+ val tks = tokenise(prog)
+ //println(tks)
+ val ast = Prog.parse_all(tks).head
+ //println(ast)
+ val code = fun_compile(ast)
+ //println(code)
+ os.write.over(os.pwd / (cname ++ ".ll"), code)
+ //println(eval(ast))
+}
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c4.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,40 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+//println("TEST1")
+
+val res = {
+ if (os.exists(os.pwd / "mand.ll"))
+ os.proc("lli", "mand.ll").call(cwd = os.pwd, check = false)
+ else throw new Exception("No CLASS file found")
+}
+
+//println("TEST2")
+
+/*
+if (res.exitCode != 0) {
+ throw new Exception("Unsuccessful call")
+}
+*/
+
+def pp(s1: String, s2: String) = {
+ val s1a = s1.split("\n").toList
+ val s2a = s2.split("\n").toList
+ for (n <- 0 to (s1a.length - 1)) {
+ println(s"|${s1a(n)}|")
+ println(s">${Try(s2a(n)).getOrElse("")}<")
+ }
+}
+
+//println("TEST3")
+
+val out = os.read(os.pwd / "mand.out")
+
+//println("TEST4")
+
+Try(res.out.text()) match {
+ case Success(v) if v == out => println(s" Success. Printed out the correct picture.\n")
+ case Success(v) => println(s" Printed out wrong or no picture.\n${pp(v, out)}") ; throw new Exception("Wrong picture")
+ case Failure(e) => println(s" Fail. Printed ${res.out.text()} instead\n") ; throw(e)
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c5.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,9 @@
+// for testing compilation
+
+import $file.cw051_add
+import cw051_add._
+
+val mand = os.read(os.pwd / "sqr.fun")
+
+test_string(mand, "sqr")
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/c6.sc Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,39 @@
+// for testing compilation
+import scala.util.{Try, Success, Failure}
+
+//println("TEST1")
+
+val res = {
+ if (os.exists(os.pwd / "sqr.ll"))
+ os.proc("lli", "sqr.ll").call(cwd = os.pwd, check = false)
+ else throw new Exception("No CLASS file found")
+}
+
+//println("TEST2")
+
+/*
+if (res.exitCode != 0) {
+ throw new Exception("Unsuccessful call")
+}
+*/
+
+def pp(s1: String, s2: String) = {
+ val s1a = s1.replace("\n","").replace(" ","")
+ val s2a = s2.replace("\n","")
+ s1a == s2a
+}
+
+//println("TEST3")
+
+val out = "Squares0149162536496481100"
+val out2 = "\"Squares\"0149162536496481100"
+
+
+//println("TEST4")
+
+Try(res.out.text()) match {
+ case Success(v) if (pp(v, out) || pp(v, out2)) => println(s" Success. Printed out the correct output.\n")
+ case Success(v) => println(s" Printed out wrong or no output.\n${v}") ; throw new Exception("Wrong Output")
+ case Failure(e) => println(s" Fail. Printed ${res.out.text()} instead\n") ; throw(e)
+}
+
--- /dev/null Thu Jan 01 00:00:00 1970 +0000
+++ b/cw5_marking/cw5_test.sh Mon Feb 03 12:34:38 2025 +0000
@@ -0,0 +1,202 @@
+#!/bin/zsh
+
+# to make the script fail safely
+set -euo pipefail
+
+
+out=${1:-output}
+
+echo -e "" > $out
+
+echo `date` | tee -a $out
+echo "" >> $out
+echo "Below is the feedback and provisional marks for your CW 5 submission." >> $out
+echo "Please note all marks are provisional until ratified by the" >> $out
+echo "assessment board -- this is not an official results transcript." >> $out
+echo "" >> $out
+
+echo "The feedback for your submission for cw05.sc" >> $out
+echo "" >> $out
+
+# marks for CW 5
+marks=$(( 0.0 ))
+
+# compilation tests
+
+function scala_compile {
+ (ulimit -t 30; JAVA_OPTS="-Xmx1g" amm -s "$1" 2> c$out 1> c$out)
+}
+
+# functional tests
+setopt no_nomatch
+
+function scala_assert {
+ rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 1> /dev/null 2> /dev/null ;
+ (ulimit -t 300; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" 1>> $out 2>> $out)
+}
+
+function scala_fail {
+ rm -rf /Users/cu/.ammonite/cache/3.0.0-M2/* 1> /dev/null 2> /dev/null ;
+ (ulimit -t 300; JAVA_OPTS="-Xmx1g -XX:MaxJavaStackTraceDepth=10" amm -s "$1" | tee -a $out)
+}
+
+
+
+### compilation test
+
+echo -e "0) cw05.sc compiles?" | tee -a $out
+
+if (scala_compile "c.sc")
+then
+ echo -e " --> yes cw05.sc compiles\n" | tee -a $out
+ tsts=$(( 0 ))
+else
+ echo -e " --> AMM DID NOT compile cw05.sc\n" | tee -a $out
+ cat c$out | tee -a $out
+ tsts=$(( 1 ))
+fi
+
+
+### tokenise test
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "1) tokenise test\n" | tee -a $out
+ cat cw05.sc c1_add.sc > cw05_add.sc
+ if (scala_assert "c1.sc")
+ then
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ #cat $out | tee -a $out
+ marks=$(( marks + 2.0 ))
+ else
+ echo -e " --> FAILED\n" | tee -a $out
+ cat $out | tee -a $out
+ fi
+fi
+
+### parsing test
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "2) parsing test\n" | tee -a $out
+ cat cw05.sc c2_add.sc > cw05_add.sc
+ START=$(date +%s)
+
+ if (scala_assert "c2.sc")
+ then
+ END=$(date +%s)
+ DIFF=$(( $END - $START ))
+ echo -e " This test ran for $DIFF seconds" | tee -a $out
+ echo -e " --> success (+ 3.0 Marks)\n" | tee -a $out
+ #cat $out | tee -a $out
+ marks=$(( marks + 3.0 ))
+ else
+ END=$(date +%s)
+ DIFF=$(( $END - $START ))
+ echo -e " This test ran for $DIFF seconds" | tee -a $out
+ echo -e " --> FAILED\n" | tee -a $out
+ cat $out | tee -a $out
+ fi
+fi
+
+### mand test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+
+tstsB=$(( 1 ))
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "3.1) Generating ll-file for mand.fun:\n" | tee -a $out
+ echo >> $out
+ cat cw05.sc c3_add.sc > cw051_add.sc
+
+ if (scala_assert "c3.sc")
+ then
+ echo -e " --> success" | tee -a $out
+ tstsB=$(( 0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ cat c$out >> $out
+ tail -25 $out | pr -to10
+ tstsB=$(( 1 ))
+ fi
+fi
+
+if [ $tstsB -eq 0 ]
+then
+ echo -e "3.2) Running mand.ll and check its output" | tee -a $out
+ if (scala_fail "c4.sc")
+ then
+ echo -e " --> success (+ 12.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 12.0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ echo -e " generated:" | tee -a $out
+ cat "mand.ll" | pr -to10
+ #cat c$out >> $out
+ fi
+fi
+
+### mand test
+echo >> $out
+#echo -e "\n\n\n" >> $out
+
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "4.1) Generating ll-file for sqr.fun:\n" | tee -a $out
+ echo >> $out
+ cat cw05.sc c3_add.sc > cw051_add.sc
+
+ if (scala_assert "c5.sc")
+ then
+ echo -e " --> success" | tee -a $out
+ tstsB=$(( 0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ cat c$out >> $out
+ tail -25 $out | pr -to10
+ tstsB=$(( 1 ))
+ fi
+fi
+
+if [ $tstsB -eq 0 ]
+then
+ echo -e "4.2) Running sqr.ll and check its output" | tee -a $out
+ if (scala_fail "c6.sc")
+ then
+ echo -e " --> success (+ 6.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 6.0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ echo -e " generated:" | tee -a $out
+ cat "sqr.ll" | pr -to10
+ #cat c$out >> $out
+ fi
+fi
+
+
+if [ $tsts -eq 0 ]
+then
+ echo -e "5) Does main return an integer in mand.ll (define i32 @main() {...})? " | tee -a $out
+ if (grep "define i32 @main()" "mand.ll" 1> /dev/null 2> /dev/null)
+ then
+ echo -e " --> success (+ 2.0 Marks)\n" | tee -a $out
+ marks=$(( marks + 2.0 ))
+ else
+ echo -e " --> FAIL\n" | tee -a $out
+ #tail -25 $out | pr -to10
+ #cat c$out >> $out
+ fi
+fi
+
+
+## final marks
+echo >> $out
+echo "Overall mark for CW 5" | tee -a $out
+printf " %0.2f\n" $marks | tee -a $out
+
+
+