/cvml/Tests.cs
C# | 302 lines | 266 code | 30 blank | 6 comment | 22 complexity | 8b7e1effd65cdd68686ca1e4927cc555 MD5 | raw file
- using System;
- using System.Collections.Generic;
- using System.Linq;
- using System.Text;
-
- using System.Diagnostics;
-
- namespace CVML
- {
- public class Tester
- {
- public void RunTests()
- {
- RunTest("one", 1);
- RunTest("two", 2);
- RunTest("zero", 0);
- RunTest("neg1", -1);
- RunTest("5", 5);
- RunTest("5 inc", 6);
- RunTest("5 dec", 4);
- RunTest("5 2 add", 7);
- RunTest("2 5 sub", 3);
- RunTest("5 2 sub", -3);
- RunTest("5 2 mul", 10);
- RunTest("2 5 div", 2);
- RunTest("5 2 div", 0);
- RunTest("5 2 mod", 2);
- RunTest("2 5 mod", 1);
- RunTest("2 5 shl", 20);
- RunTest("2 5 shr", 1);
- RunTest("(1 2 3) count", 3);
- RunTest("(1 2 3) 0 getat", 1);
- RunTest("(1 2 3) 1 getat", 2);
- RunTest("() count", 0);
- RunTest("() empty", 1);
- RunTest("(5) poplist", 5);
- RunTest("(5) count", 1);
- RunTest("(5) empty", 0);
- RunTest("(5) poplist pop count", 0);
- RunTest("() 5 pushlist count", 1);
- RunTest("() 5 pushlist 0 getat", 5);
- RunTest("() 5 pushlist dup 0 getat", 5);
- RunTest("() 5 pushlist dup 6 pushlist count", 2);
- RunTest("[1 2 add] call", 3);
- RunTest("[1 2] call add", 3);
- RunTest("1 3 5 if", 3);
- RunTest("2 3 5 if", 3);
- RunTest("0 3 5 if", 5);
- RunTest("5 0 [pop 3] ift", 5);
- RunTest("5 1 [pop 3] ift", 3);
- RunTest("0 [3] [5] ifte", 5);
- RunTest("1 [3] [5] ifte", 3);
- RunTest("3 5 0 [add] [mul] ifte", 15);
- RunTest("3 5 1 [add] [mul] ifte", 8);
- RunTest("42 10 [dec] while", 42);
- RunTest("0 10 [dec swap inc swap] while", 10);
- RunTest("{1:10 2:20 3:30} 1 tblfind", 10);
- RunTest("1 2 gt", 1);
- RunTest("2 1 gt", 0);
- RunTest("2 2 gt", 0);
- RunTest("2 2 eq", 1);
- RunTest("1 2 eq", 0);
- RunTest("2 2 neq", 0);
- RunTest("1 2 neq", 1);
- RunTest("2 2 gteq", 1);
- RunTest("2 2 lteq", 1);
- RunTest("3 2 lteq", 1);
- RunTest("3 2 lt", 1);
- RunTest("2 3 lt", 0);
- RunTest("two", 2);
- RunTest("f=[1] f call f call add", 2);
- RunTest("1 2 3 4 swapN%1", 3);
- RunTest("1 2 3 4 swapN%2", 2);
- RunTest("1 2 3 4 swapN%3", 1);
- RunTest("1 2 3 4 swapNM%1%2 pop", 2);
- RunTest("[1] [2] store", 1);
- RunTest("[1 swap restore] [2] store", 2);
- RunTest("() [pushlist] [] store count", 1);
- RunTest("() [pushlist store poplist restore] [] count", 0);
- RunTest("[1] [0] store 13 14 if", 13);
- RunTest("[1 swap restore] [0] store 13 14 if", 14);
-
- // Other incorrectly written tests.
- //RunTest("callcc=[store swap call] 13 [99 swap restore] callcc call", 13);
- //RunTest("13 store 99 swap restore", 13);
-
- // Incorrectly written tests, illustrate that it is stupidly hard to do something easy.
- //RunTest("gtz=[0 swap gt swap pop] 5 gtz call", 1);
- //RunTest("gtz=[0 swap gt swap pop] 5 gtz call pop", 5);
- }
-
- public void GetBinaryRep(StringBuilder sb,string title, byte[] block)
- {
- sb.AppendFormat("{0}, size = {1}", title, block.Length);
- sb.AppendLine();
- for (int i=0; i < block.Length; ++i)
- {
- var b = block[i];
- if (i > 0)
- {
- if (i % 8 == 0)
- sb.AppendLine();
- else
- sb.Append(' ');
- }
- sb.Append(b.ToString("x2"));
- }
- sb.AppendLine();
- }
-
- public string ObjToString(CVM.Object o)
- {
- if (o.Null)
- return "null";
- var sb = new StringBuilder();
- sb.Append(o.TypeString);
- sb.AppendFormat("${0}[{1}]", o.Id, o.Count);
- if (o.Deleted)
- sb.Append("!Deleted");
- sb.AppendFormat("#{0}", o.Refs);
- return sb.ToString();
- }
-
- public string TblToString(CVM.Table tbl)
- {
- StringBuilder sb = new StringBuilder();
- var kvs = tbl.KeyValues;
- sb.Append("{ ");
- foreach (var kv in kvs)
- {
- sb.Append(kv.Key.ToString());
- sb.Append(':');
- sb.Append(ValToString(kv.Value));
- sb.Append(' ');
- }
- sb.Append('}');
- return sb.ToString();
- }
-
- public string ValToString(CVM.Val val)
- {
- if (val.IsInt)
- return val.ToInt().ToString();
- else
- return ObjToString(val.ToObject());
- }
-
- StringBuilder BuildStackRep(List<CVM.Val> vals, StringBuilder sb)
- {
- for (int i=0; i < vals.Count; ++i)
- {
- if (i > 0) sb.Append(' ');
- string s = ValToString(vals[vals.Count - i - 1]);
- sb.Append(s);
- }
- return sb;
- }
-
- public void PrintVMCode(CVM.VM vm) {
- Console.WriteLine("VM loaded code");
- Console.WriteLine(vm.CodeString);
- }
-
- public void PrintVMConstants(CVM.VM vm)
- {
- var sb = new StringBuilder();
- foreach (var k in vm.Constants)
- sb.Append(ObjToString(k)).Append(' ');
-
- Console.WriteLine("Constants");
- Console.WriteLine(sb.ToString());
- }
-
- public void PrintVMMemory(CVM.VM vm)
- {
- var sb = new StringBuilder();
- var m = vm.GetHeapMemory();
- foreach (var o in m)
- sb.Append(ObjToString(o)).Append(' ');
- Console.WriteLine("Heap memory:");
- Console.WriteLine(" " + sb.ToString());
- }
-
- public void InspectStore(CVM.Val store)
- {
- var obj = store.ToObject();
- var bytes = obj.ArrayBytes;
- var dis = new ByteFileDisassembler(bytes);
- Console.WriteLine("code size: " + dis.code.Count);
- Console.WriteLine("ip: " + dis.ip);
- Console.WriteLine("constants size: " + dis.constants.Count);
- for (int i = 0; i < dis.constants.Count; ++i)
- {
- Console.Write(dis.constants[i]);
- Console.Write(' ');
- }
- Console.WriteLine();
- Console.WriteLine("stack size: " + dis.stack.Count);
- for (int i=0; i < dis.stack.Count; ++i) {
- Console.Write(dis.stack[i]);
- Console.Write(' ');
- }
- Console.WriteLine();
- Console.WriteLine("auxiliary stack size: " + dis.aux.Count);
- for (int i = 0; i < dis.aux.Count; ++i)
- {
- Console.Write(dis.aux[i]);
- Console.Write(' ');
- }
- Console.WriteLine();
- Console.WriteLine("array data size: " + dis.adata.Count);
- for (int i = 0; i < dis.adata.Count; ++i)
- {
- var a = dis.adata[i];
- Console.Write("array size: ");
- Console.Write(a.Length);
- Console.Write(' ');
- for (int j = 0; j < a.Length; ++j)
- {
- Console.Write(a[j]);
- Console.Write(' ');
- }
- Console.WriteLine();
- }
- Console.WriteLine();
- Console.WriteLine("object data size: " + dis.odata.Count);
- for (int i = 0; i < dis.odata.Count; ++i)
- {
- Console.Write(dis.odata[i].ToString());
- Console.Write(' ');
- }
- Console.WriteLine();
- }
-
- public void PrintVMState(CVM.VM vm)
- {
- Console.WriteLine("------------------------");
- PrintVMMemory(vm);
-
- StringBuilder sb = new StringBuilder();
-
- if (vm.CurOp.Code == CVM.OpCode.Op_restore)
- InspectStore(vm.At(0));
-
- sb.AppendFormat("ip = {0}", vm.IP).AppendLine();
- sb.AppendFormat("op = {0}", vm.CurOp.ToString()).AppendLine();
- sb.Append("stack: ");
- BuildStackRep(vm.Stack, sb);
- Console.WriteLine(sb.ToString());
- sb = new StringBuilder();
- sb.Append("aux: ");
- BuildStackRep(vm.AuxStack, sb);
- Console.WriteLine(sb.ToString());
- }
-
- public void RunTest(string input, int output)
- {
- List<Term> terms = Parser.ParseString(input);
- var ts = from t in terms select t.ToString();
-
- Console.WriteLine("Test Input (terms)");
- Console.WriteLine(string.Join(" ", ts.ToArray()));
- var bf = new ByteFile(terms);
-
- Console.WriteLine("Byte File representation");
- Console.WriteLine(bf.ToString());
-
- var vm = new CVM.VM();
-
- byte[] data = bf.GetBytes();
-
- vm.Load(data);
-
- PrintVMCode(vm);
- PrintVMConstants(vm);
-
- PrintVMState(vm);
- while (vm.Next())
- PrintVMState(vm);
-
- try
- {
- if (vm.Count < 1)
- throw new Exception("expected at least one item on the stack");
-
- CVM.Val v = vm.At(0);
- if (!v.IsInt)
- throw new Exception("expected an int");
-
- int n = v.ToInt();
- if (n != output)
- throw new Exception(String.Format("Expected {0} but got {1}", output, n));
-
- Console.WriteLine("Test passed");
- }
- catch (Exception e)
- {
- Console.WriteLine("Test failed " + e.Message);
- }
- }
- }
- }