-
-
Notifications
You must be signed in to change notification settings - Fork 66
/
Program.cs
177 lines (147 loc) · 5.04 KB
/
Program.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
using System;
using Miniscript;
using System.IO;
using System.Collections.Generic;
class MainClass {
static void Print(string s, bool lineBreak=true) {
if (lineBreak) Console.WriteLine(s);
else Console.Write(s);
}
static void ListErrors(Script script) {
if (script.errors == null) {
Print("No errors.");
return;
}
foreach (Error err in script.errors) {
Print(string.Format("{0} on line {1}: {2}",
err.type, err.lineNum, err.description));
}
}
static void Test(List<string> sourceLines, int sourceLineNum,
List<string> expectedOutput, int outputLineNum) {
if (expectedOutput == null) expectedOutput = new List<string>();
// Console.WriteLine("TEST (LINE {0}):", sourceLineNum);
// Console.WriteLine(string.Join("\n", sourceLines));
// Console.WriteLine("EXPECTING (LINE {0}):", outputLineNum);
// Console.WriteLine(string.Join("\n", expectedOutput));
Interpreter miniscript = new Interpreter(sourceLines);
List<string> actualOutput = new List<string>();
miniscript.standardOutput = (string s, bool eol) => actualOutput.Add(s);
miniscript.errorOutput = miniscript.standardOutput;
miniscript.implicitOutput = miniscript.standardOutput;
miniscript.RunUntilDone(60, false);
// Console.WriteLine("ACTUAL OUTPUT:");
// Console.WriteLine(string.Join("\n", actualOutput));
int minLen = expectedOutput.Count < actualOutput.Count ? expectedOutput.Count : actualOutput.Count;
for (int i = 0; i < minLen; i++) {
if (actualOutput[i] != expectedOutput[i]) {
Print(string.Format("TEST FAILED AT LINE {0}\n EXPECTED: {1}\n ACTUAL: {2}",
outputLineNum + i, expectedOutput[i], actualOutput[i]));
}
}
if (expectedOutput.Count > actualOutput.Count) {
Print(string.Format("TEST FAILED: MISSING OUTPUT AT LINE {0}", outputLineNum + actualOutput.Count));
for (int i = actualOutput.Count; i < expectedOutput.Count; i++) {
Print(" MISSING: " + expectedOutput[i]);
}
} else if (actualOutput.Count > expectedOutput.Count) {
Print(string.Format("TEST FAILED: EXTRA OUTPUT AT LINE {0}", outputLineNum + expectedOutput.Count));
for (int i = expectedOutput.Count; i < actualOutput.Count; i++) {
Print(" EXTRA: " + actualOutput[i]);
}
}
}
static void RunTestSuite(string path) {
StreamReader file = new StreamReader(path);
if (file == null) {
Print("Unable to read: " + path);
return;
}
List<string> sourceLines = null;
List<string> expectedOutput = null;
int testLineNum = 0;
int outputLineNum = 0;
string line = file.ReadLine();
int lineNum = 1;
while (line != null) {
if (line.StartsWith("====")) {
if (sourceLines != null) Test(sourceLines, testLineNum, expectedOutput, outputLineNum);
sourceLines = null;
expectedOutput = null;
} else if (line.StartsWith("----")) {
expectedOutput = new List<string>();
outputLineNum = lineNum + 1;
} else if (expectedOutput != null) {
expectedOutput.Add(line);
} else {
if (sourceLines == null) {
sourceLines = new List<string>();
testLineNum = lineNum;
}
sourceLines.Add(line);
}
line = file.ReadLine();
lineNum++;
}
if (sourceLines != null) Test(sourceLines, testLineNum, expectedOutput, outputLineNum);
Print("\nIntegration tests complete.\n");
}
static void RunFile(string path, bool dumpTAC=false) {
StreamReader file = new StreamReader(path);
if (file == null) {
Print("Unable to read: " + path);
return;
}
List<string> sourceLines = new List<string>();
while (!file.EndOfStream) sourceLines.Add(file.ReadLine());
Interpreter miniscript = new Interpreter(sourceLines);
miniscript.standardOutput = (string s, bool eol) => Print(s, eol);
miniscript.implicitOutput = miniscript.standardOutput;
miniscript.Compile();
if (dumpTAC && miniscript.vm != null) {
miniscript.vm.DumpTopContext();
}
while (!miniscript.done) {
miniscript.RunUntilDone();
}
}
public static void Main(string[] args) {
if (args.Length > 0 && args[0] == "--test") {
Miniscript.HostInfo.name = "Test harness";
if (args.Length > 1 && args[1] == "--integration") {
var file = args.Length < 3 || string.IsNullOrEmpty(args[2]) ? "../../../TestSuite.txt" : args[2];
Print("Running test suite.\n");
RunTestSuite(file);
return;
}
Print("Miniscript test harness.\n");
Print("Running unit tests.\n");
UnitTest.Run();
Print("\n");
const string quickTestFilePath = "../../../QuickTest.ms";
if (File.Exists(quickTestFilePath)) {
Print("Running quick test.\n");
var stopwatch = new System.Diagnostics.Stopwatch();
stopwatch.Start();
RunFile(quickTestFilePath, true);
stopwatch.Stop();
Print($"Run time: {stopwatch.Elapsed.TotalSeconds} sec");
} else {
Print("Quick test not found, skipping...\n");
}
return;
}
if (args.Length > 0) {
RunFile(args[0]);
return;
}
Interpreter repl = new Interpreter();
repl.implicitOutput = repl.standardOutput;
while (true) {
Console.Write(repl.NeedMoreInput() ? ">>> " : "> ");
string inp = Console.ReadLine();
if (inp == null) break;
repl.REPL(inp);
}
}
}