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