-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
Showing
3 changed files
with
185 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,88 @@ | ||
namespace NetLMC; | ||
using System.Reflection; | ||
|
||
public static class Tester | ||
{ | ||
public enum Result | ||
{ | ||
PASS, | ||
FAIL, | ||
CRASH, | ||
}; | ||
|
||
public struct ExpectedAction | ||
{ | ||
public bool isInput; | ||
public int value; | ||
} | ||
|
||
[System.Serializable] | ||
private class TesterException : System.Exception | ||
{ | ||
public TesterException() { } | ||
public TesterException(string message) : base(message) { } | ||
public TesterException(string message, System.Exception inner) : base(message, inner) { } | ||
protected TesterException( | ||
System.Runtime.Serialization.SerializationInfo info, | ||
System.Runtime.Serialization.StreamingContext context) : base(info, context) { } | ||
} | ||
|
||
private class ValidatorInterface : IInterface | ||
{ | ||
private readonly IEnumerator<ExpectedAction> actions; | ||
|
||
public ValidatorInterface(IEnumerable<ExpectedAction> action) | ||
{ | ||
this.actions = action.GetEnumerator(); | ||
} | ||
|
||
public ValidatorInterface(IEnumerator<ExpectedAction> action) | ||
{ | ||
this.actions = action; | ||
} | ||
|
||
public int Input() | ||
{ | ||
if (!actions.MoveNext() || !actions.Current.isInput) { throw new TesterException("Unexpected input request."); } | ||
|
||
return actions.Current.value; | ||
} | ||
|
||
public void Output(int v) | ||
{ | ||
if (!actions.MoveNext() || actions.Current.isInput) { throw new TesterException("Unexpected output"); } | ||
|
||
if (actions.Current.value != v) { throw new TesterException($"Output {v} != expected {actions.Current.value}"); } | ||
} | ||
|
||
public void DebugLog(string _) { } | ||
|
||
public void CheckDone() | ||
{ | ||
if (actions.MoveNext()) { throw new TesterException("Unexpected end of program."); } | ||
} | ||
} | ||
|
||
public static Result RunTest(IEnumerator<ExpectedAction> actions, ref Interpreter.InterpreterState state) | ||
{ | ||
var iface = new ValidatorInterface(actions); | ||
try | ||
{ | ||
Interpreter.Run(ref state, iface); | ||
iface.CheckDone(); | ||
} | ||
catch (TesterException) | ||
{ | ||
return Result.FAIL; | ||
} | ||
catch | ||
{ | ||
return Result.CRASH; | ||
} | ||
|
||
return Result.PASS; | ||
} | ||
|
||
public static ExpectedAction In(int v) => new() { isInput = true, value = v }; | ||
public static ExpectedAction Out(int v) => new() { isInput = false, value = v }; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,66 @@ | ||
namespace NetLMC; | ||
|
||
public static class Test | ||
{ | ||
public static readonly Dictionary<string, Action<Interpreter.InterpreterState>> Tests = new() | ||
{ | ||
{ "Polynomial", TestAllPolynomials }, | ||
}; | ||
|
||
public static IEnumerator<Tester.ExpectedAction> Polynomial(int a, int b, int c, int x) | ||
{ | ||
yield return Tester.In(a); | ||
yield return Tester.In(b); | ||
yield return Tester.In(c); | ||
yield return Tester.In(x); | ||
yield return Tester.Out(Math.Clamp(a + b*x + c*x*x, 0, 999)); | ||
} | ||
|
||
public static void TestAllPolynomials(Interpreter.InterpreterState inState) | ||
{ | ||
long totalPass = 0, totalFail = 0, totalCrash = 0; | ||
object ioLock = new(); | ||
|
||
Parallel.For(0, 1000, (int x, ParallelLoopState parallelState) => | ||
{ | ||
long total = totalPass + totalFail + totalCrash; | ||
lock (ioLock) | ||
{ | ||
Console.WriteLine($"Done: {total}, Pass: {totalPass}, Remain: {1_000_000_000_000 - total}"); | ||
} | ||
long numPass = 0, numFail = 0, numCrash = 0; | ||
var state = inState; | ||
for (int a = 0; a < 1000; a++) | ||
{ | ||
for (int b = 0; b < 1000; b++) | ||
{ | ||
for (int c = 0; c < 1000; c++) | ||
{ | ||
state.pc = 0; | ||
state.calc = 0; | ||
var res = Tester.RunTest(Polynomial(a, b, c, x), ref state); | ||
switch (res) | ||
{ | ||
case Tester.Result.PASS: | ||
numPass++; | ||
break; | ||
case Tester.Result.FAIL: | ||
numFail++; | ||
break; | ||
case Tester.Result.CRASH: | ||
numCrash++; | ||
break; | ||
} | ||
} | ||
} | ||
} | ||
Interlocked.Add(ref totalPass, numPass); | ||
Interlocked.Add(ref totalFail, numFail); | ||
Interlocked.Add(ref totalCrash, numCrash); | ||
}); | ||
|
||
Console.WriteLine($"Pass: {totalPass}, Fail: {totalFail}, Crash: {totalCrash}"); | ||
} | ||
} |