// 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)
}