// examples/parse translated by mycpp_main #include "mycpp/examples/parse_preamble.h" // BEGIN mycpp output #include "mycpp/runtime.h" namespace runtime { // forward declare class TraversalState; } namespace format { // forward declare } namespace j8_lite { // forward declare } namespace ansi { // forward declare } namespace pp_hnode { // forward declare class BaseEncoder; class HNodeEncoder; } namespace pretty { // forward declare class PrettyPrinter; } namespace parse { // forward declare class Lexer; class ParseError; class Parser; } GLOBAL_STR(S_Aoo, ""); GLOBAL_STR(S_nfs, "\n"); GLOBAL_STR(S_yfk, "\u001b[0;0m"); GLOBAL_STR(S_aaF, "\u001b[1m"); GLOBAL_STR(S_sqm, "\u001b[31m"); GLOBAL_STR(S_eda, "\u001b[32m"); GLOBAL_STR(S_ysf, "\u001b[33m"); GLOBAL_STR(S_osl, "\u001b[34m"); GLOBAL_STR(S_vie, "\u001b[35m"); GLOBAL_STR(S_mmi, "\u001b[36m"); GLOBAL_STR(S_rpo, "\u001b[37m"); GLOBAL_STR(S_sCc, "\u001b[4m"); GLOBAL_STR(S_woy, "\u001b[7m"); GLOBAL_STR(S_yfw, " "); GLOBAL_STR(S_utu, " $$ "); GLOBAL_STR(S_ijB, "("); GLOBAL_STR(S_zxb, "()"); GLOBAL_STR(S_anb, "(1+2)*3"); GLOBAL_STR(S_qey, "(a+b"); GLOBAL_STR(S_hxb, ")"); GLOBAL_STR(S_fFq, "*/"); GLOBAL_STR(S_jnE, "+"); GLOBAL_STR(S_jau, "+-"); GLOBAL_STR(S_gpk, "--"); GLOBAL_STR(S_vrA, "1"); GLOBAL_STR(S_sdy, "1*2+3"); GLOBAL_STR(S_nmE, "1+2"); GLOBAL_STR(S_eei, "1+2*3"); GLOBAL_STR(S_fyj, ":"); GLOBAL_STR(S_rFn, "Expected "); GLOBAL_STR(S_gFh, "F"); GLOBAL_STR(S_wqv, "NULL BUG"); GLOBAL_STR(S_otA, "Other"); GLOBAL_STR(S_cor, "T"); GLOBAL_STR(S_pqw, "Unexpected token "); GLOBAL_STR(S_Eax, "["); GLOBAL_STR(S_xmu, "[]"); GLOBAL_STR(S_pcD, "]"); GLOBAL_STR(S_tci, "_"); GLOBAL_STR(S_gfw, "___ GC: after printing"); GLOBAL_STR(S_gCD, "a"); GLOBAL_STR(S_fhr, "a*b*3*4"); GLOBAL_STR(S_Bth, "a+b+c+d"); GLOBAL_STR(S_jng, "abc"); GLOBAL_STR(S_jFv, "b"); GLOBAL_STR(S_clt, "bar"); GLOBAL_STR(S_emj, "c"); GLOBAL_STR(S_Crn, "d"); GLOBAL_STR(S_ysz, "e"); GLOBAL_STR(S_lqB, "foo"); GLOBAL_STR(S_wkf, "not null"); GLOBAL_STR(S_xww, "zz"); namespace runtime { // declare extern int NO_SPID; hnode::Record* NewRecord(BigStr* node_type); hnode::Leaf* NewLeaf(BigStr* s, hnode_asdl::color_t e_color); class TraversalState { public: TraversalState(); Dict* seen{}; Dict* ref_count{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(2, sizeof(TraversalState)); } DISALLOW_COPY_AND_ASSIGN(TraversalState) }; extern BigStr* TRUE_STR; extern BigStr* FALSE_STR; } // declare namespace runtime namespace format { // declare int _HNodeCount(hnode_asdl::hnode_t* h); int _DocCount(pretty_asdl::doc_t* d); void _HNodePrettyPrint(bool perf_stats, bool doc_debug, hnode_asdl::hnode_t* node, mylib::Writer* f, int max_width = 80); void HNodePrettyPrint(hnode_asdl::hnode_t* node, mylib::Writer* f, int max_width = 80); } // declare namespace format namespace j8_lite { // declare BigStr* EncodeString(BigStr* s, bool unquoted_ok = false); BigStr* YshEncodeString(BigStr* s); BigStr* MaybeShellEncode(BigStr* s); BigStr* ShellEncode(BigStr* s); BigStr* YshEncode(BigStr* s, bool unquoted_ok = false); } // declare namespace j8_lite namespace ansi { // declare extern BigStr* RESET; extern BigStr* BOLD; extern BigStr* UNDERLINE; extern BigStr* REVERSE; extern BigStr* RED; extern BigStr* GREEN; extern BigStr* YELLOW; extern BigStr* BLUE; extern BigStr* MAGENTA; extern BigStr* CYAN; extern BigStr* WHITE; } // declare namespace ansi namespace pp_hnode { // declare class BaseEncoder { public: BaseEncoder(); void SetIndent(int indent); void SetUseStyles(bool use_styles); void SetMaxTabularWidth(int max_tabular_width); pretty_asdl::MeasuredDoc* _Styled(BigStr* style, pretty_asdl::MeasuredDoc* mdoc); pretty_asdl::MeasuredDoc* _StyledAscii(BigStr* style, BigStr* s); pretty_asdl::MeasuredDoc* _Surrounded(BigStr* left, pretty_asdl::MeasuredDoc* mdoc, BigStr* right); pretty_asdl::MeasuredDoc* _SurroundedAndPrefixed(BigStr* left, pretty_asdl::MeasuredDoc* prefix, BigStr* sep, pretty_asdl::MeasuredDoc* mdoc, BigStr* right); pretty_asdl::MeasuredDoc* _Join(List* items, BigStr* sep, BigStr* space); pretty_asdl::MeasuredDoc* _Tabular(List* items, BigStr* sep); int indent{}; int max_tabular_width{}; bool use_styles{}; Dict* visiting{}; static constexpr uint32_t field_mask() { return maskbit(offsetof(BaseEncoder, visiting)); } static constexpr ObjHeader obj_header() { return ObjHeader::ClassFixed(field_mask(), sizeof(BaseEncoder)); } DISALLOW_COPY_AND_ASSIGN(BaseEncoder) }; class HNodeEncoder : public ::pp_hnode::BaseEncoder { public: HNodeEncoder(); pretty_asdl::MeasuredDoc* HNode(hnode_asdl::hnode_t* h); pretty_asdl::MeasuredDoc* _Field(hnode_asdl::Field* field); pretty_asdl::MeasuredDoc* _HNode(hnode_asdl::hnode_t* h); BigStr* field_color{}; BigStr* type_color{}; static constexpr uint32_t field_mask() { return ::pp_hnode::BaseEncoder::field_mask() | maskbit(offsetof(HNodeEncoder, field_color)) | maskbit(offsetof(HNodeEncoder, type_color)); } static constexpr ObjHeader obj_header() { return ObjHeader::ClassFixed(field_mask(), sizeof(HNodeEncoder)); } DISALLOW_COPY_AND_ASSIGN(HNodeEncoder) }; } // declare namespace pp_hnode namespace pretty { // declare pretty_asdl::Measure* _EmptyMeasure(); pretty_asdl::Measure* _FlattenMeasure(pretty_asdl::Measure* measure); pretty_asdl::Measure* _ConcatMeasure(pretty_asdl::Measure* m1, pretty_asdl::Measure* m2); int _SuffixLen(pretty_asdl::Measure* measure); pretty_asdl::MeasuredDoc* AsciiText(BigStr* string); pretty_asdl::MeasuredDoc* _Break(BigStr* string); pretty_asdl::MeasuredDoc* _Indent(int indent, pretty_asdl::MeasuredDoc* mdoc); pretty_asdl::Measure* _Splice(List* out, List* mdocs); pretty_asdl::MeasuredDoc* _Concat(List* mdocs); pretty_asdl::MeasuredDoc* _Group(pretty_asdl::MeasuredDoc* mdoc); pretty_asdl::MeasuredDoc* _IfFlat(pretty_asdl::MeasuredDoc* flat_mdoc, pretty_asdl::MeasuredDoc* nonflat_mdoc); pretty_asdl::MeasuredDoc* _Flat(pretty_asdl::MeasuredDoc* mdoc); class PrettyPrinter { public: PrettyPrinter(int max_width); bool _Fits(int prefix_len, pretty_asdl::MeasuredDoc* group, pretty_asdl::Measure* suffix_measure); void PrintDoc(pretty_asdl::MeasuredDoc* document, mylib::BufWriter* buf); int max_width{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(0, sizeof(PrettyPrinter)); } DISALLOW_COPY_AND_ASSIGN(PrettyPrinter) }; } // declare namespace pretty namespace parse { // declare class Lexer { public: Lexer(BigStr* s); Tuple2 Read(); void _MethodCallingOtherMethod(); BigStr* s{}; int i{}; int n{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(1, sizeof(Lexer)); } DISALLOW_COPY_AND_ASSIGN(Lexer) }; class ParseError { public: ParseError(BigStr* msg); BigStr* msg{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(1, sizeof(ParseError)); } DISALLOW_COPY_AND_ASSIGN(ParseError) }; class Parser { public: Parser(parse::Lexer* lexer); void Next(); void Eat(BigStr* tok_val); expr_asdl::expr_t* ParseFactor(); expr_asdl::expr_t* ParseTerm(); expr_asdl::expr_t* ParseExpr(); expr_asdl::expr_t* Parse(); parse::Lexer* lexer{}; BigStr* tok_val{}; expr_asdl::tok_t tok_type{}; static constexpr ObjHeader obj_header() { return ObjHeader::ClassScanned(2, sizeof(Parser)); } DISALLOW_COPY_AND_ASSIGN(Parser) }; void TestParse(); void TestCreateNull(); void TestSubtype(); void TestLeafValue(); void run_tests(); void run_benchmarks(); } // declare namespace parse namespace runtime { // define using hnode_asdl::hnode; using hnode_asdl::color_t; using hnode_asdl::color_e; int NO_SPID = -1; hnode::Record* NewRecord(BigStr* node_type) { StackRoot _root0(&node_type); return Alloc(node_type, S_ijB, S_hxb, Alloc>(), nullptr); } hnode::Leaf* NewLeaf(BigStr* s, hnode_asdl::color_t e_color) { StackRoot _root0(&s); if (s == nullptr) { return Alloc(S_tci, color_e::OtherConst); } else { return Alloc(s, e_color); } } TraversalState::TraversalState() { this->seen = Alloc>(); this->ref_count = Alloc>(); } BigStr* TRUE_STR = S_cor; BigStr* FALSE_STR = S_gFh; } // define namespace runtime namespace format { // define using hnode_asdl::hnode; using hnode_asdl::hnode_e; using hnode_asdl::hnode_t; using pretty_asdl::doc; using pretty_asdl::doc_e; using pretty_asdl::doc_t; using pretty_asdl::MeasuredDoc; using pretty_asdl::List_Measured; int _HNodeCount(hnode_asdl::hnode_t* h) { hnode_asdl::hnode_t* UP_h = nullptr; int n; StackRoot _root0(&h); StackRoot _root1(&UP_h); UP_h = h; switch (h->tag()) { case hnode_e::AlreadySeen: { return 1; } break; case hnode_e::Leaf: { return 1; } break; case hnode_e::Array: { hnode::Array* h = static_cast(UP_h); n = 1; for (ListIter it(h->children); !it.Done(); it.Next()) { hnode_asdl::hnode_t* child = it.Value(); StackRoot _for(&child ); n += _HNodeCount(child); } return n; } break; case hnode_e::Record: { hnode::Record* h = static_cast(UP_h); n = 1; for (ListIter it(h->fields); !it.Done(); it.Next()) { hnode_asdl::Field* field = it.Value(); StackRoot _for(&field ); n += _HNodeCount(field->val); } if (h->unnamed_fields != nullptr) { for (ListIter it(h->unnamed_fields); !it.Done(); it.Next()) { hnode_asdl::hnode_t* child = it.Value(); StackRoot _for(&child ); n += _HNodeCount(child); } } return n; } break; default: { assert(0); // AssertionError } } } int _DocCount(pretty_asdl::doc_t* d) { pretty_asdl::doc_t* UP_d = nullptr; int n; StackRoot _root0(&d); StackRoot _root1(&UP_d); UP_d = d; switch (d->tag()) { case doc_e::Break: { return 1; } break; case doc_e::Text: { return 1; } break; case doc_e::Indent: { doc::Indent* d = static_cast(UP_d); return (1 + _DocCount(d->mdoc->doc)); } break; case doc_e::Group: { MeasuredDoc* d = static_cast(UP_d); return (1 + _DocCount(d->doc)); } break; case doc_e::Flat: { doc::Flat* d = static_cast(UP_d); return (1 + _DocCount(d->mdoc->doc)); } break; case doc_e::IfFlat: { doc::IfFlat* d = static_cast(UP_d); return ((1 + _DocCount(d->flat_mdoc->doc)) + _DocCount(d->nonflat_mdoc->doc)); } break; case doc_e::Concat: { List_Measured* d = static_cast(UP_d); n = 1; for (ListIter it(d); !it.Done(); it.Next()) { pretty_asdl::MeasuredDoc* mdoc = it.Value(); StackRoot _for(&mdoc ); n += _DocCount(mdoc->doc); } return n; } break; default: { assert(0); // AssertionError } } } void _HNodePrettyPrint(bool perf_stats, bool doc_debug, hnode_asdl::hnode_t* node, mylib::Writer* f, int max_width) { pp_hnode::HNodeEncoder* enc = nullptr; pretty_asdl::MeasuredDoc* d = nullptr; hnode_asdl::hnode_t* p = nullptr; pretty::PrettyPrinter* printer = nullptr; mylib::BufWriter* buf = nullptr; StackRoot _root0(&node); StackRoot _root1(&f); StackRoot _root2(&enc); StackRoot _root3(&d); StackRoot _root4(&p); StackRoot _root5(&printer); StackRoot _root6(&buf); mylib::MaybeCollect(); if (perf_stats) { mylib::print_stderr(StrFormat("___ HNODE COUNT %d", _HNodeCount(node))); mylib::print_stderr(S_Aoo); } enc = Alloc(); enc->SetUseStyles(f->isatty()); enc->SetIndent(2); d = enc->HNode(node); mylib::MaybeCollect(); if (perf_stats) { if (doc_debug) { p = d->PrettyTree(false); _HNodePrettyPrint(perf_stats, false, p, f); } mylib::print_stderr(StrFormat("___ DOC COUNT %d", _DocCount(d))); mylib::print_stderr(S_Aoo); } printer = Alloc(max_width); buf = Alloc(); printer->PrintDoc(d, buf); f->write(buf->getvalue()); f->write(S_nfs); mylib::MaybeCollect(); if (perf_stats) { mylib::print_stderr(S_gfw); mylib::PrintGcStats(); mylib::print_stderr(S_Aoo); } } void HNodePrettyPrint(hnode_asdl::hnode_t* node, mylib::Writer* f, int max_width) { StackRoot _root0(&node); StackRoot _root1(&f); _HNodePrettyPrint(false, true, node, f, max_width); } } // define namespace format namespace j8_lite { // define BigStr* EncodeString(BigStr* s, bool unquoted_ok) { StackRoot _root0(&s); if ((unquoted_ok and fastfunc::CanOmitQuotes(s))) { return s; } return fastfunc::J8EncodeString(s, 1); } BigStr* YshEncodeString(BigStr* s) { StackRoot _root0(&s); return fastfunc::ShellEncodeString(s, 1); } BigStr* MaybeShellEncode(BigStr* s) { StackRoot _root0(&s); if (fastfunc::CanOmitQuotes(s)) { return s; } return fastfunc::ShellEncodeString(s, 0); } BigStr* ShellEncode(BigStr* s) { StackRoot _root0(&s); return fastfunc::ShellEncodeString(s, 0); } BigStr* YshEncode(BigStr* s, bool unquoted_ok) { StackRoot _root0(&s); if ((unquoted_ok and fastfunc::CanOmitQuotes(s))) { return s; } return fastfunc::ShellEncodeString(s, 1); } } // define namespace j8_lite namespace ansi { // define BigStr* RESET = S_yfk; BigStr* BOLD = S_aaF; BigStr* UNDERLINE = S_sCc; BigStr* REVERSE = S_woy; BigStr* RED = S_sqm; BigStr* GREEN = S_eda; BigStr* YELLOW = S_ysf; BigStr* BLUE = S_osl; BigStr* MAGENTA = S_vie; BigStr* CYAN = S_mmi; BigStr* WHITE = S_rpo; } // define namespace ansi namespace pp_hnode { // define using hnode_asdl::hnode; using hnode_asdl::hnode_e; using hnode_asdl::hnode_t; using hnode_asdl::Field; using hnode_asdl::color_e; using pretty_asdl::doc; using pretty_asdl::MeasuredDoc; using pretty_asdl::Measure; using pretty::_Break; using pretty::_Concat; using pretty::_Flat; using pretty::_Group; using pretty::_IfFlat; using pretty::_Indent; using pretty::_EmptyMeasure; using pretty::AsciiText; BaseEncoder::BaseEncoder() { this->indent = 4; this->use_styles = true; this->max_tabular_width = 22; this->visiting = Alloc>(); } void BaseEncoder::SetIndent(int indent) { this->indent = indent; } void BaseEncoder::SetUseStyles(bool use_styles) { this->use_styles = use_styles; } void BaseEncoder::SetMaxTabularWidth(int max_tabular_width) { this->max_tabular_width = max_tabular_width; } pretty_asdl::MeasuredDoc* BaseEncoder::_Styled(BigStr* style, pretty_asdl::MeasuredDoc* mdoc) { StackRoot _root0(&style); StackRoot _root1(&mdoc); if (this->use_styles) { return _Concat(NewList(std::initializer_list{Alloc(Alloc(style), _EmptyMeasure()), mdoc, Alloc(Alloc(ansi::RESET), _EmptyMeasure())})); } else { return mdoc; } } pretty_asdl::MeasuredDoc* BaseEncoder::_StyledAscii(BigStr* style, BigStr* s) { pretty_asdl::Measure* measure = nullptr; StackRoot _root0(&style); StackRoot _root1(&s); StackRoot _root2(&measure); measure = Alloc(len(s), -1); if (this->use_styles) { s = StrFormat("%s%s%s", style, s, ansi::RESET); } return Alloc(Alloc(s), measure); } pretty_asdl::MeasuredDoc* BaseEncoder::_Surrounded(BigStr* left, pretty_asdl::MeasuredDoc* mdoc, BigStr* right) { StackRoot _root0(&left); StackRoot _root1(&mdoc); StackRoot _root2(&right); return _Group(_Concat(NewList(std::initializer_list{AsciiText(left), _Indent(this->indent, _Concat(NewList(std::initializer_list{_Break(S_Aoo), mdoc}))), _Break(S_Aoo), AsciiText(right)}))); } pretty_asdl::MeasuredDoc* BaseEncoder::_SurroundedAndPrefixed(BigStr* left, pretty_asdl::MeasuredDoc* prefix, BigStr* sep, pretty_asdl::MeasuredDoc* mdoc, BigStr* right) { StackRoot _root0(&left); StackRoot _root1(&prefix); StackRoot _root2(&sep); StackRoot _root3(&mdoc); StackRoot _root4(&right); return _Group(_Concat(NewList(std::initializer_list{AsciiText(left), prefix, _Indent(this->indent, _Concat(NewList(std::initializer_list{_Break(sep), mdoc}))), _Break(S_Aoo), AsciiText(right)}))); } pretty_asdl::MeasuredDoc* BaseEncoder::_Join(List* items, BigStr* sep, BigStr* space) { List* seq = nullptr; int i; StackRoot _root0(&items); StackRoot _root1(&sep); StackRoot _root2(&space); StackRoot _root3(&seq); seq = Alloc>(); i = 0; for (ListIter it(items); !it.Done(); it.Next(), ++i) { pretty_asdl::MeasuredDoc* item = it.Value(); StackRoot _for(&item ); if (i != 0) { seq->append(AsciiText(sep)); seq->append(_Break(space)); } seq->append(item); } return _Concat(seq); } pretty_asdl::MeasuredDoc* BaseEncoder::_Tabular(List* items, BigStr* sep) { int max_flat_len; List* seq = nullptr; int i; pretty_asdl::MeasuredDoc* non_tabular = nullptr; int sep_width; List* tabular_seq = nullptr; int padding; pretty_asdl::MeasuredDoc* tabular = nullptr; StackRoot _root0(&items); StackRoot _root1(&sep); StackRoot _root2(&seq); StackRoot _root3(&non_tabular); StackRoot _root4(&tabular_seq); StackRoot _root5(&tabular); if (len(items) == 0) { return AsciiText(S_Aoo); } max_flat_len = 0; seq = Alloc>(); i = 0; for (ListIter it(items); !it.Done(); it.Next(), ++i) { pretty_asdl::MeasuredDoc* item = it.Value(); StackRoot _for(&item ); if (i != 0) { seq->append(AsciiText(sep)); seq->append(_Break(S_yfw)); } seq->append(item); max_flat_len = max(max_flat_len, item->measure->flat); } non_tabular = _Concat(seq); sep_width = len(sep); if (((max_flat_len + sep_width) + 1) <= this->max_tabular_width) { tabular_seq = Alloc>(); i = 0; for (ListIter it(items); !it.Done(); it.Next(), ++i) { pretty_asdl::MeasuredDoc* item = it.Value(); StackRoot _for(&item ); tabular_seq->append(_Flat(item)); if (i != (len(items) - 1)) { padding = ((max_flat_len - item->measure->flat) + 1); tabular_seq->append(AsciiText(sep)); tabular_seq->append(_Group(_Break(str_repeat(S_yfw, padding)))); } } tabular = _Concat(tabular_seq); return _Group(_IfFlat(non_tabular, tabular)); } else { return non_tabular; } } HNodeEncoder::HNodeEncoder() : ::pp_hnode::BaseEncoder() { this->type_color = ansi::YELLOW; this->field_color = ansi::MAGENTA; } pretty_asdl::MeasuredDoc* HNodeEncoder::HNode(hnode_asdl::hnode_t* h) { StackRoot _root0(&h); this->visiting->clear(); return this->_HNode(h); } pretty_asdl::MeasuredDoc* HNodeEncoder::_Field(hnode_asdl::Field* field) { pretty_asdl::MeasuredDoc* name = nullptr; StackRoot _root0(&field); StackRoot _root1(&name); name = AsciiText(str_concat(field->name, S_fyj)); return _Concat(NewList(std::initializer_list{name, this->_HNode(field->val)})); } pretty_asdl::MeasuredDoc* HNodeEncoder::_HNode(hnode_asdl::hnode_t* h) { hnode_asdl::hnode_t* UP_h = nullptr; BigStr* color = nullptr; BigStr* s = nullptr; List* children = nullptr; pretty_asdl::MeasuredDoc* type_name = nullptr; List* mdocs = nullptr; List* m = nullptr; pretty_asdl::MeasuredDoc* child = nullptr; StackRoot _root0(&h); StackRoot _root1(&UP_h); StackRoot _root2(&color); StackRoot _root3(&s); StackRoot _root4(&children); StackRoot _root5(&type_name); StackRoot _root6(&mdocs); StackRoot _root7(&m); StackRoot _root8(&child); UP_h = h; switch (h->tag()) { case hnode_e::AlreadySeen: { hnode::AlreadySeen* h = static_cast(UP_h); return pretty::AsciiText(StrFormat("...0x%s", mylib::hex_lower(h->heap_id))); } break; case hnode_e::Leaf: { hnode::Leaf* h = static_cast(UP_h); switch (h->color) { case color_e::TypeName: { color = ansi::YELLOW; } break; case color_e::StringConst: { color = ansi::BOLD; } break; case color_e::OtherConst: { color = ansi::GREEN; } break; case color_e::External: { color = str_concat(ansi::BOLD, ansi::BLUE); } break; case color_e::UserType: { color = ansi::GREEN; } break; default: { assert(0); // AssertionError } } s = j8_lite::EncodeString(h->s, true); return this->_StyledAscii(color, s); } break; case hnode_e::Array: { hnode::Array* h = static_cast(UP_h); mylib::MaybeCollect(); if (len(h->children) == 0) { return AsciiText(S_xmu); } children = Alloc>(); for (ListIter it(h->children); !it.Done(); it.Next()) { hnode_asdl::hnode_t* item = it.Value(); children->append(this->_HNode(item)); } return this->_Surrounded(S_Eax, this->_Tabular(children, S_Aoo), S_pcD); } break; case hnode_e::Record: { hnode::Record* h = static_cast(UP_h); type_name = nullptr; if (len(h->node_type)) { type_name = this->_StyledAscii(this->type_color, h->node_type); } mdocs = nullptr; if ((h->unnamed_fields != nullptr and len(h->unnamed_fields))) { mdocs = Alloc>(); for (ListIter it(h->unnamed_fields); !it.Done(); it.Next()) { hnode_asdl::hnode_t* item = it.Value(); mdocs->append(this->_HNode(item)); } } else { if (len(h->fields) != 0) { mdocs = Alloc>(); for (ListIter it(h->fields); !it.Done(); it.Next()) { hnode_asdl::Field* field = it.Value(); mdocs->append(this->_Field(field)); } } } if (mdocs == nullptr) { m = NewList(std::initializer_list{AsciiText(h->left)}); if (type_name != nullptr) { m->append(type_name); } m->append(AsciiText(h->right)); return _Concat(m); } child = this->_Join(mdocs, S_Aoo, S_yfw); if (type_name != nullptr) { return this->_SurroundedAndPrefixed(h->left, type_name, S_yfw, child, h->right); } else { return this->_Surrounded(h->left, child, h->right); } } break; default: { assert(0); // AssertionError } } } } // define namespace pp_hnode namespace pretty { // define using pretty_asdl::doc; using pretty_asdl::doc_e; using pretty_asdl::DocFragment; using pretty_asdl::Measure; using pretty_asdl::MeasuredDoc; using pretty_asdl::List_Measured; using mylib::BufWriter; pretty_asdl::Measure* _EmptyMeasure() { return Alloc(0, -1); } pretty_asdl::Measure* _FlattenMeasure(pretty_asdl::Measure* measure) { StackRoot _root0(&measure); return Alloc(measure->flat, -1); } pretty_asdl::Measure* _ConcatMeasure(pretty_asdl::Measure* m1, pretty_asdl::Measure* m2) { StackRoot _root0(&m1); StackRoot _root1(&m2); if (m1->nonflat != -1) { return Alloc((m1->flat + m2->flat), m1->nonflat); } else { if (m2->nonflat != -1) { return Alloc((m1->flat + m2->flat), (m1->flat + m2->nonflat)); } else { return Alloc((m1->flat + m2->flat), -1); } } } int _SuffixLen(pretty_asdl::Measure* measure) { StackRoot _root0(&measure); if (measure->nonflat != -1) { return measure->nonflat; } else { return measure->flat; } } pretty_asdl::MeasuredDoc* AsciiText(BigStr* string) { StackRoot _root0(&string); return Alloc(Alloc(string), Alloc(len(string), -1)); } pretty_asdl::MeasuredDoc* _Break(BigStr* string) { StackRoot _root0(&string); return Alloc(Alloc(string), Alloc(len(string), 0)); } pretty_asdl::MeasuredDoc* _Indent(int indent, pretty_asdl::MeasuredDoc* mdoc) { StackRoot _root0(&mdoc); return Alloc(Alloc(indent, mdoc), mdoc->measure); } pretty_asdl::Measure* _Splice(List* out, List* mdocs) { pretty_asdl::Measure* measure = nullptr; pretty_asdl::List_Measured* child = nullptr; StackRoot _root0(&out); StackRoot _root1(&mdocs); StackRoot _root2(&measure); StackRoot _root3(&child); measure = _EmptyMeasure(); for (ListIter it(mdocs); !it.Done(); it.Next()) { pretty_asdl::MeasuredDoc* mdoc = it.Value(); StackRoot _for(&mdoc ); switch (mdoc->doc->tag()) { case doc_e::Concat: { child = static_cast(mdoc->doc); _Splice(out, child); } break; default: { out->append(mdoc); } } measure = _ConcatMeasure(measure, mdoc->measure); } return measure; } pretty_asdl::MeasuredDoc* _Concat(List* mdocs) { pretty_asdl::List_Measured* flattened = nullptr; pretty_asdl::Measure* measure = nullptr; StackRoot _root0(&mdocs); StackRoot _root1(&flattened); StackRoot _root2(&measure); flattened = List_Measured::New(); measure = _Splice(flattened, mdocs); return Alloc(flattened, measure); } pretty_asdl::MeasuredDoc* _Group(pretty_asdl::MeasuredDoc* mdoc) { StackRoot _root0(&mdoc); return Alloc(mdoc, mdoc->measure); } pretty_asdl::MeasuredDoc* _IfFlat(pretty_asdl::MeasuredDoc* flat_mdoc, pretty_asdl::MeasuredDoc* nonflat_mdoc) { StackRoot _root0(&flat_mdoc); StackRoot _root1(&nonflat_mdoc); return Alloc(Alloc(flat_mdoc, nonflat_mdoc), Alloc(flat_mdoc->measure->flat, nonflat_mdoc->measure->nonflat)); } pretty_asdl::MeasuredDoc* _Flat(pretty_asdl::MeasuredDoc* mdoc) { StackRoot _root0(&mdoc); return Alloc(Alloc(mdoc), _FlattenMeasure(mdoc->measure)); } PrettyPrinter::PrettyPrinter(int max_width) { this->max_width = max_width; } bool PrettyPrinter::_Fits(int prefix_len, pretty_asdl::MeasuredDoc* group, pretty_asdl::Measure* suffix_measure) { pretty_asdl::Measure* measure = nullptr; StackRoot _root0(&group); StackRoot _root1(&suffix_measure); StackRoot _root2(&measure); measure = _ConcatMeasure(_FlattenMeasure(group->measure), suffix_measure); return (prefix_len + _SuffixLen(measure)) <= this->max_width; } void PrettyPrinter::PrintDoc(pretty_asdl::MeasuredDoc* document, mylib::BufWriter* buf) { int prefix_len; List* fragments = nullptr; int max_stack; pretty_asdl::DocFragment* frag = nullptr; pretty_asdl::doc_t* UP_doc = nullptr; pretty_asdl::Measure* measure = nullptr; bool is_flat; pretty_asdl::MeasuredDoc* subdoc = nullptr; StackRoot _root0(&document); StackRoot _root1(&buf); StackRoot _root2(&fragments); StackRoot _root3(&frag); StackRoot _root4(&UP_doc); StackRoot _root5(&measure); StackRoot _root6(&subdoc); prefix_len = 0; fragments = NewList(std::initializer_list{Alloc(_Group(document), 0, false, _EmptyMeasure())}); max_stack = len(fragments); while (len(fragments) > 0) { max_stack = max(max_stack, len(fragments)); frag = fragments->pop(); UP_doc = frag->mdoc->doc; switch (UP_doc->tag()) { case doc_e::Text: { doc::Text* text = static_cast(UP_doc); buf->write(text->string); prefix_len += frag->mdoc->measure->flat; } break; case doc_e::Break: { doc::Break* break_ = static_cast(UP_doc); if (frag->is_flat) { buf->write(break_->string); prefix_len += frag->mdoc->measure->flat; } else { buf->write(S_nfs); buf->write_spaces(frag->indent); prefix_len = frag->indent; } } break; case doc_e::Indent: { doc::Indent* indented = static_cast(UP_doc); fragments->append(Alloc(indented->mdoc, (frag->indent + indented->indent), frag->is_flat, frag->measure)); } break; case doc_e::Concat: { List_Measured* concat = static_cast(UP_doc); measure = frag->measure; for (ReverseListIter it(concat); !it.Done(); it.Next()) { pretty_asdl::MeasuredDoc* mdoc = it.Value(); StackRoot _for(&mdoc ); fragments->append(Alloc(mdoc, frag->indent, frag->is_flat, measure)); measure = _ConcatMeasure(mdoc->measure, measure); } } break; case doc_e::Group: { MeasuredDoc* group = static_cast(UP_doc); is_flat = this->_Fits(prefix_len, group, frag->measure); fragments->append(Alloc(group, frag->indent, is_flat, frag->measure)); } break; case doc_e::IfFlat: { doc::IfFlat* if_flat = static_cast(UP_doc); if (frag->is_flat) { subdoc = if_flat->flat_mdoc; } else { subdoc = if_flat->nonflat_mdoc; } fragments->append(Alloc(subdoc, frag->indent, frag->is_flat, frag->measure)); } break; case doc_e::Flat: { doc::Flat* flat_doc = static_cast(UP_doc); fragments->append(Alloc(flat_doc->mdoc, frag->indent, true, frag->measure)); } break; } } } } // define namespace pretty namespace parse { // define using expr_asdl::expr; using expr_asdl::expr_e; using expr_asdl::expr_t; using expr_asdl::tok_e; using expr_asdl::tok_t; using expr_asdl::CompoundWord; using expr_asdl::Measure_v; using expr_asdl::MeasuredDoc; namespace fmt = format; Lexer::Lexer(BigStr* s) { this->s = s; this->i = 0; this->n = len(s); } Tuple2 Lexer::Read() { BigStr* tok = nullptr; StackRoot _root0(&tok); if (this->i >= this->n) { return Tuple2(tok_e::Eof, S_Aoo); } tok = this->s->at(this->i); this->i += 1; if (tok->isdigit()) { return Tuple2(tok_e::Const, tok); } if (tok->isalpha()) { return Tuple2(tok_e::Var, tok); } if (str_contains(S_jau, tok)) { return Tuple2(tok_e::Op1, tok); } if (str_contains(S_fFq, tok)) { return Tuple2(tok_e::Op2, tok); } if (str_contains(S_zxb, tok)) { return Tuple2(tok_e::Paren, tok); } return Tuple2(tok_e::Invalid, tok); } void Lexer::_MethodCallingOtherMethod() { this->Read(); } ParseError::ParseError(BigStr* msg) { this->msg = msg; } Parser::Parser(parse::Lexer* lexer) { this->lexer = lexer; this->tok_type = tok_e::Eof; this->tok_val = S_Aoo; } void Parser::Next() { Tuple2 tup0 = this->lexer->Read(); this->tok_type = tup0.at0(); this->tok_val = tup0.at1(); } void Parser::Eat(BigStr* tok_val) { StackRoot _root0(&tok_val); if (!(str_equals(this->tok_val, tok_val))) { throw Alloc(str_concat(S_rFn, tok_val)); } this->Next(); } expr_asdl::expr_t* Parser::ParseFactor() { expr::Var* n1 = nullptr; expr::Const* n2 = nullptr; expr_asdl::expr_t* n3 = nullptr; StackRoot _root0(&n1); StackRoot _root1(&n2); StackRoot _root2(&n3); if (this->tok_type == tok_e::Var) { n1 = Alloc(this->tok_val); this->Next(); return n1; } if (this->tok_type == tok_e::Const) { n2 = Alloc(to_int(this->tok_val)); this->Next(); return n2; } if (this->tok_type == tok_e::Paren) { this->Eat(S_ijB); n3 = this->ParseExpr(); this->Eat(S_hxb); return n3; } throw Alloc(str_concat(S_pqw, this->tok_val)); } expr_asdl::expr_t* Parser::ParseTerm() { expr_asdl::expr_t* node = nullptr; BigStr* op = nullptr; expr_asdl::expr_t* n2 = nullptr; StackRoot _root0(&node); StackRoot _root1(&op); StackRoot _root2(&n2); node = this->ParseFactor(); while (this->tok_type == tok_e::Op2) { op = this->tok_val; this->Next(); n2 = this->ParseFactor(); node = Alloc(op, node, n2); } return node; } expr_asdl::expr_t* Parser::ParseExpr() { expr_asdl::expr_t* node = nullptr; BigStr* op = nullptr; expr_asdl::expr_t* n2 = nullptr; StackRoot _root0(&node); StackRoot _root1(&op); StackRoot _root2(&n2); node = this->ParseTerm(); while (this->tok_type == tok_e::Op1) { op = this->tok_val; this->Next(); n2 = this->ParseTerm(); node = Alloc(op, node, n2); } return node; } expr_asdl::expr_t* Parser::Parse() { this->Next(); return this->ParseExpr(); } void TestParse() { parse::Lexer* lex = nullptr; expr_asdl::tok_t tok_type; BigStr* tok_val = nullptr; List* CASES = nullptr; parse::Parser* p = nullptr; expr_asdl::expr_t* node = nullptr; hnode_asdl::hnode_t* htree = nullptr; mylib::Writer* f = nullptr; expr_asdl::expr_t* UP_node = nullptr; StackRoot _root0(&lex); StackRoot _root1(&tok_val); StackRoot _root2(&CASES); StackRoot _root3(&p); StackRoot _root4(&node); StackRoot _root5(&htree); StackRoot _root6(&f); StackRoot _root7(&UP_node); lex = Alloc(S_jng); while (true) { Tuple2 tup1 = lex->Read(); tok_type = tup1.at0(); tok_val = tup1.at1(); if (tok_type == tok_e::Eof) { break; } mylib::print_stderr(StrFormat("tok_val %s", tok_val)); } CASES = NewList(std::initializer_list{S_nmE, S_eei, S_sdy, S_anb, S_Bth, S_fhr, S_vrA, S_gCD, S_ijB, S_hxb, S_qey, S_yfw, S_utu}); for (ListIter it(CASES); !it.Done(); it.Next()) { BigStr* expr_ = it.Value(); StackRoot _for(&expr_ ); lex = Alloc(expr_); p = Alloc(lex); mylib::print_stderr(S_Aoo); mylib::print_stderr(S_gpk); mylib::print_stderr(StrFormat("%s =>", expr_)); node = nullptr; try { node = p->Parse(); } catch (ParseError* e) { mylib::print_stderr(StrFormat("Parse error: %s", e->msg)); continue; } htree = node->PrettyTree(false); f = mylib::Stdout(); fmt::HNodePrettyPrint(htree, f); UP_node = node; switch (UP_node->tag()) { case expr_e::Const: { expr::Const* node = static_cast(UP_node); mylib::print_stderr(StrFormat("Const %d", node->i)); } break; case expr_e::Var: { expr::Var* node = static_cast(UP_node); mylib::print_stderr(StrFormat("Var %s", node->name)); } break; default: { mylib::print_stderr(S_otA); } } } } void TestCreateNull() { expr::Const* c = nullptr; expr::Var* v = nullptr; expr::Binary* b = nullptr; hnode_asdl::hnode_t* htree = nullptr; mylib::Writer* f = nullptr; StackRoot _root0(&c); StackRoot _root1(&v); StackRoot _root2(&b); StackRoot _root3(&htree); StackRoot _root4(&f); c = expr::Const::CreateNull(true); mylib::print_stderr(StrFormat("c.i %d", c->i)); v = expr::Var::CreateNull(true); mylib::print_stderr(StrFormat("v.name %r", v->name)); b = expr::Binary::CreateNull(true); mylib::print_stderr(StrFormat("b.op %r", b->op)); b->op = S_jnE; b->left = c; b->right = v; htree = b->PrettyTree(false); f = mylib::Stdout(); fmt::HNodePrettyPrint(htree, f); } void TestSubtype() { expr_asdl::CompoundWord* c = nullptr; BigStr* s1 = nullptr; List* strs = nullptr; expr_asdl::CompoundWord* c3 = nullptr; expr_asdl::CompoundWord* c4 = nullptr; StackRoot _root0(&c); StackRoot _root1(&s1); StackRoot _root2(&strs); StackRoot _root3(&c3); StackRoot _root4(&c4); c = CompoundWord::New(); c->append(S_lqB); c->append(S_clt); mylib::print_stderr(StrFormat("len(c) = %d", len(c))); s1 = c->at(1); mylib::print_stderr(StrFormat("s1 = %r", s1)); c->set(1, S_xww); mylib::print_stderr(StrFormat("c[1] = %r", c->at(1))); for (ListIter it(c); !it.Done(); it.Next()) { BigStr* s = it.Value(); StackRoot _for(&s ); mylib::print_stderr(StrFormat("s = %r", s)); } strs = NewList(std::initializer_list{S_gCD, S_jFv, S_emj, S_Crn}); c3 = static_cast(strs); mylib::print_stderr(StrFormat("len(c3) = %d", len(c3))); c4 = CompoundWord::Take(strs); mylib::print_stderr(StrFormat("len(c4) = %d", len(c4))); mylib::print_stderr(StrFormat("len(strs) = %d", len(strs))); if (c->at(0) == nullptr) { mylib::print_stderr(S_wqv); } else { mylib::print_stderr(S_wkf); } mylib::print_stderr(StrFormat("c4[0] = %s", c4->at(0))); strs->append(S_ysz); mylib::print_stderr(StrFormat("len(strs) = %d", len(strs))); for (ListIter it(c4); !it.Done(); it.Next()) { BigStr* s = it.Value(); StackRoot _for(&s ); print(StrFormat("s = %r", s)); } } void TestLeafValue() { mylib::Writer* f = nullptr; int n; expr_asdl::Measure_v* m = nullptr; expr_asdl::MeasuredDoc* d = nullptr; hnode_asdl::hnode_t* tree = nullptr; StackRoot _root0(&f); StackRoot _root1(&m); StackRoot _root2(&d); StackRoot _root3(&tree); f = mylib::Stdout(); n = 10; for (int i = 0; i < n; ++i) { m = Alloc(i, (i + 1)); d = Alloc(StrFormat("s%d", i), m); tree = d->PrettyTree(false); fmt::HNodePrettyPrint(tree, f); } } void run_tests() { TestParse(); TestCreateNull(); TestSubtype(); TestLeafValue(); } void run_benchmarks() { int n; int result; int i; parse::Lexer* lex = nullptr; parse::Parser* p = nullptr; expr_asdl::expr_t* tree = nullptr; StackRoot _root0(&lex); StackRoot _root1(&p); StackRoot _root2(&tree); n = 100000; result = 0; i = 0; while (i < n) { lex = Alloc(S_fhr); p = Alloc(lex); tree = p->Parse(); i += 1; mylib::MaybeCollect(); } mylib::print_stderr(StrFormat("result = %d", result)); mylib::print_stderr(StrFormat("iterations = %d", n)); } } // define namespace parse int main(int argc, char **argv) { gHeap.Init(); char* b = getenv("BENCHMARK"); if (b && strlen(b)) { // match Python's logic fprintf(stderr, "Benchmarking...\n"); parse::run_benchmarks(); } else { parse::run_tests(); } gHeap.CleanProcessExit(); }