feat: merge master
Merge request lab2425_spring/WACC_37!25 Co-authored-by: Gleb Koval <gleb@koval.net>
This commit is contained in:
commit
de181d161d
@ -45,6 +45,7 @@ compile_jvm:
|
|||||||
- .scala-build/
|
- .scala-build/
|
||||||
|
|
||||||
test_jvm:
|
test_jvm:
|
||||||
|
image: gumjoe/wacc-ci-scala:x86
|
||||||
stage: test
|
stage: test
|
||||||
# Use our own runner (not cloud VM or shared) to ensure we have multiple cores.
|
# Use our own runner (not cloud VM or shared) to ensure we have multiple cores.
|
||||||
tags: [ large ]
|
tags: [ large ]
|
||||||
|
@ -3,8 +3,8 @@
|
|||||||
|
|
||||||
// dependencies
|
// dependencies
|
||||||
//> using dep com.github.j-mie6::parsley::5.0.0-M10
|
//> using dep com.github.j-mie6::parsley::5.0.0-M10
|
||||||
//> using dep com.github.j-mie6::parsley-cats::1.3.0
|
//> using dep com.github.j-mie6::parsley-cats::1.5.0
|
||||||
//> using dep com.lihaoyi::os-lib::0.11.3
|
//> using dep com.lihaoyi::os-lib::0.11.4
|
||||||
//> using dep com.github.scopt::scopt::4.1.0
|
//> using dep com.github.scopt::scopt::4.1.0
|
||||||
//> using test.dep org.scalatest::scalatest::3.2.19
|
//> using test.dep org.scalatest::scalatest::3.2.19
|
||||||
|
|
||||||
|
@ -4,6 +4,10 @@ import scala.collection.mutable
|
|||||||
import parsley.{Failure, Success}
|
import parsley.{Failure, Success}
|
||||||
import scopt.OParser
|
import scopt.OParser
|
||||||
import java.io.File
|
import java.io.File
|
||||||
|
import java.io.PrintStream
|
||||||
|
|
||||||
|
import assemblyIR as asm
|
||||||
|
import wacc.microWacc.IntLiter
|
||||||
|
|
||||||
case class CliConfig(
|
case class CliConfig(
|
||||||
file: File = new File(".")
|
file: File = new File(".")
|
||||||
@ -30,7 +34,9 @@ val cliParser = {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
def compile(contents: String): Int = {
|
def frontend(
|
||||||
|
contents: String
|
||||||
|
)(using stdout: PrintStream): Either[microWacc.Program, Int] = {
|
||||||
parser.parse(contents) match {
|
parser.parse(contents) match {
|
||||||
case Success(prog) =>
|
case Success(prog) =>
|
||||||
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
|
given errors: mutable.Builder[Error, List[Error]] = List.newBuilder
|
||||||
@ -39,6 +45,7 @@ def compile(contents: String): Int = {
|
|||||||
val typedProg = typeChecker.check(prog)
|
val typedProg = typeChecker.check(prog)
|
||||||
if (errors.result.nonEmpty) {
|
if (errors.result.nonEmpty) {
|
||||||
given errorContent: String = contents
|
given errorContent: String = contents
|
||||||
|
Right(
|
||||||
errors.result
|
errors.result
|
||||||
.map { error =>
|
.map { error =>
|
||||||
printError(error)
|
printError(error)
|
||||||
@ -48,19 +55,190 @@ def compile(contents: String): Int = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
.max()
|
.max()
|
||||||
} else {
|
)
|
||||||
println(typedProg)
|
} else Left(typedProg)
|
||||||
0
|
|
||||||
}
|
|
||||||
case Failure(msg) =>
|
case Failure(msg) =>
|
||||||
println(msg)
|
stdout.println(msg)
|
||||||
100
|
Right(100)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
val s = "enter an integer to echo"
|
||||||
|
def backend(typedProg: microWacc.Program): List[asm.AsmLine] | String =
|
||||||
|
typedProg match {
|
||||||
|
case microWacc.Program(
|
||||||
|
Nil,
|
||||||
|
microWacc.Call(microWacc.Builtin.Exit, microWacc.IntLiter(v) :: Nil) :: Nil
|
||||||
|
) =>
|
||||||
|
s""".intel_syntax noprefix
|
||||||
|
.globl main
|
||||||
|
main:
|
||||||
|
mov edi, ${v}
|
||||||
|
call exit@plt
|
||||||
|
"""
|
||||||
|
case microWacc.Program(
|
||||||
|
Nil,
|
||||||
|
microWacc.Assign(microWacc.Ident("x", _), microWacc.IntLiter(1)) ::
|
||||||
|
microWacc.Call(microWacc.Builtin.Println, _) ::
|
||||||
|
microWacc.Assign(
|
||||||
|
microWacc.Ident("x", _),
|
||||||
|
microWacc.Call(microWacc.Builtin.ReadInt, Nil)
|
||||||
|
) ::
|
||||||
|
microWacc.Call(microWacc.Builtin.Println, microWacc.Ident("x", _) :: Nil) :: Nil
|
||||||
|
) =>
|
||||||
|
""".intel_syntax noprefix
|
||||||
|
.globl main
|
||||||
|
.section .rodata
|
||||||
|
# length of .L.str0
|
||||||
|
.int 24
|
||||||
|
.L.str0:
|
||||||
|
.asciz "enter an integer to echo"
|
||||||
|
.text
|
||||||
|
main:
|
||||||
|
push rbp
|
||||||
|
# push {rbx, r12}
|
||||||
|
sub rsp, 16
|
||||||
|
mov qword ptr [rsp], rbx
|
||||||
|
mov qword ptr [rsp + 8], r12
|
||||||
|
mov rbp, rsp
|
||||||
|
mov r12d, 1
|
||||||
|
lea rdi, [rip + .L.str0]
|
||||||
|
# statement primitives do not return results (but will clobber r0/rax)
|
||||||
|
call _prints
|
||||||
|
call _println
|
||||||
|
# load the current value in the destination of the read so it supports defaults
|
||||||
|
mov edi, r12d
|
||||||
|
call _readi
|
||||||
|
mov r12d, eax
|
||||||
|
mov edi, eax
|
||||||
|
# statement primitives do not return results (but will clobber r0/rax)
|
||||||
|
call _printi
|
||||||
|
call _println
|
||||||
|
mov rax, 0
|
||||||
|
# pop/peek {rbx, r12}
|
||||||
|
mov rbx, qword ptr [rsp]
|
||||||
|
mov r12, qword ptr [rsp + 8]
|
||||||
|
add rsp, 16
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
# length of .L._printi_str0
|
||||||
|
.int 2
|
||||||
|
.L._printi_str0:
|
||||||
|
.asciz "%d"
|
||||||
|
.text
|
||||||
|
_printi:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
||||||
|
and rsp, -16
|
||||||
|
mov esi, edi
|
||||||
|
lea rdi, [rip + .L._printi_str0]
|
||||||
|
# on x86, al represents the number of SIMD registers used as variadic arguments
|
||||||
|
mov al, 0
|
||||||
|
call printf@plt
|
||||||
|
mov rdi, 0
|
||||||
|
call fflush@plt
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
# length of .L._prints_str0
|
||||||
|
.int 4
|
||||||
|
.L._prints_str0:
|
||||||
|
.asciz "%.*s"
|
||||||
|
.text
|
||||||
|
_prints:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
||||||
|
and rsp, -16
|
||||||
|
mov rdx, rdi
|
||||||
|
mov esi, dword ptr [rdi - 4]
|
||||||
|
lea rdi, [rip + .L._prints_str0]
|
||||||
|
# on x86, al represents the number of SIMD registers used as variadic arguments
|
||||||
|
mov al, 0
|
||||||
|
call printf@plt
|
||||||
|
mov rdi, 0
|
||||||
|
call fflush@plt
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
# length of .L._println_str0
|
||||||
|
.int 0
|
||||||
|
.L._println_str0:
|
||||||
|
.asciz ""
|
||||||
|
.text
|
||||||
|
_println:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
||||||
|
and rsp, -16
|
||||||
|
lea rdi, [rip + .L._println_str0]
|
||||||
|
call puts@plt
|
||||||
|
mov rdi, 0
|
||||||
|
call fflush@plt
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
|
||||||
|
.section .rodata
|
||||||
|
# length of .L._readi_str0
|
||||||
|
.int 2
|
||||||
|
.L._readi_str0:
|
||||||
|
.asciz "%d"
|
||||||
|
.text
|
||||||
|
_readi:
|
||||||
|
push rbp
|
||||||
|
mov rbp, rsp
|
||||||
|
# external calls must be stack-aligned to 16 bytes, accomplished by masking with fffffffffffffff0
|
||||||
|
and rsp, -16
|
||||||
|
# RDI contains the "original" value of the destination of the read
|
||||||
|
# allocate space on the stack to store the read: preserve alignment!
|
||||||
|
# the passed default argument should be stored in case of EOF
|
||||||
|
sub rsp, 16
|
||||||
|
mov dword ptr [rsp], edi
|
||||||
|
lea rsi, qword ptr [rsp]
|
||||||
|
lea rdi, [rip + .L._readi_str0]
|
||||||
|
# on x86, al represents the number of SIMD registers used as variadic arguments
|
||||||
|
mov al, 0
|
||||||
|
call scanf@plt
|
||||||
|
mov eax, dword ptr [rsp]
|
||||||
|
add rsp, 16
|
||||||
|
mov rsp, rbp
|
||||||
|
pop rbp
|
||||||
|
ret
|
||||||
|
"""
|
||||||
|
case _ => List()
|
||||||
|
}
|
||||||
|
|
||||||
|
def compile(filename: String, outFile: Option[File] = None)(using
|
||||||
|
stdout: PrintStream = Console.out
|
||||||
|
): Int =
|
||||||
|
frontend(os.read(os.Path(filename))) match {
|
||||||
|
case Left(typedProg) =>
|
||||||
|
val asmFile = outFile.getOrElse(File(filename.stripSuffix(".wacc") + ".s"))
|
||||||
|
backend(typedProg) match {
|
||||||
|
case s: String =>
|
||||||
|
os.write.over(os.Path(asmFile.getAbsolutePath), s)
|
||||||
|
case ops: List[asm.AsmLine] => {
|
||||||
|
writer.writeTo(ops, PrintStream(asmFile))
|
||||||
|
}
|
||||||
|
}
|
||||||
|
0
|
||||||
|
case Right(exitCode) => exitCode
|
||||||
|
}
|
||||||
|
|
||||||
def main(args: Array[String]): Unit =
|
def main(args: Array[String]): Unit =
|
||||||
OParser.parse(cliParser, args, CliConfig()) match {
|
OParser.parse(cliParser, args, CliConfig()) match {
|
||||||
case Some(config) =>
|
case Some(config) =>
|
||||||
System.exit(compile(os.read(os.Path(config.file.getAbsolutePath))))
|
compile(
|
||||||
|
config.file.getAbsolutePath,
|
||||||
|
outFile = Some(File(".", config.file.getName.stripSuffix(".wacc") + ".s"))
|
||||||
|
)
|
||||||
case None =>
|
case None =>
|
||||||
}
|
}
|
||||||
|
@ -2,6 +2,7 @@ package wacc
|
|||||||
|
|
||||||
import wacc.ast.Position
|
import wacc.ast.Position
|
||||||
import wacc.types._
|
import wacc.types._
|
||||||
|
import java.io.PrintStream
|
||||||
|
|
||||||
/** Error types for semantic errors
|
/** Error types for semantic errors
|
||||||
*/
|
*/
|
||||||
@ -23,39 +24,39 @@ enum Error {
|
|||||||
* @param errorContent
|
* @param errorContent
|
||||||
* Contents of the file to generate code snippets
|
* Contents of the file to generate code snippets
|
||||||
*/
|
*/
|
||||||
def printError(error: Error)(using errorContent: String): Unit = {
|
def printError(error: Error)(using errorContent: String, stdout: PrintStream): Unit = {
|
||||||
println("Semantic error:")
|
stdout.println("Semantic error:")
|
||||||
error match {
|
error match {
|
||||||
case Error.DuplicateDeclaration(ident) =>
|
case Error.DuplicateDeclaration(ident) =>
|
||||||
printPosition(ident.pos)
|
printPosition(ident.pos)
|
||||||
println(s"Duplicate declaration of identifier ${ident.v}")
|
stdout.println(s"Duplicate declaration of identifier ${ident.v}")
|
||||||
highlight(ident.pos, ident.v.length)
|
highlight(ident.pos, ident.v.length)
|
||||||
case Error.UndeclaredVariable(ident) =>
|
case Error.UndeclaredVariable(ident) =>
|
||||||
printPosition(ident.pos)
|
printPosition(ident.pos)
|
||||||
println(s"Undeclared variable ${ident.v}")
|
stdout.println(s"Undeclared variable ${ident.v}")
|
||||||
highlight(ident.pos, ident.v.length)
|
highlight(ident.pos, ident.v.length)
|
||||||
case Error.UndefinedFunction(ident) =>
|
case Error.UndefinedFunction(ident) =>
|
||||||
printPosition(ident.pos)
|
printPosition(ident.pos)
|
||||||
println(s"Undefined function ${ident.v}")
|
stdout.println(s"Undefined function ${ident.v}")
|
||||||
highlight(ident.pos, ident.v.length)
|
highlight(ident.pos, ident.v.length)
|
||||||
case Error.FunctionParamsMismatch(id, expected, got, funcType) =>
|
case Error.FunctionParamsMismatch(id, expected, got, funcType) =>
|
||||||
printPosition(id.pos)
|
printPosition(id.pos)
|
||||||
println(s"Function expects $expected parameters, got $got")
|
stdout.println(s"Function expects $expected parameters, got $got")
|
||||||
println(
|
stdout.println(
|
||||||
s"(function ${id.v} has type (${funcType.params.mkString(", ")}) -> ${funcType.returnType})"
|
s"(function ${id.v} has type (${funcType.params.mkString(", ")}) -> ${funcType.returnType})"
|
||||||
)
|
)
|
||||||
highlight(id.pos, 1)
|
highlight(id.pos, 1)
|
||||||
case Error.TypeMismatch(pos, expected, got, msg) =>
|
case Error.TypeMismatch(pos, expected, got, msg) =>
|
||||||
printPosition(pos)
|
printPosition(pos)
|
||||||
println(s"Type mismatch: $msg\nExpected: $expected\nGot: $got")
|
stdout.println(s"Type mismatch: $msg\nExpected: $expected\nGot: $got")
|
||||||
highlight(pos, 1)
|
highlight(pos, 1)
|
||||||
case Error.SemanticError(pos, msg) =>
|
case Error.SemanticError(pos, msg) =>
|
||||||
printPosition(pos)
|
printPosition(pos)
|
||||||
println(msg)
|
stdout.println(msg)
|
||||||
highlight(pos, 1)
|
highlight(pos, 1)
|
||||||
case wacc.Error.InternalError(pos, msg) =>
|
case wacc.Error.InternalError(pos, msg) =>
|
||||||
printPosition(pos)
|
printPosition(pos)
|
||||||
println(s"Internal error: $msg")
|
stdout.println(s"Internal error: $msg")
|
||||||
highlight(pos, 1)
|
highlight(pos, 1)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -70,7 +71,7 @@ def printError(error: Error)(using errorContent: String): Unit = {
|
|||||||
* @param errorContent
|
* @param errorContent
|
||||||
* Contents of the file to generate code snippets
|
* Contents of the file to generate code snippets
|
||||||
*/
|
*/
|
||||||
def highlight(pos: Position, size: Int)(using errorContent: String): Unit = {
|
def highlight(pos: Position, size: Int)(using errorContent: String, stdout: PrintStream): Unit = {
|
||||||
val lines = errorContent.split("\n")
|
val lines = errorContent.split("\n")
|
||||||
|
|
||||||
val preLine = if (pos.line > 1) lines(pos.line - 2) else ""
|
val preLine = if (pos.line > 1) lines(pos.line - 2) else ""
|
||||||
@ -78,7 +79,7 @@ def highlight(pos: Position, size: Int)(using errorContent: String): Unit = {
|
|||||||
val postLine = if (pos.line < lines.size) lines(pos.line) else ""
|
val postLine = if (pos.line < lines.size) lines(pos.line) else ""
|
||||||
val linePointer = " " * (pos.column + 2) + ("^" * (size)) + "\n"
|
val linePointer = " " * (pos.column + 2) + ("^" * (size)) + "\n"
|
||||||
|
|
||||||
println(
|
stdout.println(
|
||||||
s" >$preLine\n >$midLine\n$linePointer >$postLine"
|
s" >$preLine\n >$midLine\n$linePointer >$postLine"
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@ -88,6 +89,6 @@ def highlight(pos: Position, size: Int)(using errorContent: String): Unit = {
|
|||||||
* @param pos
|
* @param pos
|
||||||
* Position of the error
|
* Position of the error
|
||||||
*/
|
*/
|
||||||
def printPosition(pos: Position): Unit = {
|
def printPosition(pos: Position)(using stdout: PrintStream): Unit = {
|
||||||
println(s"(line ${pos.line}, column ${pos.column}):")
|
stdout.println(s"(line ${pos.line}, column ${pos.column}):")
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,9 @@ package wacc
|
|||||||
import org.scalatest.{ParallelTestExecution, BeforeAndAfterAll}
|
import org.scalatest.{ParallelTestExecution, BeforeAndAfterAll}
|
||||||
import org.scalatest.flatspec.AnyFlatSpec
|
import org.scalatest.flatspec.AnyFlatSpec
|
||||||
import org.scalatest.Inspectors.forEvery
|
import org.scalatest.Inspectors.forEvery
|
||||||
|
import java.io.File
|
||||||
|
import sys.process._
|
||||||
|
import java.io.PrintStream
|
||||||
|
|
||||||
class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with ParallelTestExecution {
|
class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with ParallelTestExecution {
|
||||||
val files =
|
val files =
|
||||||
@ -20,12 +23,51 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
|
|||||||
}
|
}
|
||||||
|
|
||||||
// tests go here
|
// tests go here
|
||||||
forEvery(files.filter { (filename, _) =>
|
forEvery(files) { (filename, expectedResult) =>
|
||||||
!fileIsDissallowed(filename)
|
val baseFilename = filename.stripSuffix(".wacc")
|
||||||
}) { (filename, expectedResult) =>
|
given stdout: PrintStream = PrintStream(File(baseFilename + ".out"))
|
||||||
s"$filename" should "be parsed with correct result" in {
|
val result = compile(filename)
|
||||||
val contents = os.read(os.Path(filename))
|
|
||||||
assert(expectedResult.contains(compile(contents)))
|
s"$filename" should "be compiled with correct result" in {
|
||||||
|
assert(expectedResult.contains(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result == 0) it should "run with correct result" in {
|
||||||
|
if (fileIsDisallowedBackend(filename)) pending
|
||||||
|
|
||||||
|
// Retrieve contents to get input and expected output + exit code
|
||||||
|
val contents = scala.io.Source.fromFile(File(filename)).getLines.toList
|
||||||
|
val inputLine =
|
||||||
|
contents.find(_.matches("^# ?[Ii]nput:.*$")).map(_.split(":").last.strip).getOrElse("")
|
||||||
|
val outputLineIdx = contents.indexWhere(_.matches("^# ?[Oo]utput:.*$"))
|
||||||
|
val expectedOutput =
|
||||||
|
if (outputLineIdx == -1) ""
|
||||||
|
else
|
||||||
|
contents
|
||||||
|
.drop(outputLineIdx + 1)
|
||||||
|
.takeWhile(_.startsWith("#"))
|
||||||
|
.map(_.stripPrefix("#").stripLeading)
|
||||||
|
.mkString("\n")
|
||||||
|
|
||||||
|
val exitLineIdx = contents.indexWhere(_.matches("^# ?[Ee]xit:.*$"))
|
||||||
|
val expectedExit =
|
||||||
|
if (exitLineIdx == -1) 0
|
||||||
|
else contents(exitLineIdx + 1).stripPrefix("#").strip.toInt
|
||||||
|
|
||||||
|
// Assembly and link using gcc
|
||||||
|
val asmFilename = baseFilename + ".s"
|
||||||
|
val execFilename = baseFilename
|
||||||
|
val gccResult = s"gcc -o $execFilename -z noexecstack $asmFilename".!
|
||||||
|
assert(gccResult == 0)
|
||||||
|
|
||||||
|
// Run the executable with the provided input
|
||||||
|
val stdout = new StringBuilder
|
||||||
|
// val execResult = s"$execFilename".!(ProcessLogger(stdout.append(_)))
|
||||||
|
val execResult =
|
||||||
|
s"echo $inputLine" #| s"timeout 5s $execFilename" ! ProcessLogger(stdout.append(_))
|
||||||
|
|
||||||
|
assert(execResult == expectedExit)
|
||||||
|
assert(stdout.toString == expectedOutput)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -33,57 +75,27 @@ class ParallelExamplesSpec extends AnyFlatSpec with BeforeAndAfterAll with Paral
|
|||||||
val d = java.io.File(dir)
|
val d = java.io.File(dir)
|
||||||
os.walk(os.Path(d.getAbsolutePath)).filter { _.ext == "wacc" }
|
os.walk(os.Path(d.getAbsolutePath)).filter { _.ext == "wacc" }
|
||||||
|
|
||||||
def fileIsDissallowed(filename: String): Boolean =
|
def fileIsDisallowedBackend(filename: String): Boolean =
|
||||||
Seq(
|
Seq(
|
||||||
// format: off
|
// format: off
|
||||||
// disable formatting to avoid binPack
|
// disable formatting to avoid binPack
|
||||||
// "wacc-examples/valid/advanced",
|
"^.*wacc-examples/valid/advanced.*$",
|
||||||
// "wacc-examples/valid/array",
|
"^.*wacc-examples/valid/array.*$",
|
||||||
// "wacc-examples/valid/basic/exit",
|
"^.*wacc-examples/valid/basic/skip.*$",
|
||||||
// "wacc-examples/valid/basic/skip",
|
"^.*wacc-examples/valid/expressions.*$",
|
||||||
// "wacc-examples/valid/expressions",
|
"^.*wacc-examples/valid/function/nested_functions.*$",
|
||||||
// "wacc-examples/valid/function/nested_functions",
|
"^.*wacc-examples/valid/function/simple_functions.*$",
|
||||||
// "wacc-examples/valid/function/simple_functions",
|
"^.*wacc-examples/valid/if.*$",
|
||||||
// "wacc-examples/valid/if",
|
"^.*wacc-examples/valid/IO/print.*$",
|
||||||
// "wacc-examples/valid/IO/print",
|
"^.*wacc-examples/valid/IO/read(?!echoInt\\.wacc).*$",
|
||||||
// "wacc-examples/valid/IO/read",
|
"^.*wacc-examples/valid/IO/IOLoop.wacc.*$",
|
||||||
// "wacc-examples/valid/IO/IOLoop.wacc",
|
"^.*wacc-examples/valid/IO/IOSequence.wacc.*$",
|
||||||
// "wacc-examples/valid/IO/IOSequence.wacc",
|
"^.*wacc-examples/valid/pairs.*$",
|
||||||
// "wacc-examples/valid/pairs",
|
"^.*wacc-examples/valid/runtimeErr.*$",
|
||||||
// "wacc-examples/valid/runtimeErr",
|
"^.*wacc-examples/valid/scope.*$",
|
||||||
// "wacc-examples/valid/scope",
|
"^.*wacc-examples/valid/sequence.*$",
|
||||||
// "wacc-examples/valid/sequence",
|
"^.*wacc-examples/valid/variables.*$",
|
||||||
// "wacc-examples/valid/variables",
|
"^.*wacc-examples/valid/while.*$",
|
||||||
// "wacc-examples/valid/while",
|
|
||||||
// invalid (syntax)
|
|
||||||
// "wacc-examples/invalid/syntaxErr/array",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/basic",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/expressions",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/function",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/if",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/literals",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/pairs",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/print",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/sequence",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/variables",
|
|
||||||
// "wacc-examples/invalid/syntaxErr/while",
|
|
||||||
// invalid (semantic)
|
|
||||||
// "wacc-examples/invalid/semanticErr/array",
|
|
||||||
// "wacc-examples/invalid/semanticErr/exit",
|
|
||||||
// "wacc-examples/invalid/semanticErr/expressions",
|
|
||||||
// "wacc-examples/invalid/semanticErr/function",
|
|
||||||
// "wacc-examples/invalid/semanticErr/if",
|
|
||||||
// "wacc-examples/invalid/semanticErr/IO",
|
|
||||||
// "wacc-examples/invalid/semanticErr/multiple",
|
|
||||||
// "wacc-examples/invalid/semanticErr/pairs",
|
|
||||||
// "wacc-examples/invalid/semanticErr/print",
|
|
||||||
// "wacc-examples/invalid/semanticErr/read",
|
|
||||||
// "wacc-examples/invalid/semanticErr/scope",
|
|
||||||
// "wacc-examples/invalid/semanticErr/variables",
|
|
||||||
// "wacc-examples/invalid/semanticErr/while",
|
|
||||||
// invalid (whack)
|
|
||||||
// "wacc-examples/invalid/whack"
|
|
||||||
// format: on
|
// format: on
|
||||||
// format: on
|
).find(filename.matches).isDefined
|
||||||
).find(filename.contains).isDefined
|
|
||||||
}
|
}
|
||||||
|
1
wacc.target
Normal file
1
wacc.target
Normal file
@ -0,0 +1 @@
|
|||||||
|
x86-64
|
Loading…
x
Reference in New Issue
Block a user