113 lines
3.8 KiB
C#
113 lines
3.8 KiB
C#
using System;
|
|
using System.Collections.Generic;
|
|
using System.Collections.Immutable;
|
|
using System.Linq;
|
|
using SearchOption = System.IO.SearchOption;
|
|
using Compiler = System.Func<Ast.AstNode, string>;
|
|
using static Global;
|
|
|
|
public static class MainClass {
|
|
public static readonly Dir tests = Dir("Tests/");
|
|
public static readonly Dir tests_results = Dir("tests_results/");
|
|
|
|
public static void CompileToFile (Compiler compile, File source, File dest) {
|
|
source
|
|
.Read()
|
|
.Pipe(Parser.Parse)
|
|
.Pipe(compile)
|
|
.Pipe(c => dest.Write(c));
|
|
}
|
|
|
|
public static bool RunTest(string toolchainName, Compiler compile, Exe runner, File source) {
|
|
var destPath = tests_results.Combine(source);
|
|
var sourcePath = tests.Combine(source);
|
|
var expected = sourcePath.DropExtension().Combine(Ext(".o"));
|
|
|
|
Console.Write($"\x1b[KRunning test {source} ({toolchainName}) ");
|
|
|
|
destPath.DirName().Create();
|
|
|
|
UserErrorException exception = null;
|
|
try {
|
|
CompileToFile(compile, sourcePath, destPath);
|
|
} catch (UserErrorException e) {
|
|
exception = e;
|
|
}
|
|
|
|
if (exception != null) {
|
|
Console.WriteLine("");
|
|
Console.WriteLine("\x1b[1;31mFail\x1b[m");
|
|
Console.WriteLine($"\x1b[1;33m{exception.Message}\x1b[m\n");
|
|
return false;
|
|
} else {
|
|
var actualStr = runner.Run(destPath);
|
|
var expectedStr = expected.Read();
|
|
if (actualStr != expectedStr) {
|
|
Console.WriteLine("\x1b[1;31mFail\x1b[m");
|
|
Console.WriteLine($"\x1b[1;33m{source}: expected {expectedStr} but got {actualStr}.\x1b[m\n");
|
|
return false;
|
|
} else {
|
|
Console.Write("\x1b[1;32mOK\x1b[m\n"); // \r at the end for quiet
|
|
return true;
|
|
}
|
|
}
|
|
}
|
|
|
|
public static void RunTests() {
|
|
// Circumvent bug with collection initializers, tuples and
|
|
// first-class functions by using repeated .Add()
|
|
// See https://repl.it/@suzannesoy/WarlikeWorstTraining#main.cs
|
|
var compilers = ImmutableList<Tuple<string, Compiler, Exe>>.Empty
|
|
.Add(" js ", Compilers.JS.Compile, Exe("node"))
|
|
.Add("eval", Evaluator.EvaluateWrap, Exe("cat"));
|
|
|
|
var total = 0;
|
|
var passed = 0;
|
|
var failed = 0;
|
|
foreach (var t in Dir("Tests/").GetFiles("*.e", SearchOption.AllDirectories).OrderBy(f => f.ToString())) {
|
|
foreach (var compiler in compilers) {
|
|
if (RunTest(compiler.Item1, compiler.Item2, compiler.Item3, t)) {
|
|
passed++;
|
|
} else {
|
|
failed++;
|
|
}
|
|
total++;
|
|
}
|
|
}
|
|
Console.WriteLine($"\x1b[K{passed}/{total} tests passed, {failed} failed.");
|
|
if (failed != 0) {
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
|
|
public static void Main (string[] args) {
|
|
try {
|
|
if (args.Length != 1) {
|
|
Console.WriteLine("Usage: mono main.exe path/to/file.e");
|
|
Console.WriteLine("");
|
|
Console.WriteLine("Language syntax:");
|
|
Console.WriteLine("");
|
|
Console.WriteLine(" Expression =");
|
|
Console.WriteLine(" Int");
|
|
Console.WriteLine(" | String");
|
|
Console.WriteLine(" | true");
|
|
Console.WriteLine(" | false");
|
|
Console.WriteLine(" | Expression && Expression");
|
|
Console.WriteLine("");
|
|
Console.WriteLine("I'll run the tests for you in the meanwhile.");
|
|
Console.WriteLine("");
|
|
RunTests();
|
|
} else {
|
|
var source = args[0].File();
|
|
var destPrefix = source.DropExtension();
|
|
CompileToFile(Compilers.JS.Compile, source, destPrefix.Combine(Ext(".js")));
|
|
CompileToFile(Evaluator.EvaluateWrap, source, destPrefix.Combine(Ext(".txt")));
|
|
Console.Write(destPrefix.Combine(Ext(".txt")).Read());
|
|
}
|
|
} catch (UserErrorException e) {
|
|
Console.WriteLine("");
|
|
Console.WriteLine($"\x1b[1;33m{e.Message}\x1b[m\n");
|
|
Environment.Exit(1);
|
|
}
|
|
}
|
|
} |