https://github.com/akkartik/mu/blob/master/040tests.cc
1
2
3
4
5
6
7
8
9
10
11
12 :(after "Begin Transforms")
13 Transform.push_back(create_test_function);
14
15 :(code)
16 void test_run_test() {
17 Mem.push_back(vma(0xbd000000));
18 Reg[ESP].u = 0xbd000100;
19 run(
20 "== code 0x1\n"
21 "main:\n"
22 " e8/call run-tests/disp32\n"
23 " f4/halt\n"
24 "test-foo:\n"
25 " 01 d8\n"
26 " c3/return\n"
27 );
28
29 CHECK_TRACE_CONTENTS(
30 "run: 0x00000007 opcode: 01\n"
31 );
32 }
33
34 void create_test_function(program& p) {
35 if (p.segments.empty()) return;
36 segment& code = *find(p, "code");
37 trace(3, "transform") << "-- create 'run-tests'" << end();
38 vector<line> new_insts;
39 for (int i = 0; i < SIZE(code.lines); ++i) {
40 line& inst = code.lines.at(i);
41 for (int j = 0; j < SIZE(inst.words); ++j) {
42 const word& curr = inst.words.at(j);
43 if (*curr.data.rbegin() != ':') continue;
44 if (!starts_with(curr.data, "test-")) continue;
45 string fn = drop_last(curr.data);
46 new_insts.push_back(call(fn));
47 }
48 }
49 if (new_insts.empty()) return;
50 code.lines.push_back(label("run-tests"));
51 code.lines.insert(code.lines.end(), new_insts.begin(), new_insts.end());
52 code.lines.push_back(ret());
53 }
54
55 string to_string(const segment& s) {
56 ostringstream out;
57 for (int i = 0; i < SIZE(s.lines); ++i) {
58 const line& l = s.lines.at(i);
59 for (int j = 0; j < SIZE(l.words); ++j) {
60 if (j > 0) out << ' ';
61 out << to_string(l.words.at(j));
62 }
63 out << '\n';
64 }
65 return out.str();
66 }
67
68 line call(string s) {
69 line result;
70 result.words.push_back(call());
71 result.words.push_back(disp32(s));
72 return result;
73 }
74
75 word call() {
76 word result;
77 result.data = "e8";
78 result.metadata.push_back("call");
79 return result;
80 }
81
82 word disp32(string s) {
83 word result;
84 result.data = s;
85 result.metadata.push_back("disp32");
86 return result;
87 }
88
89 line ret() {
90 line result;
91 result.words.push_back(word());
92 result.words.back().data = "c3";
93 result.words.back().metadata.push_back("return");
94 return result;
95 }