// BEGIN mycpp output #include "gc_heap.h" using gc_heap::Alloc; using gc_heap::kZeroMask; using gc_heap::StackRoots; #include "my_runtime.h" #include "mylib2.h" using gc_heap::NewStr; using gc_heap::NewList; using gc_heap::NewDict; 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 gc_heap::Obj { public: ParseError(Str* reason); Str* reason; DISALLOW_COPY_AND_ASSIGN(ParseError) }; Str* f(Str* s); void ExceptDemo(); void run_tests(); void run_benchmarks(); inline Str* fmt0(Str* a0) { gBuf.reset(); gBuf.write_const("error: ", 7); gBuf.format_s(a0); return gBuf.getvalue(); } inline Str* fmt1(Str* a0) { gBuf.reset(); gBuf.write_const("result = ", 9); gBuf.format_s(a0); return gBuf.getvalue(); } inline Str* fmt2(int a0) { gBuf.reset(); gBuf.write_const("num_exceptions = ", 17); gBuf.format_d(a0); return gBuf.getvalue(); } inline Str* fmt3(int a0) { gBuf.reset(); gBuf.write_const("Ran ", 4); gBuf.format_d(a0); gBuf.write_const(" iterations of try/except", 25); return gBuf.getvalue(); } } // 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(Str* reason) : gc_heap::Obj(Tag::FixedSize, kZeroMask, sizeof(ParseError)) { this->reason = reason; } Str* f(Str* s) { StackRoots _roots({&s}); if (str_equals(s->index(0), str4)) { throw Alloc(str5); } return s; } void ExceptDemo() { Str* result = nullptr; List* tmp = nullptr; StackRoots _roots({&result, &tmp}); result = str6; tmp = NewList(std::initializer_list{str7, str8}); for (ListIter it(tmp); !it.Done(); it.Next()) { Str* prog = it.Value(); StackRoots _for({&prog }); try { result = f(prog); } catch (ParseError* e) { println_stderr(fmt0(e->reason)); continue; } println_stderr(fmt1(result)); } } void run_tests() { List* tmp = nullptr; StackRoots _roots({&tmp}); tmp = NewList(std::initializer_list{1, 2, 3, 4, 5}); for (ListIter it(tmp); !it.Done(); it.Next()) { int i = it.Value(); StackRoots _for({&i }); IfDemo(i); } println_stderr(str11); ExceptDemo(); } void run_benchmarks() { int n; Str* result = nullptr; int num_exceptions; int i; List* cases = nullptr; StackRoots _roots({&result, &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()) { Str* prog = it.Value(); StackRoots _for({&prog }); try { result = f(prog); } catch (ParseError* e) { num_exceptions += 1; continue; } } i += 1; } println_stderr(fmt2(num_exceptions)); println_stderr(fmt3(n)); } } // define namespace control_flow