// examples/control_flow translated by mycpp // BEGIN mycpp output #include "mycpp/runtime.h" GLOBAL_STR(str0, "one"); GLOBAL_STR(str1, "two"); GLOBAL_STR(str2, "three"); GLOBAL_STR(str3, "other number"); GLOBAL_STR(str4, "f"); GLOBAL_STR(str5, "started with f"); GLOBAL_STR(str6, ""); GLOBAL_STR(str7, "foo"); GLOBAL_STR(str8, "bar"); GLOBAL_STR(str9, "error: %s"); GLOBAL_STR(str10, "result = %s"); GLOBAL_STR(str11, ""); GLOBAL_STR(str12, ""); GLOBAL_STR(str13, "fail"); GLOBAL_STR(str14, "ok"); GLOBAL_STR(str15, "ok"); GLOBAL_STR(str16, "ok"); GLOBAL_STR(str17, "num_exceptions = %d"); GLOBAL_STR(str18, "Ran %d iterations of try/except"); namespace control_flow { // forward declare class ParseError; } // forward declare namespace control_flow namespace control_flow { // declare void IfDemo(int i); class ParseError { public: ParseError(BigStr* reason); BigStr* reason{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(1, sizeof(ParseError)); } DISALLOW_COPY_AND_ASSIGN(ParseError) }; BigStr* f(BigStr* s); void ExceptDemo(); void run_tests(); void run_benchmarks(); } // declare namespace control_flow namespace control_flow { // define void IfDemo(int i) { if (i == 1) { print(str0); } else { if (i == 2) { print(str1); } else { if (i == 3) { print(str2); } else { if (i == 4) { ; // pass } else { print(str3); } } } } } ParseError::ParseError(BigStr* reason) { this->reason = reason; } BigStr* f(BigStr* s) { if (str_equals(s->at(0), str4)) { throw Alloc(str5); } return s; } void ExceptDemo() { BigStr* result = nullptr; List* tmp = nullptr; result = str6; tmp = NewList(std::initializer_list{str7, str8}); for (ListIter it(tmp); !it.Done(); it.Next()) { BigStr* prog = it.Value(); try { result = f(prog); } catch (ParseError* e) { mylib::print_stderr(StrFormat("error: %s", e->reason)); continue; } mylib::print_stderr(StrFormat("result = %s", result)); } } void run_tests() { List* tmp = nullptr; tmp = NewList(std::initializer_list{1, 2, 3, 4, 5}); for (ListIter it(tmp); !it.Done(); it.Next()) { int i = it.Value(); IfDemo(i); } mylib::print_stderr(str11); ExceptDemo(); } void run_benchmarks() { int n; BigStr* result = nullptr; int num_exceptions; int i; List* cases = nullptr; StackRoot _root0(&cases); n = 100000; result = str12; num_exceptions = 0; i = 0; cases = NewList(std::initializer_list{str13, str14, str15, str16}); while (i < n) { for (ListIter it(cases); !it.Done(); it.Next()) { BigStr* prog = it.Value(); try { result = f(prog); } catch (ParseError* e) { num_exceptions += 1; continue; } } i += 1; mylib::MaybeCollect(); } mylib::print_stderr(StrFormat("num_exceptions = %d", num_exceptions)); mylib::print_stderr(StrFormat("Ran %d iterations of try/except", n)); } } // define namespace control_flow int main(int argc, char **argv) { gHeap.Init(); char* b = getenv("BENCHMARK"); if (b && strlen(b)) { // match Python's logic fprintf(stderr, "Benchmarking...\n"); control_flow::run_benchmarks(); } else { control_flow::run_tests(); } gHeap.CleanProcessExit(); }