From 6e1eeeebfb453fa7c871869c19375ce60fbd7413 Mon Sep 17 00:00:00 2001 From: Kartik Agaram Date: Sat, 27 Jul 2019 16:01:55 -0700 Subject: 5485 - promote SubX to top-level --- html/040---tests.cc.html | 160 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 160 insertions(+) create mode 100644 html/040---tests.cc.html (limited to 'html/040---tests.cc.html') diff --git a/html/040---tests.cc.html b/html/040---tests.cc.html new file mode 100644 index 00000000..73a7898d --- /dev/null +++ b/html/040---tests.cc.html @@ -0,0 +1,160 @@ + + + + +Mu - subx/040---tests.cc + + + + + + + + + + +https://github.com/akkartik/mu/blob/master/subx/040---tests.cc +
+ 1 //: Automatically aggregate functions starting with 'test-' into a test suite
+ 2 //: called 'run-tests'. Running this function will run all tests.
+ 3 //:
+ 4 //: This is actually SubX's first (trivial) compiler. We generate all the code
+ 5 //: needed for the 'run-tests' function.
+ 6 //:
+ 7 //: By convention, temporary functions needed by tests will start with
+ 8 //: '_test-'.
+ 9 
+10 //: We don't rely on any transforms running in previous layers, but this layer
+11 //: knows about labels and will emit labels for previous layers to transform.
+12 :(after "Begin Transforms")
+13 // Begin Level-4 Transforms
+14 Transform.push_back(create_test_function);
+15 // End Level-4 Transforms
+16 
+17 :(code)
+18 void test_run_test() {
+19   Mem.push_back(vma(0xbd000000));  // manually allocate memory
+20   Reg[ESP].u = 0xbd000100;
+21   run(
+22       "== code 0x1\n"  // code segment
+23       "main:\n"
+24       "  e8/call run-tests/disp32\n"  // 5 bytes
+25       "  f4/halt\n"                   // 1 byte
+26       "test-foo:\n"  // offset 7
+27       "  01 d8\n"  // just some unique instruction: add EBX to EAX
+28       "  c3/return\n"
+29   );
+30   // check that code in test-foo ran (implicitly called by run-tests)
+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;  // not a label
+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;  // no tests found
+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 }
+
+ + + -- cgit 1.4.1-2-gfad0