// yaks_main.mycpp.cc: translated from Python by mycpp

// #include "_gen/yaks/yaks_main.mycpp.h"

#include "yaks/preamble.h"
// BEGIN mycpp output

#include "mycpp/runtime.h"

GLOBAL_STR(str0, "(");
GLOBAL_STR(str1, ")");
GLOBAL_STR(str2, "_");
GLOBAL_STR(str3, "T");
GLOBAL_STR(str4, "F");
GLOBAL_STR(str5, "\n<html>\n  <head>\n     <title>oil AST</title>\n     <style>\n      .n { color: brown }\n      .s { font-weight: bold }\n      .o { color: darkgreen }\n     </style>\n  </head>\n  <body>\n    <pre>\n");
GLOBAL_STR(str6, "\n    </pre>\n  </body>\n</html>\n    ");
GLOBAL_STR(str7, "n");
GLOBAL_STR(str8, "s");
GLOBAL_STR(str9, "o");
GLOBAL_STR(str10, "o");
GLOBAL_STR(str11, "o");
GLOBAL_STR(str12, "<span class=\"%s\">");
GLOBAL_STR(str13, "</span>");
GLOBAL_STR(str14, " ");
GLOBAL_STR(str15, "\n");
GLOBAL_STR(str16, " ");
GLOBAL_STR(str17, "]");
GLOBAL_STR(str18, " ");
GLOBAL_STR(str19, " ");
GLOBAL_STR(str20, "\n");
GLOBAL_STR(str21, "\n");
GLOBAL_STR(str22, " ");
GLOBAL_STR(str23, "%s%s: [");
GLOBAL_STR(str24, "\n");
GLOBAL_STR(str25, "\n");
GLOBAL_STR(str26, "%s]");
GLOBAL_STR(str27, "%s%s: ");
GLOBAL_STR(str28, "\n");
GLOBAL_STR(str29, "\n");
GLOBAL_STR(str30, " ");
GLOBAL_STR(str31, "UNTYPED any");
GLOBAL_STR(str32, "...0x%s");
GLOBAL_STR(str33, " ");
GLOBAL_STR(str34, " ");
GLOBAL_STR(str35, " %s:");
GLOBAL_STR(str36, "UNTYPED any");
GLOBAL_STR(str37, "[");
GLOBAL_STR(str38, " ");
GLOBAL_STR(str39, "]");
GLOBAL_STR(str40, "...0x%s");
GLOBAL_STR(str41, "foo");
GLOBAL_STR(str42, "\n");
GLOBAL_STR(str43, "<%s %r>");
GLOBAL_STR(str44, "code");
GLOBAL_STR(str45, "message");
GLOBAL_STR(str46, "%s, got %s");
GLOBAL_STR(str47, " (line %d, offset %d-%d: %r)");
GLOBAL_STR(str48, "");
GLOBAL_STR(str49, " 0x%s");
GLOBAL_STR(str50, "");
GLOBAL_STR(str51, "\n");
GLOBAL_STR(str52, "\n");
GLOBAL_STR(str53, " ");
GLOBAL_STR(str54, "[]");
GLOBAL_STR(str55, "[");
GLOBAL_STR(str56, ",");
GLOBAL_STR(str57, "]");
GLOBAL_STR(str58, "{}");
GLOBAL_STR(str59, "{");
GLOBAL_STR(str60, ",");
GLOBAL_STR(str61, ":");
GLOBAL_STR(str62, "}");
GLOBAL_STR(str63, "{");
GLOBAL_STR(str64, "\"type\":");
GLOBAL_STR(str65, "\"data\":");
GLOBAL_STR(str66, "}");
GLOBAL_STR(str67, "\"SparseArray\",");
GLOBAL_STR(str68, "{}");
GLOBAL_STR(str69, "{");
GLOBAL_STR(str70, ",");
GLOBAL_STR(str71, ":");
GLOBAL_STR(str72, "}");
GLOBAL_STR(str73, "\"BashArray\",");
GLOBAL_STR(str74, "{}");
GLOBAL_STR(str75, "{");
GLOBAL_STR(str76, ",");
GLOBAL_STR(str77, ":");
GLOBAL_STR(str78, "}");
GLOBAL_STR(str79, "\"BashAssoc\",");
GLOBAL_STR(str80, "{}");
GLOBAL_STR(str81, "{");
GLOBAL_STR(str82, ",");
GLOBAL_STR(str83, ":");
GLOBAL_STR(str84, "}");
GLOBAL_STR(str85, "null");
GLOBAL_STR(str86, "true");
GLOBAL_STR(str87, "false");
GLOBAL_STR(str88, "null");
GLOBAL_STR(str89, "INFINITY");
GLOBAL_STR(str90, "-");
GLOBAL_STR(str91, "null");
GLOBAL_STR(str92, "NAN");
GLOBAL_STR(str93, "[ -->%s ]");
GLOBAL_STR(str94, "Can't encode List%s in object cycle");
GLOBAL_STR(str95, "{ -->%s }");
GLOBAL_STR(str96, "Can't encode Dict%s in object cycle");
GLOBAL_STR(str97, "<%s%s>");
GLOBAL_STR(str98, "Can't serialize object of type %s");
GLOBAL_STR(str99, "Single quotes aren't part of JSON; you may want 'json8 read'");
GLOBAL_STR(str100, "Comments aren't part of JSON; you may want 'json8 read'");
GLOBAL_STR(str101, "Pure JSON does not accept j\"\" prefix");
GLOBAL_STR(str102, "Invalid UTF-8 in %s string literal");
GLOBAL_STR(str103, "J8 Lines can't have unescaped ASCII control chars");
GLOBAL_STR(str104, "Unexpected EOF while lexing %s string");
GLOBAL_STR(str105, "Bad backslash escape in %s string");
GLOBAL_STR(str106, "%s strings can't have unescaped ASCII control chars");
GLOBAL_STR(str107, "Invalid UTF-8 in %s string literal");
GLOBAL_STR(str108, "Code point can't be greater than U+10ffff");
GLOBAL_STR(str109, "\\u{%s} escape is illegal because it's in the surrogate range");
GLOBAL_STR(str110, "\\y%s escapes not allowed in u'' strings");
GLOBAL_STR(str111, "J8");
GLOBAL_STR(str112, "JSON");
GLOBAL_STR(str113, "");
GLOBAL_STR(str114, "Expected %s, got %s");
GLOBAL_STR(str115, "t");
GLOBAL_STR(str116, "Integer is too big");
GLOBAL_STR(str117, "Unexpected EOF while parsing %s");
GLOBAL_STR(str118, "Invalid token while parsing %s: %s");
GLOBAL_STR(str119, "Got %d bytes of unexpected trailing input");
GLOBAL_STR(str120, "t");
GLOBAL_STR(str121, "Unexpected EOF while parsing %s");
GLOBAL_STR(str122, "Invalid token while parsing %s: %s");
GLOBAL_STR(str123, "Unexpected trailing input");
GLOBAL_STR(str124, "%s tok_id %s %d-%d");
GLOBAL_STR(str125, "Unexpected text after J8 Line (%s)");
GLOBAL_STR(str126, "Unexpected trailing input in J8 Lines");
GLOBAL_STR(str127, "\u001b[0;0m");
GLOBAL_STR(str128, "\u001b[1m");
GLOBAL_STR(str129, "\u001b[4m");
GLOBAL_STR(str130, "\u001b[7m");
GLOBAL_STR(str131, "\u001b[31m");
GLOBAL_STR(str132, "\u001b[32m");
GLOBAL_STR(str133, "\u001b[33m");
GLOBAL_STR(str134, "\u001b[34m");
GLOBAL_STR(str135, "\u001b[35m");
GLOBAL_STR(str136, "\u001b[36m");
GLOBAL_STR(str137, "\u001b[37m");
GLOBAL_STR(str138, "\n");
GLOBAL_STR(str139, "&");
GLOBAL_STR(str140, "&amp;");
GLOBAL_STR(str141, "<");
GLOBAL_STR(str142, "&lt;");
GLOBAL_STR(str143, ">");
GLOBAL_STR(str144, "&gt;");
GLOBAL_STR(str145, "int");
GLOBAL_STR(str146, "BigStr*");
GLOBAL_STR(str147, "List<");
GLOBAL_STR(str148, ">*");
GLOBAL_STR(str149, " %s");
GLOBAL_STR(str150, "%d");
GLOBAL_STR(str151, "  return ");
GLOBAL_STR(str152, ";\n");
GLOBAL_STR(str153, " %s(");
GLOBAL_STR(str154, ", ");
GLOBAL_STR(str155, ") {\n");
GLOBAL_STR(str156, "}\n");
GLOBAL_STR(str157, "#include \"mycpp/runtime.h\"\n");
GLOBAL_STR(str158, "namespace %s {\n");
GLOBAL_STR(str159, "}  // namespace %s\n");
GLOBAL_STR(str160, "Expected Symbol, got %s");
GLOBAL_STR(str161, "Expected List, got %s");
GLOBAL_STR(str162, "path");
GLOBAL_STR(str163, "chunk");
GLOBAL_STR(str164, "Bool");
GLOBAL_STR(str165, "Int");
GLOBAL_STR(str166, "Str");
GLOBAL_STR(str167, "List");
GLOBAL_STR(str168, "Dict");
GLOBAL_STR(str169, "Signature should have 3 items: =>  params  return");
GLOBAL_STR(str170, "=>");
GLOBAL_STR(str171, "Signature should start with =>");
GLOBAL_STR(str172, "Statement shouldn't be empty");
GLOBAL_STR(str173, "var");
GLOBAL_STR(str174, "setvar");
GLOBAL_STR(str175, "call");
GLOBAL_STR(str176, "return");
GLOBAL_STR(str177, "break");
GLOBAL_STR(str178, "continue");
GLOBAL_STR(str179, "Invalid statment %r");
GLOBAL_STR(str180, "Module should have at least 2 items, got %d");
GLOBAL_STR(str181, "Module shouldn't be empty");
GLOBAL_STR(str182, "global");
GLOBAL_STR(str183, "func");
GLOBAL_STR(str184, "class");
GLOBAL_STR(str185, "Invalid module def %r");
GLOBAL_STR(str186, "foo");
GLOBAL_STR(str187, "Action required");
GLOBAL_STR(str188, "cpp");
GLOBAL_STR(str189, "");
GLOBAL_STR(str190, "\n");
GLOBAL_STR(str191, "\n");
GLOBAL_STR(str192, "check");
GLOBAL_STR(str193, "hi");
GLOBAL_STR(str194, "\n");
GLOBAL_STR(str195, "Invalid action %r");

namespace runtime {  // forward declare

  class TraversalState;

}  // forward declare namespace runtime

namespace format {  // forward declare

  class ColorOutput;
  class TextOutput;
  class HtmlOutput;
  class AnsiOutput;
  class _PrettyPrinter;

}  // forward declare namespace format

namespace error {  // forward declare

  class _ErrorWithLocation;
  class Usage;
  class Parse;
  class FailGlob;
  class RedirectEval;
  class FatalRuntime;
  class Strict;
  class ErrExit;
  class Expr;
  class Structured;
  class AssertionErr;
  class TypeErrVerbose;
  class TypeErr;
  class Runtime;
  class Decode;
  class Encode;

}  // forward declare namespace error

namespace num {  // forward declare


}  // forward declare namespace num

namespace j8 {  // forward declare

  class InstancePrinter;
  class PrettyPrinter;
  class LexerDecoder;
  class _Parser;
  class Parser;
  class Nil8Parser;
  class J8LinesParser;

}  // forward declare namespace j8

namespace j8_lite {  // forward declare


}  // forward declare namespace j8_lite

namespace ansi {  // forward declare


}  // forward declare namespace ansi

namespace pretty {  // forward declare

  class PrettyPrinter;

}  // forward declare namespace pretty

namespace cgi {  // forward declare


}  // forward declare namespace cgi

namespace gen_cpp {  // forward declare


}  // forward declare namespace gen_cpp

namespace transform {  // forward declare


}  // forward declare namespace transform

namespace yaks_main {  // forward declare


}  // forward declare namespace yaks_main

namespace runtime {  // declare

using hnode_asdl::hnode;
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<int, bool>* seen;
  Dict<int, int>* 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

using hnode_asdl::hnode;
format::ColorOutput* DetectConsoleOutput(mylib::Writer* f);
class ColorOutput {
 public:
  ColorOutput(mylib::Writer* f);
  virtual format::ColorOutput* NewTempBuffer();
  virtual void FileHeader();
  virtual void FileFooter();
  virtual void PushColor(hnode_asdl::color_t e_color);
  virtual void PopColor();
  virtual void write(BigStr* s);
  void WriteRaw(Tuple2<BigStr*, int>* raw);
  int NumChars();
  Tuple2<BigStr*, int> GetRaw();
  mylib::Writer* f;
  int num_chars;
  
  static constexpr uint32_t field_mask() {
    return maskbit(offsetof(ColorOutput, f));
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(ColorOutput));
  }

  DISALLOW_COPY_AND_ASSIGN(ColorOutput)
};

class TextOutput : public ::format::ColorOutput {
 public:
  TextOutput(mylib::Writer* f);
  virtual format::TextOutput* NewTempBuffer();
  virtual void PushColor(hnode_asdl::color_t e_color);
  virtual void PopColor();
  
  static constexpr uint32_t field_mask() {
    return ::format::ColorOutput::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(TextOutput));
  }

  DISALLOW_COPY_AND_ASSIGN(TextOutput)
};

class HtmlOutput : public ::format::ColorOutput {
 public:
  HtmlOutput(mylib::Writer* f);
  virtual format::HtmlOutput* NewTempBuffer();
  virtual void FileHeader();
  virtual void FileFooter();
  virtual void PushColor(hnode_asdl::color_t e_color);
  virtual void PopColor();
  virtual void write(BigStr* s);
  
  static constexpr uint32_t field_mask() {
    return ::format::ColorOutput::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(HtmlOutput));
  }

  DISALLOW_COPY_AND_ASSIGN(HtmlOutput)
};

class AnsiOutput : public ::format::ColorOutput {
 public:
  AnsiOutput(mylib::Writer* f);
  virtual format::AnsiOutput* NewTempBuffer();
  virtual void PushColor(hnode_asdl::color_t e_color);
  virtual void PopColor();
  
  static constexpr uint32_t field_mask() {
    return ::format::ColorOutput::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(AnsiOutput));
  }

  DISALLOW_COPY_AND_ASSIGN(AnsiOutput)
};

extern int INDENT;
class _PrettyPrinter {
 public:
  _PrettyPrinter(int max_col);
  bool _PrintWrappedArray(List<hnode_asdl::hnode_t*>* array, int prefix_len, format::ColorOutput* f, int indent);
  bool _PrintWholeArray(List<hnode_asdl::hnode_t*>* array, int prefix_len, format::ColorOutput* f, int indent);
  void _PrintRecord(hnode::Record* node, format::ColorOutput* f, int indent);
  void PrintNode(hnode_asdl::hnode_t* node, format::ColorOutput* f, int indent);
  int max_col;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(0, sizeof(_PrettyPrinter));
  }

  DISALLOW_COPY_AND_ASSIGN(_PrettyPrinter)
};

bool _TrySingleLineObj(hnode::Record* node, format::ColorOutput* f, int max_chars);
bool _TrySingleLine(hnode_asdl::hnode_t* node, format::ColorOutput* f, int max_chars);
void PrintTree(hnode_asdl::hnode_t* node, format::ColorOutput* f);
void PrintTree2(hnode_asdl::hnode_t* node, format::ColorOutput* f);

}  // declare namespace format

namespace error {  // declare

using syntax_asdl::loc;
BigStr* _ValType(value_asdl::value_t* val);
class _ErrorWithLocation {
 public:
  _ErrorWithLocation(BigStr* msg, syntax_asdl::loc_t* location);
  bool HasLocation();
  BigStr* UserErrorString();
  syntax_asdl::loc_t* location;
  BigStr* msg;
  
  static constexpr uint32_t field_mask() {
    return maskbit(offsetof(_ErrorWithLocation, location))
         | maskbit(offsetof(_ErrorWithLocation, msg));
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(_ErrorWithLocation));
  }

  DISALLOW_COPY_AND_ASSIGN(_ErrorWithLocation)
};

class Usage : public ::error::_ErrorWithLocation {
 public:
  Usage(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::_ErrorWithLocation::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Usage));
  }

  DISALLOW_COPY_AND_ASSIGN(Usage)
};

class Parse : public ::error::_ErrorWithLocation {
 public:
  Parse(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::_ErrorWithLocation::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Parse));
  }

  DISALLOW_COPY_AND_ASSIGN(Parse)
};

class FailGlob : public ::error::_ErrorWithLocation {
 public:
  FailGlob(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::_ErrorWithLocation::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(FailGlob));
  }

  DISALLOW_COPY_AND_ASSIGN(FailGlob)
};

class RedirectEval : public ::error::_ErrorWithLocation {
 public:
  RedirectEval(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::_ErrorWithLocation::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(RedirectEval));
  }

  DISALLOW_COPY_AND_ASSIGN(RedirectEval)
};

class FatalRuntime : public ::error::_ErrorWithLocation {
 public:
  FatalRuntime(int exit_status, BigStr* msg, syntax_asdl::loc_t* location);
  int ExitStatus();

  int exit_status;
  
  static constexpr uint32_t field_mask() {
    return ::error::_ErrorWithLocation::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(FatalRuntime));
  }

  DISALLOW_COPY_AND_ASSIGN(FatalRuntime)
};

class Strict : public ::error::FatalRuntime {
 public:
  Strict(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::FatalRuntime::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Strict));
  }

  DISALLOW_COPY_AND_ASSIGN(Strict)
};

class ErrExit : public ::error::FatalRuntime {
 public:
  ErrExit(int exit_status, BigStr* msg, syntax_asdl::loc_t* location, bool show_code = false);

  bool show_code;
  
  static constexpr uint32_t field_mask() {
    return ::error::FatalRuntime::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(ErrExit));
  }

  DISALLOW_COPY_AND_ASSIGN(ErrExit)
};

class Expr : public ::error::FatalRuntime {
 public:
  Expr(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::FatalRuntime::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Expr));
  }

  DISALLOW_COPY_AND_ASSIGN(Expr)
};

class Structured : public ::error::FatalRuntime {
 public:
  Structured(int status, BigStr* msg, syntax_asdl::loc_t* location, Dict<BigStr*, value_asdl::value_t*>* properties = nullptr);
  value::Dict* ToDict();

  Dict<BigStr*, value_asdl::value_t*>* properties;
  
  static constexpr uint32_t field_mask() {
    return ::error::FatalRuntime::field_mask()
         | maskbit(offsetof(Structured, properties));
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Structured));
  }

  DISALLOW_COPY_AND_ASSIGN(Structured)
};

class AssertionErr : public ::error::Expr {
 public:
  AssertionErr(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::Expr::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(AssertionErr));
  }

  DISALLOW_COPY_AND_ASSIGN(AssertionErr)
};

class TypeErrVerbose : public ::error::Expr {
 public:
  TypeErrVerbose(BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::Expr::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(TypeErrVerbose));
  }

  DISALLOW_COPY_AND_ASSIGN(TypeErrVerbose)
};

class TypeErr : public ::error::TypeErrVerbose {
 public:
  TypeErr(value_asdl::value_t* actual_val, BigStr* msg, syntax_asdl::loc_t* location);
  
  static constexpr uint32_t field_mask() {
    return ::error::TypeErrVerbose::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(TypeErr));
  }

  DISALLOW_COPY_AND_ASSIGN(TypeErr)
};

class Runtime {
 public:
  Runtime(BigStr* msg);
  BigStr* UserErrorString();
  BigStr* msg;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(1, sizeof(Runtime));
  }

  DISALLOW_COPY_AND_ASSIGN(Runtime)
};

class Decode {
 public:
  Decode(BigStr* msg, BigStr* s, int start_pos, int end_pos, int line_num);
  BigStr* Message();
  BigStr* __str__();
  BigStr* msg;
  BigStr* s;
  int start_pos;
  int end_pos;
  int line_num;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(2, sizeof(Decode));
  }

  DISALLOW_COPY_AND_ASSIGN(Decode)
};

class Encode {
 public:
  Encode(BigStr* msg);
  BigStr* Message();
  BigStr* msg;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(1, sizeof(Encode));
  }

  DISALLOW_COPY_AND_ASSIGN(Encode)
};

[[noreturn]] void e_usage(BigStr* msg, syntax_asdl::loc_t* location);
[[noreturn]] void e_strict(BigStr* msg, syntax_asdl::loc_t* location);
[[noreturn]] void p_die(BigStr* msg, syntax_asdl::loc_t* location);
[[noreturn]] void e_die(BigStr* msg, syntax_asdl::loc_t* location = nullptr);
[[noreturn]] void e_die_status(int status, BigStr* msg, syntax_asdl::loc_t* location = nullptr);

}  // declare namespace error

namespace num {  // declare

value::Int* ToBig(int i);
mops::BigInt Exponent(mops::BigInt x, mops::BigInt y);

}  // declare namespace num

namespace j8 {  // declare

using id_kind_asdl::Id;
BigStr* ValType(value_asdl::value_t* val);
int ValueId(value_asdl::value_t* val);
BigStr* ValueIdString(value_asdl::value_t* val);
BigStr* Utf8Encode(int code);
extern int SHOW_CYCLES;
extern int SHOW_NON_DATA;
extern int LOSSY_JSON;
extern int INF_NAN_ARE_NULL;
void _Print(value_asdl::value_t* val, mylib::BufWriter* buf, int indent, int options = 0);
void PrintMessage(value_asdl::value_t* val, mylib::BufWriter* buf, int indent);
void PrintJsonMessage(value_asdl::value_t* val, mylib::BufWriter* buf, int indent);
void PrintLine(value_asdl::value_t* val, mylib::Writer* f);
void EncodeString(BigStr* s, mylib::BufWriter* buf, bool unquoted_ok = false);
BigStr* MaybeEncodeString(BigStr* s);
BigStr* MaybeEncodeJsonString(BigStr* s);
extern int UNSEEN;
extern int EXPLORING;
extern int FINISHED;
class InstancePrinter {
 public:
  InstancePrinter(mylib::BufWriter* buf, int indent, int options);
  void _ItemIndent(int level);
  void _BracketIndent(int level);
  void _MaybeNewline();
  void _MaybeSpace();
  void _PrintList(value::List* val, int level);
  void _PrintDict(value::Dict* val, int level);
  void _PrintBashPrefix(BigStr* type_str, int level);
  void _PrintBashSuffix(int level);
  void _PrintSparseArray(value::SparseArray* val, int level);
  void _PrintBashArray(value::BashArray* val, int level);
  void _PrintBashAssoc(value::BashAssoc* val, int level);
  void Print(value_asdl::value_t* val, int level = 0);
  mylib::BufWriter* buf;
  Dict<int, int>* visited;
  int indent;
  int options;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(2, sizeof(InstancePrinter));
  }

  DISALLOW_COPY_AND_ASSIGN(InstancePrinter)
};

class PrettyPrinter {
 public:
  PrettyPrinter(int max_col);
  void PrettyTree(value_asdl::value_t* val, format::ColorOutput* f);
  void Print(value_asdl::value_t* val, mylib::BufWriter* buf);
  Dict<int, int>* ref_count;
  int max_col;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(1, sizeof(PrettyPrinter));
  }

  DISALLOW_COPY_AND_ASSIGN(PrettyPrinter)
};

class LexerDecoder {
 public:
  LexerDecoder(BigStr* s, bool is_j8, BigStr* lang_str);
  error::Decode* _Error(BigStr* msg, int end_pos);
  Tuple3<int, int, BigStr*> Next();
  Tuple3<int, int, BigStr*> NextForLines();
  Tuple3<int, int, BigStr*> _DecodeString(int left_id, int str_pos);
  BigStr* s;
  BigStr* lang_str;
  mylib::BufWriter* decoded;
  bool is_j8;
  int pos;
  int cur_line_num;

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassScanned(3, sizeof(LexerDecoder));
  }

  DISALLOW_COPY_AND_ASSIGN(LexerDecoder)
};

class _Parser {
 public:
  _Parser(BigStr* s, bool is_j8);
  void _Next();
  void _Eat(int tok_id);
  void _NextForLines();
  error::Decode* _ParseError(BigStr* msg);
  BigStr* decoded;
  int end_pos;
  bool is_j8;
  BigStr* lang_str;
  j8::LexerDecoder* lexer;
  BigStr* s;
  int start_pos;
  int tok_id;
  
  static constexpr uint32_t field_mask() {
    return maskbit(offsetof(_Parser, decoded))
         | maskbit(offsetof(_Parser, lang_str))
         | maskbit(offsetof(_Parser, lexer))
         | maskbit(offsetof(_Parser, s));
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(_Parser));
  }

  DISALLOW_COPY_AND_ASSIGN(_Parser)
};

class Parser : public ::j8::_Parser {
 public:
  Parser(BigStr* s, bool is_j8);
  Tuple2<BigStr*, value_asdl::value_t*> _ParsePair();
  value_asdl::value_t* _ParseDict();
  value_asdl::value_t* _ParseList();
  value_asdl::value_t* _ParseValue();
  value_asdl::value_t* ParseValue();
  
  static constexpr uint32_t field_mask() {
    return ::j8::_Parser::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Parser));
  }

  DISALLOW_COPY_AND_ASSIGN(Parser)
};

class Nil8Parser : public ::j8::_Parser {
 public:
  Nil8Parser(BigStr* s, bool is_j8);
  nil8_asdl::nvalue_t* _ParseRecord();
  nil8_asdl::nvalue_t* _ParseList8();
  nil8_asdl::nvalue_t* _ParseNil8();
  nil8_asdl::nvalue_t* ParseNil8();
  
  static constexpr uint32_t field_mask() {
    return ::j8::_Parser::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(Nil8Parser));
  }

  DISALLOW_COPY_AND_ASSIGN(Nil8Parser)
};

class J8LinesParser : public ::j8::_Parser {
 public:
  J8LinesParser(BigStr* s);
  void _Show(BigStr* s);
  void _ParseLine(List<BigStr*>* out);
  List<BigStr*>* Parse();
  
  static constexpr uint32_t field_mask() {
    return ::j8::_Parser::field_mask();
  }

  static constexpr ObjHeader obj_header() {
    return ObjHeader::ClassFixed(field_mask(), sizeof(J8LinesParser));
  }

  DISALLOW_COPY_AND_ASSIGN(J8LinesParser)
};

List<BigStr*>* SplitJ8Lines(BigStr* s);

}  // declare namespace j8

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 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::MeasuredDoc* _Concat(List<pretty_asdl::MeasuredDoc*>* 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, doc::Group* 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 cgi {  // declare

BigStr* escape(BigStr* s);

}  // declare namespace cgi

namespace gen_cpp {  // declare

void GenType(yaks_asdl::ktype_t* typ, mylib::Writer* f);
void GenParam(yaks_asdl::NameType* p, mylib::Writer* f);
void GenExpr(yaks_asdl::kexpr_t* expr, mylib::Writer* f);
void GenStatement(yaks_asdl::stmt_t* st, mylib::Writer* f);
void GenFunction(mod_def::Func* func, mylib::Writer* f);
void GenCpp(yaks_asdl::Program* prog, mylib::Writer* f);

}  // declare namespace gen_cpp

namespace transform {  // declare

BigStr* MustBeSymbol(nil8_asdl::nvalue_t* nval);
List<nil8_asdl::nvalue_t*>* MustBeList(nil8_asdl::nvalue_t* nval);
yaks_asdl::kexpr_t* TransformExpr(nil8_asdl::nvalue_t* nval);
yaks_asdl::ktype_t* TransformType(nil8_asdl::nvalue_t* nval);
yaks_asdl::NameType* TransformParam(List<nil8_asdl::nvalue_t*>* param_n);
List<yaks_asdl::NameType*>* TransformParams(List<nil8_asdl::nvalue_t*>* params_n);
yaks_asdl::Signature* TransformSignature(nil8_asdl::nvalue_t* nval);
mod_def::Func* TransformFunc(List<nil8_asdl::nvalue_t*>* func_n);
yaks_asdl::Module* TransformModule(List<nil8_asdl::nvalue_t*>* mod_n);
yaks_asdl::Program* Transform(nil8_asdl::nvalue_t* nval);

}  // declare namespace transform

namespace yaks_main {  // declare

int main(List<BigStr*>* argv);

}  // declare namespace yaks_main

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<hnode::Record>(node_type, Alloc<List<hnode_asdl::Field*>>(), false, str0, str1, Alloc<List<hnode_asdl::hnode_t*>>());
}

hnode::Leaf* NewLeaf(BigStr* s, hnode_asdl::color_t e_color) {
  StackRoot _root0(&s);

  if (s == nullptr) {
    return Alloc<hnode::Leaf>(str2, color_e::OtherConst);
  }
  else {
    return Alloc<hnode::Leaf>(s, e_color);
  }
}

TraversalState::TraversalState() {
  this->seen = Alloc<Dict<int, bool>>();
  this->ref_count = Alloc<Dict<int, int>>();
}
BigStr* TRUE_STR = str3;
BigStr* FALSE_STR = str4;

}  // define namespace runtime

namespace format {  // define

using hnode_asdl::hnode;
using hnode_asdl::hnode_e;
using hnode_asdl::hnode_t;
using hnode_asdl::color_e;
using hnode_asdl::color_t;

format::ColorOutput* DetectConsoleOutput(mylib::Writer* f) {
  StackRoot _root0(&f);

  if (f->isatty()) {
    return Alloc<AnsiOutput>(f);
  }
  else {
    return Alloc<TextOutput>(f);
  }
}

ColorOutput::ColorOutput(mylib::Writer* f) {
  this->f = f;
  this->num_chars = 0;
}

format::ColorOutput* ColorOutput::NewTempBuffer() {
  FAIL(kNotImplemented);  // Python NotImplementedError
}

void ColorOutput::FileHeader() {
  ;  // pass
}

void ColorOutput::FileFooter() {
  ;  // pass
}

void ColorOutput::PushColor(hnode_asdl::color_t e_color) {
  FAIL(kNotImplemented);  // Python NotImplementedError
}

void ColorOutput::PopColor() {
  FAIL(kNotImplemented);  // Python NotImplementedError
}

void ColorOutput::write(BigStr* s) {
  StackRoot _root0(&s);

  this->f->write(s);
  this->num_chars += len(s);
}

void ColorOutput::WriteRaw(Tuple2<BigStr*, int>* raw) {
  BigStr* s = nullptr;
  int num_chars;
  StackRoot _root0(&raw);
  StackRoot _root1(&s);

  Tuple2<BigStr*, int>* tup0 = raw;
  s = tup0->at0();
  num_chars = tup0->at1();
  this->f->write(s);
  this->num_chars += num_chars;
}

int ColorOutput::NumChars() {
  return this->num_chars;
}

Tuple2<BigStr*, int> ColorOutput::GetRaw() {
  mylib::BufWriter* f = nullptr;
  StackRoot _root0(&f);

  f = static_cast<mylib::BufWriter*>(this->f);
  return Tuple2<BigStr*, int>(f->getvalue(), this->num_chars);
}

TextOutput::TextOutput(mylib::Writer* f) : ::format::ColorOutput(f) {
}

format::TextOutput* TextOutput::NewTempBuffer() {
  return Alloc<TextOutput>(Alloc<mylib::BufWriter>());
}

void TextOutput::PushColor(hnode_asdl::color_t e_color) {
  ;  // pass
}

void TextOutput::PopColor() {
  ;  // pass
}

HtmlOutput::HtmlOutput(mylib::Writer* f) : ::format::ColorOutput(f) {
}

format::HtmlOutput* HtmlOutput::NewTempBuffer() {
  return Alloc<HtmlOutput>(Alloc<mylib::BufWriter>());
}

void HtmlOutput::FileHeader() {
  this->f->write(str5);
}

void HtmlOutput::FileFooter() {
  this->f->write(str6);
}

void HtmlOutput::PushColor(hnode_asdl::color_t e_color) {
  BigStr* css_class = nullptr;
  StackRoot _root0(&css_class);

  if (e_color == color_e::TypeName) {
    css_class = str7;
  }
  else {
    if (e_color == color_e::StringConst) {
      css_class = str8;
    }
    else {
      if (e_color == color_e::OtherConst) {
        css_class = str9;
      }
      else {
        if (e_color == color_e::External) {
          css_class = str10;
        }
        else {
          if (e_color == color_e::UserType) {
            css_class = str11;
          }
          else {
            assert(0);  // AssertionError
          }
        }
      }
    }
  }
  this->f->write(StrFormat("<span class=\"%s\">", css_class));
}

void HtmlOutput::PopColor() {
  this->f->write(str13);
}

void HtmlOutput::write(BigStr* s) {
  StackRoot _root0(&s);

  this->f->write(cgi::escape(s));
  this->num_chars += len(s);
}

AnsiOutput::AnsiOutput(mylib::Writer* f) : ::format::ColorOutput(f) {
}

format::AnsiOutput* AnsiOutput::NewTempBuffer() {
  return Alloc<AnsiOutput>(Alloc<mylib::BufWriter>());
}

void AnsiOutput::PushColor(hnode_asdl::color_t e_color) {
  if (e_color == color_e::TypeName) {
    this->f->write(ansi::YELLOW);
  }
  else {
    if (e_color == color_e::StringConst) {
      this->f->write(ansi::BOLD);
    }
    else {
      if (e_color == color_e::OtherConst) {
        this->f->write(ansi::GREEN);
      }
      else {
        if (e_color == color_e::External) {
          this->f->write(str_concat(ansi::BOLD, ansi::BLUE));
        }
        else {
          if (e_color == color_e::UserType) {
            this->f->write(ansi::GREEN);
          }
          else {
            assert(0);  // AssertionError
          }
        }
      }
    }
  }
}

void AnsiOutput::PopColor() {
  this->f->write(ansi::RESET);
}
int INDENT = 2;

_PrettyPrinter::_PrettyPrinter(int max_col) {
  this->max_col = max_col;
}

bool _PrettyPrinter::_PrintWrappedArray(List<hnode_asdl::hnode_t*>* array, int prefix_len, format::ColorOutput* f, int indent) {
  bool all_fit;
  int chars_so_far;
  int i;
  format::ColorOutput* single_f = nullptr;
  BigStr* s = nullptr;
  int num_chars;
  StackRoot _root0(&array);
  StackRoot _root1(&f);
  StackRoot _root2(&single_f);
  StackRoot _root3(&s);

  all_fit = true;
  chars_so_far = prefix_len;
  i = 0;
  for (ListIter<hnode_asdl::hnode_t*> it(array); !it.Done(); it.Next(), ++i) {
    hnode_asdl::hnode_t* val = it.Value();
    StackRoot _for(&val  );
    if (i != 0) {
      f->write(str14);
    }
    single_f = f->NewTempBuffer();
    if (_TrySingleLine(val, single_f, (this->max_col - chars_so_far))) {
      Tuple2<BigStr*, int> tup1 = single_f->GetRaw();
      s = tup1.at0();
      num_chars = tup1.at1();
      f->WriteRaw((Alloc<Tuple2<BigStr*, int>>(s, num_chars)));
      chars_so_far += single_f->NumChars();
    }
    else {
      f->write(str15);
      this->PrintNode(val, f, (indent + INDENT));
      chars_so_far = 0;
      all_fit = false;
    }
  }
  return all_fit;
}

bool _PrettyPrinter::_PrintWholeArray(List<hnode_asdl::hnode_t*>* array, int prefix_len, format::ColorOutput* f, int indent) {
  bool all_fit;
  List<Tuple2<BigStr*, int>*>* pieces = nullptr;
  int chars_so_far;
  format::ColorOutput* single_f = nullptr;
  BigStr* s = nullptr;
  int num_chars;
  int i;
  StackRoot _root0(&array);
  StackRoot _root1(&f);
  StackRoot _root2(&pieces);
  StackRoot _root3(&single_f);
  StackRoot _root4(&s);

  all_fit = true;
  pieces = Alloc<List<Tuple2<BigStr*, int>*>>();
  chars_so_far = prefix_len;
  for (ListIter<hnode_asdl::hnode_t*> it(array); !it.Done(); it.Next()) {
    hnode_asdl::hnode_t* item = it.Value();
    StackRoot _for(&item  );
    single_f = f->NewTempBuffer();
    if (_TrySingleLine(item, single_f, (this->max_col - chars_so_far))) {
      Tuple2<BigStr*, int> tup2 = single_f->GetRaw();
      s = tup2.at0();
      num_chars = tup2.at1();
      pieces->append((Alloc<Tuple2<BigStr*, int>>(s, num_chars)));
      chars_so_far += single_f->NumChars();
    }
    else {
      all_fit = false;
      break;
    }
  }
  if (all_fit) {
    i = 0;
    for (ListIter<Tuple2<BigStr*, int>*> it(pieces); !it.Done(); it.Next(), ++i) {
      Tuple2<BigStr*, int>* p = it.Value();
      StackRoot _for(&p    );
      if (i != 0) {
        f->write(str16);
      }
      f->WriteRaw(p);
    }
    f->write(str17);
  }
  return all_fit;
}

void _PrettyPrinter::_PrintRecord(hnode::Record* node, format::ColorOutput* f, int indent) {
  BigStr* ind = nullptr;
  BigStr* prefix = nullptr;
  int prefix_len;
  bool all_fit;
  BigStr* name = nullptr;
  hnode_asdl::hnode_t* val = nullptr;
  BigStr* ind1 = nullptr;
  hnode_asdl::hnode_t* UP_val = nullptr;
  int tag;
  BigStr* name_str = nullptr;
  format::ColorOutput* single_f = nullptr;
  BigStr* s = nullptr;
  int num_chars;
  StackRoot _root0(&node);
  StackRoot _root1(&f);
  StackRoot _root2(&ind);
  StackRoot _root3(&prefix);
  StackRoot _root4(&name);
  StackRoot _root5(&val);
  StackRoot _root6(&ind1);
  StackRoot _root7(&UP_val);
  StackRoot _root8(&name_str);
  StackRoot _root9(&single_f);
  StackRoot _root10(&s);

  ind = str_repeat(str18, indent);
  if (node->abbrev) {
    prefix = str_concat(ind, node->left);
    f->write(prefix);
    if (len(node->node_type)) {
      f->PushColor(color_e::TypeName);
      f->write(node->node_type);
      f->PopColor();
      f->write(str19);
    }
    prefix_len = ((len(prefix) + len(node->node_type)) + 1);
    all_fit = this->_PrintWrappedArray(node->unnamed_fields, prefix_len, f, indent);
    if (!all_fit) {
      f->write(str20);
      f->write(ind);
    }
    f->write(node->right);
  }
  else {
    f->write(str_concat(ind, node->left));
    f->PushColor(color_e::TypeName);
    f->write(node->node_type);
    f->PopColor();
    f->write(str21);
    for (ListIter<hnode_asdl::Field*> it(node->fields); !it.Done(); it.Next()) {
      hnode_asdl::Field* field = it.Value();
      StackRoot _for(&field    );
      name = field->name;
      val = field->val;
      ind1 = str_repeat(str22, (indent + INDENT));
      UP_val = val;
      tag = val->tag();
      if (tag == hnode_e::Array) {
        hnode::Array* val = static_cast<hnode::Array*>(UP_val);
        name_str = StrFormat("%s%s: [", ind1, name);
        f->write(name_str);
        prefix_len = len(name_str);
        if (!this->_PrintWholeArray(val->children, prefix_len, f, indent)) {
          f->write(str24);
          for (ListIter<hnode_asdl::hnode_t*> it(val->children); !it.Done(); it.Next()) {
            hnode_asdl::hnode_t* child = it.Value();
            StackRoot _for(&child          );
            this->PrintNode(child, f, ((indent + INDENT) + INDENT));
            f->write(str25);
          }
          f->write(StrFormat("%s]", ind1));
        }
      }
      else {
        name_str = StrFormat("%s%s: ", ind1, name);
        f->write(name_str);
        prefix_len = len(name_str);
        single_f = f->NewTempBuffer();
        if (_TrySingleLine(val, single_f, (this->max_col - prefix_len))) {
          Tuple2<BigStr*, int> tup3 = single_f->GetRaw();
          s = tup3.at0();
          num_chars = tup3.at1();
          f->WriteRaw((Alloc<Tuple2<BigStr*, int>>(s, num_chars)));
        }
        else {
          f->write(str28);
          this->PrintNode(val, f, ((indent + INDENT) + INDENT));
        }
      }
      f->write(str29);
    }
    f->write(str_concat(ind, node->right));
  }
}

void _PrettyPrinter::PrintNode(hnode_asdl::hnode_t* node, format::ColorOutput* f, int indent) {
  BigStr* ind = nullptr;
  format::ColorOutput* single_f = nullptr;
  BigStr* s = nullptr;
  int num_chars;
  hnode_asdl::hnode_t* UP_node = nullptr;
  int tag;
  StackRoot _root0(&node);
  StackRoot _root1(&f);
  StackRoot _root2(&ind);
  StackRoot _root3(&single_f);
  StackRoot _root4(&s);
  StackRoot _root5(&UP_node);

  ind = str_repeat(str30, indent);
  single_f = f->NewTempBuffer();
  single_f->write(ind);
  if (_TrySingleLine(node, single_f, (this->max_col - indent))) {
    Tuple2<BigStr*, int> tup4 = single_f->GetRaw();
    s = tup4.at0();
    num_chars = tup4.at1();
    f->WriteRaw((Alloc<Tuple2<BigStr*, int>>(s, num_chars)));
    return ;
  }
  UP_node = node;
  tag = node->tag();
  if (tag == hnode_e::Leaf) {
    hnode::Leaf* node = static_cast<hnode::Leaf*>(UP_node);
    f->PushColor(node->color);
    f->write(j8_lite::EncodeString(node->s, true));
    f->PopColor();
  }
  else {
    if (tag == hnode_e::External) {
      hnode::External* node = static_cast<hnode::External*>(UP_node);
      f->PushColor(color_e::External);
      // if not PYTHON
      {
        f->write(str31);
      }
      // endif MYCPP
      f->PopColor();
    }
    else {
      if (tag == hnode_e::Record) {
        hnode::Record* node = static_cast<hnode::Record*>(UP_node);
        this->_PrintRecord(node, f, indent);
      }
      else {
        if (tag == hnode_e::AlreadySeen) {
          hnode::AlreadySeen* node = static_cast<hnode::AlreadySeen*>(UP_node);
          f->write(StrFormat("...0x%s", mylib::hex_lower(node->heap_id)));
        }
        else {
          assert(0);  // AssertionError
        }
      }
    }
  }
}

bool _TrySingleLineObj(hnode::Record* node, format::ColorOutput* f, int max_chars) {
  int i;
  StackRoot _root0(&node);
  StackRoot _root1(&f);

  f->write(node->left);
  if (node->abbrev) {
    if (len(node->node_type)) {
      f->PushColor(color_e::TypeName);
      f->write(node->node_type);
      f->PopColor();
      f->write(str33);
    }
    i = 0;
    for (ListIter<hnode_asdl::hnode_t*> it(node->unnamed_fields); !it.Done(); it.Next(), ++i) {
      hnode_asdl::hnode_t* val = it.Value();
      StackRoot _for(&val    );
      if (i != 0) {
        f->write(str34);
      }
      if (!_TrySingleLine(val, f, max_chars)) {
        return false;
      }
    }
  }
  else {
    f->PushColor(color_e::TypeName);
    f->write(node->node_type);
    f->PopColor();
    for (ListIter<hnode_asdl::Field*> it(node->fields); !it.Done(); it.Next()) {
      hnode_asdl::Field* field = it.Value();
      StackRoot _for(&field    );
      f->write(StrFormat(" %s:", field->name));
      if (!_TrySingleLine(field->val, f, max_chars)) {
        return false;
      }
    }
  }
  f->write(node->right);
  return true;
}

bool _TrySingleLine(hnode_asdl::hnode_t* node, format::ColorOutput* f, int max_chars) {
  hnode_asdl::hnode_t* UP_node = nullptr;
  int tag;
  int i;
  int num_chars_so_far;
  StackRoot _root0(&node);
  StackRoot _root1(&f);
  StackRoot _root2(&UP_node);

  UP_node = node;
  tag = node->tag();
  if (tag == hnode_e::Leaf) {
    hnode::Leaf* node = static_cast<hnode::Leaf*>(UP_node);
    f->PushColor(node->color);
    f->write(j8_lite::EncodeString(node->s, true));
    f->PopColor();
  }
  else {
    if (tag == hnode_e::External) {
      hnode::External* node = static_cast<hnode::External*>(UP_node);
      f->PushColor(color_e::External);
      // if not PYTHON
      {
        f->write(str36);
      }
      // endif MYCPP
      f->PopColor();
    }
    else {
      if (tag == hnode_e::Array) {
        hnode::Array* node = static_cast<hnode::Array*>(UP_node);
        f->write(str37);
        i = 0;
        for (ListIter<hnode_asdl::hnode_t*> it(node->children); !it.Done(); it.Next(), ++i) {
          hnode_asdl::hnode_t* item = it.Value();
          StackRoot _for(&item        );
          if (i != 0) {
            f->write(str38);
          }
          if (!_TrySingleLine(item, f, max_chars)) {
            return false;
          }
        }
        f->write(str39);
      }
      else {
        if (tag == hnode_e::Record) {
          hnode::Record* node = static_cast<hnode::Record*>(UP_node);
          return _TrySingleLineObj(node, f, max_chars);
        }
        else {
          if (tag == hnode_e::AlreadySeen) {
            hnode::AlreadySeen* node = static_cast<hnode::AlreadySeen*>(UP_node);
            f->write(StrFormat("...0x%s", mylib::hex_lower(node->heap_id)));
          }
          else {
            assert(0);  // AssertionError
          }
        }
      }
    }
  }
  num_chars_so_far = f->NumChars();
  if (num_chars_so_far > max_chars) {
    return false;
  }
  return true;
}

void PrintTree(hnode_asdl::hnode_t* node, format::ColorOutput* f) {
  format::_PrettyPrinter* pp = nullptr;
  StackRoot _root0(&node);
  StackRoot _root1(&f);
  StackRoot _root2(&pp);

  pp = Alloc<_PrettyPrinter>(100);
  pp->PrintNode(node, f, 0);
}

void PrintTree2(hnode_asdl::hnode_t* node, format::ColorOutput* f) {
  pretty_asdl::MeasuredDoc* doc = nullptr;
  pretty::PrettyPrinter* printer = nullptr;
  mylib::BufWriter* buf = nullptr;
  StackRoot _root0(&node);
  StackRoot _root1(&f);
  StackRoot _root2(&doc);
  StackRoot _root3(&printer);
  StackRoot _root4(&buf);

  doc = pretty::AsciiText(str41);
  printer = Alloc<pretty::PrettyPrinter>(20);
  buf = Alloc<mylib::BufWriter>();
  printer->PrintDoc(doc, buf);
  f->write(buf->getvalue());
  f->write(str42);
}

}  // define namespace format

namespace error {  // define

using syntax_asdl::loc_e;
using syntax_asdl::loc_t;
using syntax_asdl::loc;
using value_asdl::value;
using value_asdl::value_t;
using value_asdl::value_str;

BigStr* _ValType(value_asdl::value_t* val) {
  StackRoot _root0(&val);

  return value_str(val->tag(), false);
}

_ErrorWithLocation::_ErrorWithLocation(BigStr* msg, syntax_asdl::loc_t* location) {
  this->msg = msg;
  if (location == nullptr) {
    this->location = loc::Missing;
  }
  else {
    this->location = location;
  }
}

bool _ErrorWithLocation::HasLocation() {
  return this->location->tag() != loc_e::Missing;
}

BigStr* _ErrorWithLocation::UserErrorString() {
  return this->msg;
}

Usage::Usage(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
}

Parse::Parse(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
}

FailGlob::FailGlob(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
}

RedirectEval::RedirectEval(BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
}

FatalRuntime::FatalRuntime(int exit_status, BigStr* msg, syntax_asdl::loc_t* location) : ::error::_ErrorWithLocation(msg, location) {
  this->exit_status = exit_status;
}

int FatalRuntime::ExitStatus() {
  return this->exit_status;
}

Strict::Strict(BigStr* msg, syntax_asdl::loc_t* location) : ::error::FatalRuntime(1, msg, location) {
}

ErrExit::ErrExit(int exit_status, BigStr* msg, syntax_asdl::loc_t* location, bool show_code) : ::error::FatalRuntime(exit_status, msg, location) {
  this->show_code = show_code;
}

Expr::Expr(BigStr* msg, syntax_asdl::loc_t* location) : ::error::FatalRuntime(3, msg, location) {
}

Structured::Structured(int status, BigStr* msg, syntax_asdl::loc_t* location, Dict<BigStr*, value_asdl::value_t*>* properties) : ::error::FatalRuntime(status, msg, location) {
  this->properties = properties;
}

value::Dict* Structured::ToDict() {
  Dict<BigStr*, value_asdl::value_t*>* d = nullptr;
  StackRoot _root0(&d);

  d = Alloc<Dict<BigStr*, value_asdl::value_t*>>();
  if (this->properties != nullptr) {
    d->update(this->properties);
  }
  d->set(str44, num::ToBig(this->ExitStatus()));
  d->set(str45, Alloc<value::Str>(this->msg));
  return Alloc<value::Dict>(d);
}

AssertionErr::AssertionErr(BigStr* msg, syntax_asdl::loc_t* location) : ::error::Expr(msg, location) {
}

TypeErrVerbose::TypeErrVerbose(BigStr* msg, syntax_asdl::loc_t* location) : ::error::Expr(msg, location) {
}

TypeErr::TypeErr(value_asdl::value_t* actual_val, BigStr* msg, syntax_asdl::loc_t* location) : ::error::TypeErrVerbose(StrFormat("%s, got %s", msg, _ValType(actual_val)), location) {
}

Runtime::Runtime(BigStr* msg) {
  this->msg = msg;
}

BigStr* Runtime::UserErrorString() {
  return this->msg;
}

Decode::Decode(BigStr* msg, BigStr* s, int start_pos, int end_pos, int line_num) {
  this->msg = msg;
  this->s = s;
  this->start_pos = start_pos;
  this->end_pos = end_pos;
  this->line_num = line_num;
}

BigStr* Decode::Message() {
  int start;
  int end;
  BigStr* part = nullptr;
  StackRoot _root0(&part);

  start = max(0, (this->start_pos - 4));
  end = min(len(this->s), (this->end_pos + 4));
  part = this->s->slice(start, end);
  return str_concat(this->msg, StrFormat(" (line %d, offset %d-%d: %r)", this->line_num, this->start_pos, this->end_pos, part));
}

BigStr* Decode::__str__() {
  return this->Message();
}

Encode::Encode(BigStr* msg) {
  this->msg = msg;
}

BigStr* Encode::Message() {
  return this->msg;
}

[[noreturn]] void e_usage(BigStr* msg, syntax_asdl::loc_t* location) {
  StackRoot _root0(&msg);
  StackRoot _root1(&location);

  throw Alloc<Usage>(msg, location);
}

[[noreturn]] void e_strict(BigStr* msg, syntax_asdl::loc_t* location) {
  StackRoot _root0(&msg);
  StackRoot _root1(&location);

  throw Alloc<Strict>(msg, location);
}

[[noreturn]] void p_die(BigStr* msg, syntax_asdl::loc_t* location) {
  StackRoot _root0(&msg);
  StackRoot _root1(&location);

  throw Alloc<Parse>(msg, location);
}

[[noreturn]] void e_die(BigStr* msg, syntax_asdl::loc_t* location) {
  StackRoot _root0(&msg);
  StackRoot _root1(&location);

  throw Alloc<FatalRuntime>(1, msg, location);
}

[[noreturn]] void e_die_status(int status, BigStr* msg, syntax_asdl::loc_t* location) {
  StackRoot _root0(&msg);
  StackRoot _root1(&location);

  throw Alloc<FatalRuntime>(status, msg, location);
}

}  // define namespace error

namespace num {  // define

using value_asdl::value;

value::Int* ToBig(int i) {
  return Alloc<value::Int>(mops::IntWiden(i));
}

mops::BigInt Exponent(mops::BigInt x, mops::BigInt y) {
  int y_int;
  mops::BigInt result;
  y_int = mops::BigTruncate(y);
  result = mops::BigInt(1);
  for (int i = 0; i < y_int; ++i) {
    result = mops::Mul(result, x);
  }
  return result;
}

}  // define namespace num

namespace j8 {  // define

using id_kind_asdl::Id;
using id_kind_asdl::Id_t;
using id_kind_asdl::Id_str;
using value_asdl::value;
using value_asdl::value_e;
using value_asdl::value_t;
using value_asdl::value_str;
using nil8_asdl::nvalue;
using nil8_asdl::nvalue_t;
namespace fmt = format;

BigStr* ValType(value_asdl::value_t* val) {
  StackRoot _root0(&val);

  return value_str(val->tag(), false);
}

int ValueId(value_asdl::value_t* val) {
  StackRoot _root0(&val);

  switch (val->tag()) {
    case value_e::Null: 
    case value_e::Bool: 
    case value_e::Int: 
    case value_e::Float: 
    case value_e::Str: {
      return -1;
    }
      break;
    default: {
      return HeapValueId(val);
    }
  }
}

BigStr* ValueIdString(value_asdl::value_t* val) {
  int heap_id;
  StackRoot _root0(&val);

  heap_id = ValueId(val);
  if (heap_id == -1) {
    return str48;
  }
  else {
    return StrFormat(" 0x%s", mylib::hex_lower(heap_id));
  }
}

BigStr* Utf8Encode(int code) {
  int num_cont_bytes;
  List<int>* bytes_ = nullptr;
  int b;
  List<BigStr*>* tmp = nullptr;
  StackRoot _root0(&bytes_);
  StackRoot _root1(&tmp);

  num_cont_bytes = 0;
  if (code <= 127) {
    return chr((code & 127));
  }
  else {
    if (code <= 2047) {
      num_cont_bytes = 1;
    }
    else {
      if (code <= 65535) {
        num_cont_bytes = 2;
      }
      else {
        num_cont_bytes = 3;
      }
    }
  }
  bytes_ = Alloc<List<int>>();
  for (int _ = 0; _ < num_cont_bytes; ++_) {
    bytes_->append((128 | (code & 63)));
    code >>= 6;
  }
  b = ((30 << (6 - num_cont_bytes)) | (code & (63 >> num_cont_bytes)));
  bytes_->append(b);
  bytes_->reverse();
  tmp = Alloc<List<BigStr*>>();
  for (ListIter<int> it(bytes_); !it.Done(); it.Next()) {
    int b = it.Value();
    tmp->append(chr((b & 255)));
  }
  return str50->join(tmp);
}
int SHOW_CYCLES = (1 << 1);
int SHOW_NON_DATA = (1 << 2);
int LOSSY_JSON = (1 << 3);
int INF_NAN_ARE_NULL = (1 << 4);

void _Print(value_asdl::value_t* val, mylib::BufWriter* buf, int indent, int options) {
  j8::InstancePrinter* p = nullptr;
  StackRoot _root0(&val);
  StackRoot _root1(&buf);
  StackRoot _root2(&p);

  p = Alloc<InstancePrinter>(buf, indent, options);
  p->Print(val);
}

void PrintMessage(value_asdl::value_t* val, mylib::BufWriter* buf, int indent) {
  StackRoot _root0(&val);
  StackRoot _root1(&buf);

  _Print(val, buf, indent);
}

void PrintJsonMessage(value_asdl::value_t* val, mylib::BufWriter* buf, int indent) {
  StackRoot _root0(&val);
  StackRoot _root1(&buf);

  _Print(val, buf, indent, (LOSSY_JSON | INF_NAN_ARE_NULL));
}

void PrintLine(value_asdl::value_t* val, mylib::Writer* f) {
  mylib::BufWriter* buf = nullptr;
  StackRoot _root0(&val);
  StackRoot _root1(&f);
  StackRoot _root2(&buf);

  buf = Alloc<mylib::BufWriter>();
  _Print(val, buf, -1, (SHOW_CYCLES | SHOW_NON_DATA));
  f->write(buf->getvalue());
  f->write(str51);
}

void EncodeString(BigStr* s, mylib::BufWriter* buf, bool unquoted_ok) {
  StackRoot _root0(&s);
  StackRoot _root1(&buf);

  if ((unquoted_ok and fastfunc::CanOmitQuotes(s))) {
    buf->write(s);
    return ;
  }
  _Print(Alloc<value::Str>(s), buf, -1);
}

BigStr* MaybeEncodeString(BigStr* s) {
  mylib::BufWriter* buf = nullptr;
  StackRoot _root0(&s);
  StackRoot _root1(&buf);

  buf = Alloc<mylib::BufWriter>();
  _Print(Alloc<value::Str>(s), buf, -1);
  return buf->getvalue();
}

BigStr* MaybeEncodeJsonString(BigStr* s) {
  mylib::BufWriter* buf = nullptr;
  StackRoot _root0(&s);
  StackRoot _root1(&buf);

  buf = Alloc<mylib::BufWriter>();
  _Print(Alloc<value::Str>(s), buf, -1, LOSSY_JSON);
  return buf->getvalue();
}
int UNSEEN = 0;
int EXPLORING = 1;
int FINISHED = 2;

InstancePrinter::InstancePrinter(mylib::BufWriter* buf, int indent, int options) {
  this->buf = buf;
  this->indent = indent;
  this->options = options;
  this->visited = Alloc<Dict<int, int>>();
}

void InstancePrinter::_ItemIndent(int level) {
  if (this->indent == -1) {
    return ;
  }
  this->buf->write_spaces(((level + 1) * this->indent));
}

void InstancePrinter::_BracketIndent(int level) {
  if (this->indent == -1) {
    return ;
  }
  this->buf->write_spaces((level * this->indent));
}

void InstancePrinter::_MaybeNewline() {
  if (this->indent == -1) {
    return ;
  }
  this->buf->write(str52);
}

void InstancePrinter::_MaybeSpace() {
  if (this->indent == -1) {
    return ;
  }
  this->buf->write(str53);
}

void InstancePrinter::_PrintList(value::List* val, int level) {
  int i;
  StackRoot _root0(&val);

  if (len(val->items) == 0) {
    this->buf->write(str54);
  }
  else {
    this->buf->write(str55);
    this->_MaybeNewline();
    i = 0;
    for (ListIter<value_asdl::value_t*> it(val->items); !it.Done(); it.Next(), ++i) {
      value_asdl::value_t* item = it.Value();
      StackRoot _for(&item    );
      if (i != 0) {
        this->buf->write(str56);
        this->_MaybeNewline();
      }
      this->_ItemIndent(level);
      this->Print(item, (level + 1));
    }
    this->_MaybeNewline();
    this->_BracketIndent(level);
    this->buf->write(str57);
  }
}

void InstancePrinter::_PrintDict(value::Dict* val, int level) {
  int i;
  StackRoot _root0(&val);

  if (len(val->d) == 0) {
    this->buf->write(str58);
  }
  else {
    this->buf->write(str59);
    this->_MaybeNewline();
    i = 0;
    for (DictIter<BigStr*, value_asdl::value_t*> it(val->d); !it.Done(); it.Next()) {
      BigStr* k = it.Key();
      value_asdl::value_t* v = it.Value();
      if (i != 0) {
        this->buf->write(str60);
        this->_MaybeNewline();
      }
      this->_ItemIndent(level);
      pyj8::WriteString(k, this->options, this->buf);
      this->buf->write(str61);
      this->_MaybeSpace();
      this->Print(v, (level + 1));
      i += 1;
    }
    this->_MaybeNewline();
    this->_BracketIndent(level);
    this->buf->write(str62);
  }
}

void InstancePrinter::_PrintBashPrefix(BigStr* type_str, int level) {
  StackRoot _root0(&type_str);

  this->buf->write(str63);
  this->_MaybeNewline();
  this->_ItemIndent(level);
  this->buf->write(str64);
  this->_MaybeSpace();
  this->buf->write(type_str);
  this->_MaybeNewline();
  this->_ItemIndent(level);
  this->buf->write(str65);
  this->_MaybeSpace();
}

void InstancePrinter::_PrintBashSuffix(int level) {
  this->_MaybeNewline();
  this->_BracketIndent(level);
  this->buf->write(str66);
}

void InstancePrinter::_PrintSparseArray(value::SparseArray* val, int level) {
  bool first;
  int i;
  StackRoot _root0(&val);

  this->_PrintBashPrefix(str67, level);
  if (len(val->d) == 0) {
    this->buf->write(str68);
  }
  else {
    this->buf->write(str69);
    this->_MaybeNewline();
    first = true;
    i = 0;
    for (DictIter<mops::BigInt, BigStr*> it(val->d); !it.Done(); it.Next()) {
      mops::BigInt k = it.Key();
      BigStr* v = it.Value();
      if (i != 0) {
        this->buf->write(str70);
        this->_MaybeNewline();
      }
      this->_ItemIndent((level + 1));
      pyj8::WriteString(mops::ToStr(k), this->options, this->buf);
      this->buf->write(str71);
      this->_MaybeSpace();
      pyj8::WriteString(v, this->options, this->buf);
      i += 1;
    }
    this->_MaybeNewline();
    this->_BracketIndent((level + 1));
    this->buf->write(str72);
  }
  this->_PrintBashSuffix(level);
}

void InstancePrinter::_PrintBashArray(value::BashArray* val, int level) {
  bool first;
  int i;
  StackRoot _root0(&val);

  this->_PrintBashPrefix(str73, level);
  if (len(val->strs) == 0) {
    this->buf->write(str74);
  }
  else {
    this->buf->write(str75);
    this->_MaybeNewline();
    first = true;
    i = 0;
    for (ListIter<BigStr*> it(val->strs); !it.Done(); it.Next(), ++i) {
      BigStr* s = it.Value();
      StackRoot _for(&s    );
      if (s == nullptr) {
        continue;
      }
      if (!first) {
        this->buf->write(str76);
        this->_MaybeNewline();
      }
      this->_ItemIndent((level + 1));
      pyj8::WriteString(str(i), this->options, this->buf);
      this->buf->write(str77);
      this->_MaybeSpace();
      pyj8::WriteString(s, this->options, this->buf);
      first = false;
    }
    this->_MaybeNewline();
    this->_BracketIndent((level + 1));
    this->buf->write(str78);
  }
  this->_PrintBashSuffix(level);
}

void InstancePrinter::_PrintBashAssoc(value::BashAssoc* val, int level) {
  int i;
  StackRoot _root0(&val);

  this->_PrintBashPrefix(str79, level);
  if (len(val->d) == 0) {
    this->buf->write(str80);
  }
  else {
    this->buf->write(str81);
    this->_MaybeNewline();
    i = 0;
    for (DictIter<BigStr*, BigStr*> it(val->d); !it.Done(); it.Next()) {
      BigStr* k2 = it.Key();
      BigStr* v2 = it.Value();
      if (i != 0) {
        this->buf->write(str82);
        this->_MaybeNewline();
      }
      this->_ItemIndent((level + 1));
      pyj8::WriteString(k2, this->options, this->buf);
      this->buf->write(str83);
      this->_MaybeSpace();
      pyj8::WriteString(v2, this->options, this->buf);
      i += 1;
    }
    this->_MaybeNewline();
    this->_BracketIndent((level + 1));
    this->buf->write(str84);
  }
  this->_PrintBashSuffix(level);
}

void InstancePrinter::Print(value_asdl::value_t* val, int level) {
  value_asdl::value_t* UP_val = nullptr;
  double fl;
  BigStr* s = nullptr;
  int heap_id;
  int node_state;
  BigStr* ysh_type = nullptr;
  BigStr* id_str = nullptr;
  StackRoot _root0(&val);
  StackRoot _root1(&UP_val);
  StackRoot _root2(&s);
  StackRoot _root3(&ysh_type);
  StackRoot _root4(&id_str);

  UP_val = val;
  switch (val->tag()) {
    case value_e::Null: {
      this->buf->write(str85);
    }
      break;
    case value_e::Bool: {
      value::Bool* val = static_cast<value::Bool*>(UP_val);
      this->buf->write(val->b ? str86 : str87);
    }
      break;
    case value_e::Int: {
      value::Int* val = static_cast<value::Int*>(UP_val);
      this->buf->write(mops::ToStr(val->i));
    }
      break;
    case value_e::Float: {
      value::Float* val = static_cast<value::Float*>(UP_val);
      fl = val->f;
      if (math::isinf(fl)) {
        if ((this->options & INF_NAN_ARE_NULL)) {
          s = str88;
        }
        else {
          s = str89;
          if (fl < 0) {
            s = str_concat(str90, s);
          }
        }
      }
      else {
        if (math::isnan(fl)) {
          if ((this->options & INF_NAN_ARE_NULL)) {
            s = str91;
          }
          else {
            s = str92;
          }
        }
        else {
          s = str(fl);
        }
      }
      this->buf->write(s);
    }
      break;
    case value_e::Str: {
      value::Str* val = static_cast<value::Str*>(UP_val);
      pyj8::WriteString(val->s, this->options, this->buf);
    }
      break;
    case value_e::List: {
      value::List* val = static_cast<value::List*>(UP_val);
      heap_id = HeapValueId(val);
      node_state = this->visited->get(heap_id, UNSEEN);
      if (node_state == FINISHED) {
        this->_PrintList(val, level);
        return ;
      }
      if (node_state == EXPLORING) {
        if ((this->options & SHOW_CYCLES)) {
          this->buf->write(StrFormat("[ -->%s ]", ValueIdString(val)));
          return ;
        }
        else {
          throw Alloc<error::Encode>(StrFormat("Can't encode List%s in object cycle", ValueIdString(val)));
        }
      }
      this->visited->set(heap_id, EXPLORING);
      this->_PrintList(val, level);
      this->visited->set(heap_id, FINISHED);
    }
      break;
    case value_e::Dict: {
      value::Dict* val = static_cast<value::Dict*>(UP_val);
      heap_id = HeapValueId(val);
      node_state = this->visited->get(heap_id, UNSEEN);
      if (node_state == FINISHED) {
        this->_PrintDict(val, level);
        return ;
      }
      if (node_state == EXPLORING) {
        if ((this->options & SHOW_CYCLES)) {
          this->buf->write(StrFormat("{ -->%s }", ValueIdString(val)));
          return ;
        }
        else {
          throw Alloc<error::Encode>(StrFormat("Can't encode Dict%s in object cycle", ValueIdString(val)));
        }
      }
      this->visited->set(heap_id, EXPLORING);
      this->_PrintDict(val, level);
      this->visited->set(heap_id, FINISHED);
    }
      break;
    case value_e::SparseArray: {
      value::SparseArray* val = static_cast<value::SparseArray*>(UP_val);
      this->_PrintSparseArray(val, level);
    }
      break;
    case value_e::BashArray: {
      value::BashArray* val = static_cast<value::BashArray*>(UP_val);
      this->_PrintBashArray(val, level);
    }
      break;
    case value_e::BashAssoc: {
      value::BashAssoc* val = static_cast<value::BashAssoc*>(UP_val);
      this->_PrintBashAssoc(val, level);
    }
      break;
    default: {
      ;  // pass
      if ((this->options & SHOW_NON_DATA)) {
        ysh_type = ValType(val);
        id_str = ValueIdString(val);
        this->buf->write(StrFormat("<%s%s>", ysh_type, id_str));
      }
      else {
        throw Alloc<error::Encode>(StrFormat("Can't serialize object of type %s", ValType(val)));
      }
    }
  }
}

PrettyPrinter::PrettyPrinter(int max_col) {
  this->max_col = max_col;
  this->ref_count = Alloc<Dict<int, int>>();
}

void PrettyPrinter::PrettyTree(value_asdl::value_t* val, format::ColorOutput* f) {
  StackRoot _root0(&val);
  StackRoot _root1(&f);

  ;  // pass
}

void PrettyPrinter::Print(value_asdl::value_t* val, mylib::BufWriter* buf) {
  format::ColorOutput* f = nullptr;
  StackRoot _root0(&val);
  StackRoot _root1(&buf);
  StackRoot _root2(&f);

  f = fmt::DetectConsoleOutput(mylib::Stdout());
  this->PrettyTree(val, f);
  ;  // pass
}

LexerDecoder::LexerDecoder(BigStr* s, bool is_j8, BigStr* lang_str) {
  this->s = s;
  this->is_j8 = is_j8;
  this->lang_str = lang_str;
  this->pos = 0;
  this->cur_line_num = 1;
  this->decoded = Alloc<mylib::BufWriter>();
}

error::Decode* LexerDecoder::_Error(BigStr* msg, int end_pos) {
  StackRoot _root0(&msg);

  return Alloc<error::Decode>(msg, this->s, this->pos, end_pos, this->cur_line_num);
}

Tuple3<int, int, BigStr*> LexerDecoder::Next() {
  int tok_id;
  int end_pos;
  Tuple2<int, int> tup0 = match::MatchJ8Token(this->s, this->pos);
  tok_id = tup0.at0();
  end_pos = tup0.at1();
  if (!this->is_j8) {
    if ((tok_id == Id::Left_BSingleQuote || tok_id == Id::Left_USingleQuote)) {
      throw this->_Error(str99, end_pos);
    }
    if (tok_id == Id::Ignored_Comment) {
      throw this->_Error(str100, end_pos);
    }
  }
  if ((tok_id == Id::Left_DoubleQuote || tok_id == Id::Left_BSingleQuote || tok_id == Id::Left_USingleQuote)) {
    return this->_DecodeString(tok_id, end_pos);
  }
  if (tok_id == Id::Left_JDoubleQuote) {
    if (this->is_j8) {
      return this->_DecodeString(tok_id, end_pos);
    }
    else {
      throw this->_Error(str101, end_pos);
    }
  }
  if (tok_id == Id::Ignored_Newline) {
    this->cur_line_num += 1;
  }
  this->pos = end_pos;
  return Tuple3<int, int, BigStr*>(tok_id, end_pos, nullptr);
}

Tuple3<int, int, BigStr*> LexerDecoder::NextForLines() {
  int tok_id;
  int end_pos;
  Tuple2<int, int> tup1 = match::MatchJ8LinesToken(this->s, this->pos);
  tok_id = tup1.at0();
  end_pos = tup1.at1();
  if ((tok_id == Id::Left_DoubleQuote || tok_id == Id::Left_JDoubleQuote || tok_id == Id::Left_BSingleQuote || tok_id == Id::Left_USingleQuote)) {
    return this->_DecodeString(tok_id, end_pos);
  }
  if ((tok_id == Id::Lit_Chars and !pyj8::PartIsUtf8(this->s, this->pos, end_pos))) {
    throw this->_Error(StrFormat("Invalid UTF-8 in %s string literal", this->lang_str), end_pos);
  }
  if (tok_id == Id::Char_AsciiControl) {
    throw this->_Error(str103, end_pos);
  }
  if (tok_id == Id::J8_Newline) {
    this->cur_line_num += 1;
  }
  this->pos = end_pos;
  return Tuple3<int, int, BigStr*>(tok_id, end_pos, nullptr);
}

Tuple3<int, int, BigStr*> LexerDecoder::_DecodeString(int left_id, int str_pos) {
  int tok_id;
  int str_end;
  BigStr* s = nullptr;
  BigStr* part = nullptr;
  BigStr* ch = nullptr;
  BigStr* h = nullptr;
  int i;
  BigStr* h1 = nullptr;
  BigStr* h2 = nullptr;
  int i1;
  int i2;
  int code_point;
  StackRoot _root0(&s);
  StackRoot _root1(&part);
  StackRoot _root2(&ch);
  StackRoot _root3(&h);
  StackRoot _root4(&h1);
  StackRoot _root5(&h2);

  while (true) {
    if ((left_id == Id::Left_DoubleQuote || left_id == Id::Left_JDoubleQuote)) {
      Tuple2<int, int> tup2 = match::MatchJsonStrToken(this->s, str_pos);
      tok_id = tup2.at0();
      str_end = tup2.at1();
    }
    else {
      Tuple2<int, int> tup3 = match::MatchJ8StrToken(this->s, str_pos);
      tok_id = tup3.at0();
      str_end = tup3.at1();
    }
    if (tok_id == Id::Eol_Tok) {
      throw this->_Error(StrFormat("Unexpected EOF while lexing %s string", this->lang_str), str_end);
    }
    if (tok_id == Id::Unknown_Backslash) {
      throw this->_Error(StrFormat("Bad backslash escape in %s string", this->lang_str), str_end);
    }
    if (tok_id == Id::Char_AsciiControl) {
      throw this->_Error(StrFormat("%s strings can't have unescaped ASCII control chars", this->lang_str), str_end);
    }
    if ((tok_id == Id::Right_SingleQuote || tok_id == Id::Right_DoubleQuote)) {
      this->pos = str_end;
      s = this->decoded->getvalue();
      this->decoded->clear();
      return Tuple3<int, int, BigStr*>(Id::J8_String, str_end, s);
    }
    if (tok_id == Id::Lit_Chars) {
      part = this->s->slice(str_pos, str_end);
      if (!pyj8::PartIsUtf8(this->s, str_pos, str_end)) {
        throw this->_Error(StrFormat("Invalid UTF-8 in %s string literal", this->lang_str), str_end);
      }
    }
    else {
      if (tok_id == Id::Char_OneChar) {
        ch = this->s->at((str_pos + 1));
        part = consts::LookupCharC(ch);
      }
      else {
        if (tok_id == Id::Char_UBraced) {
          h = this->s->slice((str_pos + 3), (str_end - 1));
          i = to_int(h, 16);
          if (i > 1114111) {
            throw this->_Error(str108, str_end);
          }
          if ((55296 <= i and i < 57344)) {
            throw this->_Error(StrFormat("\\u{%s} escape is illegal because it's in the surrogate range", h), str_end);
          }
          part = Utf8Encode(i);
        }
        else {
          if (tok_id == Id::Char_YHex) {
            h = this->s->slice((str_pos + 2), str_end);
            if (left_id != Id::Left_BSingleQuote) {
              throw this->_Error(StrFormat("\\y%s escapes not allowed in u'' strings", h), str_end);
            }
            i = to_int(h, 16);
            part = chr(i);
          }
          else {
            if (tok_id == Id::Char_SurrogatePair) {
              h1 = this->s->slice((str_pos + 2), (str_pos + 6));
              h2 = this->s->slice((str_pos + 8), (str_pos + 12));
              i1 = (to_int(h1, 16) - 55296);
              i2 = (to_int(h2, 16) - 56320);
              code_point = ((65536 + (i1 << 10)) + i2);
              part = Utf8Encode(code_point);
            }
            else {
              if (tok_id == Id::Char_Unicode4) {
                h = this->s->slice((str_pos + 2), str_end);
                i = to_int(h, 16);
                part = Utf8Encode(i);
              }
              else {
                assert(0);  // AssertionError
              }
            }
          }
        }
      }
    }
    this->decoded->write(part);
    str_pos = str_end;
  }
}

_Parser::_Parser(BigStr* s, bool is_j8) {
  this->s = s;
  this->is_j8 = is_j8;
  this->lang_str = is_j8 ? str111 : str112;
  this->lexer = Alloc<LexerDecoder>(s, is_j8, this->lang_str);
  this->tok_id = Id::Undefined_Tok;
  this->start_pos = 0;
  this->end_pos = 0;
  this->decoded = str113;
}

void _Parser::_Next() {
  while (true) {
    this->start_pos = this->end_pos;
    Tuple3<int, int, BigStr*> tup4 = this->lexer->Next();
    this->tok_id = tup4.at0();
    this->end_pos = tup4.at1();
    this->decoded = tup4.at2();
    if ((this->tok_id != Id::Ignored_Space && this->tok_id != Id::Ignored_Newline && this->tok_id != Id::Ignored_Comment)) {
      break;
    }
  }
}

void _Parser::_Eat(int tok_id) {
  if (this->tok_id != tok_id) {
    throw this->_ParseError(StrFormat("Expected %s, got %s", Id_str(tok_id), Id_str(this->tok_id)));
  }
  this->_Next();
}

void _Parser::_NextForLines() {
  this->start_pos = this->end_pos;
  Tuple3<int, int, BigStr*> tup5 = this->lexer->NextForLines();
  this->tok_id = tup5.at0();
  this->end_pos = tup5.at1();
  this->decoded = tup5.at2();
}

error::Decode* _Parser::_ParseError(BigStr* msg) {
  StackRoot _root0(&msg);

  return Alloc<error::Decode>(msg, this->s, this->start_pos, this->end_pos, this->lexer->cur_line_num);
}

Parser::Parser(BigStr* s, bool is_j8) : ::j8::_Parser(s, is_j8) {
}

Tuple2<BigStr*, value_asdl::value_t*> Parser::_ParsePair() {
  BigStr* k = nullptr;
  value_asdl::value_t* v = nullptr;
  StackRoot _root0(&k);
  StackRoot _root1(&v);

  k = this->decoded;
  this->_Eat(Id::J8_String);
  this->_Eat(Id::J8_Colon);
  v = this->_ParseValue();
  return Tuple2<BigStr*, value_asdl::value_t*>(k, v);
}

value_asdl::value_t* Parser::_ParseDict() {
  Dict<BigStr*, value_asdl::value_t*>* d = nullptr;
  BigStr* k = nullptr;
  value_asdl::value_t* v = nullptr;
  StackRoot _root0(&d);
  StackRoot _root1(&k);
  StackRoot _root2(&v);

  d = Alloc<Dict<BigStr*, value_asdl::value_t*>>();
  this->_Next();
  if (this->tok_id == Id::J8_RBrace) {
    this->_Next();
    return Alloc<value::Dict>(d);
  }
  Tuple2<BigStr*, value_asdl::value_t*> tup6 = this->_ParsePair();
  k = tup6.at0();
  v = tup6.at1();
  d->set(k, v);
  while (this->tok_id == Id::J8_Comma) {
    this->_Next();
    Tuple2<BigStr*, value_asdl::value_t*> tup7 = this->_ParsePair();
    k = tup7.at0();
    v = tup7.at1();
    d->set(k, v);
  }
  this->_Eat(Id::J8_RBrace);
  return Alloc<value::Dict>(d);
}

value_asdl::value_t* Parser::_ParseList() {
  List<value_asdl::value_t*>* items = nullptr;
  StackRoot _root0(&items);

  items = Alloc<List<value_asdl::value_t*>>();
  this->_Next();
  if (this->tok_id == Id::J8_RBracket) {
    this->_Next();
    return Alloc<value::List>(items);
  }
  items->append(this->_ParseValue());
  while (this->tok_id == Id::J8_Comma) {
    this->_Next();
    items->append(this->_ParseValue());
  }
  this->_Eat(Id::J8_RBracket);
  return Alloc<value::List>(items);
}

value_asdl::value_t* Parser::_ParseValue() {
  value::Bool* b = nullptr;
  BigStr* part = nullptr;
  mops::BigInt big;
  value::Str* str_val = nullptr;
  StackRoot _root0(&b);
  StackRoot _root1(&part);
  StackRoot _root2(&str_val);

  if (this->tok_id == Id::J8_LBrace) {
    return this->_ParseDict();
  }
  else {
    if (this->tok_id == Id::J8_LBracket) {
      return this->_ParseList();
    }
    else {
      if (this->tok_id == Id::J8_Null) {
        this->_Next();
        return value::Null;
      }
      else {
        if (this->tok_id == Id::J8_Bool) {
          b = Alloc<value::Bool>(str_equals(this->s->at(this->start_pos), str115));
          this->_Next();
          return b;
        }
        else {
          if (this->tok_id == Id::J8_Int) {
            part = this->s->slice(this->start_pos, this->end_pos);
            this->_Next();
            try {
              big = mops::FromStr(part);
            }
            catch (ValueError*) {
              throw this->_ParseError(str116);
            }
            return Alloc<value::Int>(big);
          }
          else {
            if (this->tok_id == Id::J8_Float) {
              part = this->s->slice(this->start_pos, this->end_pos);
              this->_Next();
              return Alloc<value::Float>(to_float(part));
            }
            else {
              if (this->tok_id == Id::J8_String) {
                str_val = Alloc<value::Str>(this->decoded);
                this->_Next();
                return str_val;
              }
              else {
                if (this->tok_id == Id::Eol_Tok) {
                  throw this->_ParseError(StrFormat("Unexpected EOF while parsing %s", this->lang_str));
                }
                else {
                  throw this->_ParseError(StrFormat("Invalid token while parsing %s: %s", this->lang_str, Id_str(this->tok_id)));
                }
              }
            }
          }
        }
      }
    }
  }
}

value_asdl::value_t* Parser::ParseValue() {
  value_asdl::value_t* obj = nullptr;
  int n;
  int extra;
  StackRoot _root0(&obj);

  this->_Next();
  obj = this->_ParseValue();
  n = len(this->s);
  if (this->start_pos != n) {
    extra = (n - this->start_pos);
    throw this->_ParseError(StrFormat("Got %d bytes of unexpected trailing input", extra));
  }
  return obj;
}

Nil8Parser::Nil8Parser(BigStr* s, bool is_j8) : ::j8::_Parser(s, is_j8) {
}

nil8_asdl::nvalue_t* Nil8Parser::_ParseRecord() {
  List<nil8_asdl::nvalue_t*>* items = nullptr;
  StackRoot _root0(&items);

  items = Alloc<List<nil8_asdl::nvalue_t*>>();
  this->_Next();
  if (this->tok_id == Id::J8_RParen) {
    this->_Next();
    return Alloc<nvalue::List>(items);
  }
  while (this->tok_id != Id::J8_RParen) {
    items->append(this->_ParseNil8());
  }
  this->_Eat(Id::J8_RParen);
  return Alloc<nvalue::List>(items);
}

nil8_asdl::nvalue_t* Nil8Parser::_ParseList8() {
  List<nil8_asdl::nvalue_t*>* items = nullptr;
  StackRoot _root0(&items);

  items = Alloc<List<nil8_asdl::nvalue_t*>>();
  this->_Next();
  if (this->tok_id == Id::J8_RBracket) {
    this->_Next();
    return Alloc<nvalue::List>(items);
  }
  while (this->tok_id != Id::J8_RBracket) {
    items->append(this->_ParseNil8());
  }
  this->_Eat(Id::J8_RBracket);
  return Alloc<nvalue::List>(items);
}

nil8_asdl::nvalue_t* Nil8Parser::_ParseNil8() {
  nil8_asdl::nvalue_t* obj = nullptr;
  nvalue::Bool* b = nullptr;
  BigStr* part = nullptr;
  nvalue::Str* str_val = nullptr;
  nvalue::Symbol* op = nullptr;
  nil8_asdl::nvalue_t* operand2 = nullptr;
  nil8_asdl::nvalue_t* infix = nullptr;
  StackRoot _root0(&obj);
  StackRoot _root1(&b);
  StackRoot _root2(&part);
  StackRoot _root3(&str_val);
  StackRoot _root4(&op);
  StackRoot _root5(&operand2);
  StackRoot _root6(&infix);

  if (this->tok_id == Id::J8_LParen) {
    obj = this->_ParseRecord();
  }
  else {
    if (this->tok_id == Id::J8_LBracket) {
      obj = this->_ParseList8();
    }
    else {
      if (this->tok_id == Id::J8_Null) {
        this->_Next();
        obj = nvalue::Null;
      }
      else {
        if (this->tok_id == Id::J8_Bool) {
          b = Alloc<nvalue::Bool>(str_equals(this->s->at(this->start_pos), str120));
          this->_Next();
          obj = b;
        }
        else {
          if (this->tok_id == Id::J8_Int) {
            part = this->s->slice(this->start_pos, this->end_pos);
            this->_Next();
            obj = Alloc<nvalue::Int>(to_int(part));
          }
          else {
            if (this->tok_id == Id::J8_Float) {
              part = this->s->slice(this->start_pos, this->end_pos);
              this->_Next();
              obj = Alloc<nvalue::Float>(to_float(part));
            }
            else {
              if (this->tok_id == Id::J8_String) {
                str_val = Alloc<nvalue::Str>(this->decoded);
                this->_Next();
                obj = str_val;
              }
              else {
                if ((this->tok_id == Id::J8_Identifier || this->tok_id == Id::J8_Operator || this->tok_id == Id::J8_Colon || this->tok_id == Id::J8_Comma)) {
                  part = this->s->slice(this->start_pos, this->end_pos);
                  this->_Next();
                  obj = Alloc<nvalue::Symbol>(part);
                }
                else {
                  if (this->tok_id == Id::Eol_Tok) {
                    throw this->_ParseError(StrFormat("Unexpected EOF while parsing %s", this->lang_str));
                  }
                  else {
                    throw this->_ParseError(StrFormat("Invalid token while parsing %s: %s", this->lang_str, Id_str(this->tok_id)));
                  }
                }
              }
            }
          }
        }
      }
    }
  }
  if ((this->tok_id == Id::J8_Operator || this->tok_id == Id::J8_Colon || this->tok_id == Id::J8_Comma)) {
    part = this->s->slice(this->start_pos, this->end_pos);
    op = Alloc<nvalue::Symbol>(part);
    this->_Next();
    operand2 = this->_ParseNil8();
    infix = Alloc<nvalue::List>(NewList<nil8_asdl::nvalue_t*>(std::initializer_list<nil8_asdl::nvalue_t*>{op, obj, operand2}));
    return infix;
  }
  return obj;
}

nil8_asdl::nvalue_t* Nil8Parser::ParseNil8() {
  nil8_asdl::nvalue_t* obj = nullptr;
  StackRoot _root0(&obj);

  this->_Next();
  obj = this->_ParseNil8();
  if (this->tok_id != Id::Eol_Tok) {
    throw this->_ParseError(str123);
  }
  return obj;
}

J8LinesParser::J8LinesParser(BigStr* s) : ::j8::_Parser(s, true) {
}

void J8LinesParser::_Show(BigStr* s) {
  StackRoot _root0(&s);

  mylib::print_stderr(StrFormat("%s tok_id %s %d-%d", s, Id_str(this->tok_id), this->start_pos, this->end_pos));
}

void J8LinesParser::_ParseLine(List<BigStr*>* out) {
  int string_start;
  int prev_id;
  int prev_start;
  int string_end;
  StackRoot _root0(&out);

  if (this->tok_id == Id::WS_Space) {
    this->_NextForLines();
  }
  if ((this->tok_id == Id::J8_Newline || this->tok_id == Id::Eol_Tok)) {
    this->_NextForLines();
    return ;
  }
  if (this->tok_id == Id::J8_String) {
    out->append(this->decoded);
    this->_NextForLines();
    if (this->tok_id == Id::WS_Space) {
      this->_NextForLines();
    }
    if ((this->tok_id != Id::J8_Newline && this->tok_id != Id::Eol_Tok)) {
      throw this->_ParseError(StrFormat("Unexpected text after J8 Line (%s)", Id_str(this->tok_id)));
    }
    this->_NextForLines();
    return ;
  }
  if (this->tok_id == Id::Lit_Chars) {
    string_start = this->start_pos;
    while (true) {
      prev_id = this->tok_id;
      prev_start = this->start_pos;
      this->_NextForLines();
      if ((this->tok_id == Id::J8_Newline || this->tok_id == Id::Eol_Tok)) {
        break;
      }
    }
    if (prev_id == Id::WS_Space) {
      string_end = prev_start;
    }
    else {
      string_end = this->start_pos;
    }
    out->append(this->s->slice(string_start, string_end));
    this->_NextForLines();
    return ;
  }
  assert(0);  // AssertionError
}

List<BigStr*>* J8LinesParser::Parse() {
  List<BigStr*>* lines = nullptr;
  StackRoot _root0(&lines);

  this->_NextForLines();
  lines = Alloc<List<BigStr*>>();
  while (this->tok_id != Id::Eol_Tok) {
    this->_ParseLine(lines);
  }
  if (this->tok_id != Id::Eol_Tok) {
    throw this->_ParseError(str126);
  }
  return lines;
}

List<BigStr*>* SplitJ8Lines(BigStr* s) {
  j8::J8LinesParser* p = nullptr;
  StackRoot _root0(&s);
  StackRoot _root1(&p);

  p = Alloc<J8LinesParser>(s);
  return p->Parse();
}

}  // define namespace j8

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 = str127;
BigStr* BOLD = str128;
BigStr* UNDERLINE = str129;
BigStr* REVERSE = str130;
BigStr* RED = str131;
BigStr* GREEN = str132;
BigStr* YELLOW = str133;
BigStr* BLUE = str134;
BigStr* MAGENTA = str135;
BigStr* CYAN = str136;
BigStr* WHITE = str137;

}  // define namespace ansi

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 mylib::BufWriter;

pretty_asdl::Measure* _EmptyMeasure() {
  return Alloc<Measure>(0, -1);
}

pretty_asdl::Measure* _FlattenMeasure(pretty_asdl::Measure* measure) {
  StackRoot _root0(&measure);

  return Alloc<Measure>(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<Measure>((m1->flat + m2->flat), m1->nonflat);
  }
  else {
    if (m2->nonflat != -1) {
      return Alloc<Measure>((m1->flat + m2->flat), (m1->flat + m2->nonflat));
    }
    else {
      return Alloc<Measure>((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<MeasuredDoc>(Alloc<doc::Text>(string), Alloc<Measure>(len(string), -1));
}

pretty_asdl::MeasuredDoc* _Break(BigStr* string) {
  StackRoot _root0(&string);

  return Alloc<MeasuredDoc>(Alloc<doc::Break>(string), Alloc<Measure>(len(string), 0));
}

pretty_asdl::MeasuredDoc* _Indent(int indent, pretty_asdl::MeasuredDoc* mdoc) {
  StackRoot _root0(&mdoc);

  return Alloc<MeasuredDoc>(Alloc<doc::Indent>(indent, mdoc), mdoc->measure);
}

pretty_asdl::MeasuredDoc* _Concat(List<pretty_asdl::MeasuredDoc*>* mdocs) {
  pretty_asdl::Measure* measure = nullptr;
  StackRoot _root0(&mdocs);
  StackRoot _root1(&measure);

  measure = _EmptyMeasure();
  for (ListIter<pretty_asdl::MeasuredDoc*> it(mdocs); !it.Done(); it.Next()) {
    pretty_asdl::MeasuredDoc* mdoc = it.Value();
    StackRoot _for(&mdoc  );
    measure = _ConcatMeasure(measure, mdoc->measure);
  }
  return Alloc<MeasuredDoc>(Alloc<doc::Concat>(mdocs), measure);
}

pretty_asdl::MeasuredDoc* _Group(pretty_asdl::MeasuredDoc* mdoc) {
  StackRoot _root0(&mdoc);

  return Alloc<MeasuredDoc>(Alloc<doc::Group>(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<MeasuredDoc>(Alloc<doc::IfFlat>(flat_mdoc, nonflat_mdoc), Alloc<Measure>(flat_mdoc->measure->flat, nonflat_mdoc->measure->nonflat));
}

pretty_asdl::MeasuredDoc* _Flat(pretty_asdl::MeasuredDoc* mdoc) {
  StackRoot _root0(&mdoc);

  return Alloc<MeasuredDoc>(Alloc<doc::Flat>(mdoc), _FlattenMeasure(mdoc->measure));
}

PrettyPrinter::PrettyPrinter(int max_width) {
  this->max_width = max_width;
}

bool PrettyPrinter::_Fits(int prefix_len, doc::Group* 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->mdoc->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<pretty_asdl::DocFragment*>* fragments = nullptr;
  pretty_asdl::DocFragment* frag = nullptr;
  doc::Text* text = nullptr;
  BigStr* break_str = nullptr;
  doc::Indent* indented = nullptr;
  doc::Concat* concat = nullptr;
  pretty_asdl::Measure* measure = nullptr;
  doc::Group* group = nullptr;
  bool flat;
  doc::IfFlat* if_flat = nullptr;
  pretty_asdl::MeasuredDoc* subdoc = nullptr;
  doc::Flat* flat_doc = nullptr;
  StackRoot _root0(&document);
  StackRoot _root1(&buf);
  StackRoot _root2(&fragments);
  StackRoot _root3(&frag);
  StackRoot _root4(&text);
  StackRoot _root5(&break_str);
  StackRoot _root6(&indented);
  StackRoot _root7(&concat);
  StackRoot _root8(&measure);
  StackRoot _root9(&group);
  StackRoot _root10(&if_flat);
  StackRoot _root11(&subdoc);
  StackRoot _root12(&flat_doc);

  prefix_len = 0;
  fragments = NewList<pretty_asdl::DocFragment*>(std::initializer_list<pretty_asdl::DocFragment*>{Alloc<DocFragment>(_Group(document), 0, false, _EmptyMeasure())});
  while (len(fragments) > 0) {
    frag = fragments->pop();
    switch (frag->mdoc->doc->tag()) {
      case doc_e::Text: {
        text = static_cast<doc::Text*>(frag->mdoc->doc);
        buf->write(text->string);
        prefix_len += frag->mdoc->measure->flat;
      }
        break;
      case doc_e::Break: {
        if (frag->is_flat) {
          break_str = static_cast<doc::Break*>(frag->mdoc->doc)->string;
          buf->write(break_str);
          prefix_len += frag->mdoc->measure->flat;
        }
        else {
          buf->write(str138);
          buf->write_spaces(frag->indent);
          prefix_len = frag->indent;
        }
      }
        break;
      case doc_e::Indent: {
        indented = static_cast<doc::Indent*>(frag->mdoc->doc);
        fragments->append(Alloc<DocFragment>(indented->mdoc, (frag->indent + indented->indent), frag->is_flat, frag->measure));
      }
        break;
      case doc_e::Concat: {
        concat = static_cast<doc::Concat*>(frag->mdoc->doc);
        measure = frag->measure;
        for (ReverseListIter<pretty_asdl::MeasuredDoc*> it(concat->mdocs); !it.Done(); it.Next()) {
          pretty_asdl::MeasuredDoc* mdoc = it.Value();
          StackRoot _for(&mdoc        );
          fragments->append(Alloc<DocFragment>(mdoc, frag->indent, frag->is_flat, measure));
          measure = _ConcatMeasure(mdoc->measure, measure);
        }
      }
        break;
      case doc_e::Group: {
        group = static_cast<doc::Group*>(frag->mdoc->doc);
        flat = this->_Fits(prefix_len, group, frag->measure);
        fragments->append(Alloc<DocFragment>(group->mdoc, frag->indent, flat, frag->measure));
      }
        break;
      case doc_e::IfFlat: {
        if_flat = static_cast<doc::IfFlat*>(frag->mdoc->doc);
        if (frag->is_flat) {
          subdoc = if_flat->flat_mdoc;
        }
        else {
          subdoc = if_flat->nonflat_mdoc;
        }
        fragments->append(Alloc<DocFragment>(subdoc, frag->indent, frag->is_flat, frag->measure));
      }
        break;
      case doc_e::Flat: {
        flat_doc = static_cast<doc::Flat*>(frag->mdoc->doc);
        fragments->append(Alloc<DocFragment>(flat_doc->mdoc, frag->indent, true, frag->measure));
      }
        break;
    }
  }
}

}  // define namespace pretty

namespace cgi {  // define


BigStr* escape(BigStr* s) {
  StackRoot _root0(&s);

  s = s->replace(str139, str140);
  s = s->replace(str141, str142);
  s = s->replace(str143, str144);
  return s;
}

}  // define namespace cgi

namespace gen_cpp {  // define

using yaks_asdl::Program;
using yaks_asdl::mod_def;
using yaks_asdl::mod_def_e;
using yaks_asdl::ktype;
using yaks_asdl::ktype_e;
using yaks_asdl::ktype_t;
using yaks_asdl::NameType;
using yaks_asdl::stmt;
using yaks_asdl::stmt_e;
using yaks_asdl::stmt_t;
using yaks_asdl::Int;
using yaks_asdl::kexpr_e;
using yaks_asdl::kexpr_t;
using yaks_asdl::Int;

void GenType(yaks_asdl::ktype_t* typ, mylib::Writer* f) {
  yaks_asdl::ktype_t* UP_typ = nullptr;
  StackRoot _root0(&typ);
  StackRoot _root1(&f);
  StackRoot _root2(&UP_typ);

  UP_typ = typ;
  switch (typ->tag()) {
    case ktype_e::Int: {
      f->write(str145);
    }
      break;
    case ktype_e::Str: {
      f->write(str146);
    }
      break;
    case ktype_e::List: {
      ktype::List* typ = static_cast<ktype::List*>(UP_typ);
      f->write(str147);
      GenType(typ->T, f);
      f->write(str148);
    }
      break;
    default: {
      assert(0);  // AssertionError
    }
  }
}

void GenParam(yaks_asdl::NameType* p, mylib::Writer* f) {
  StackRoot _root0(&p);
  StackRoot _root1(&f);

  GenType(p->typ, f);
  f->write(StrFormat(" %s", p->name));
}

void GenExpr(yaks_asdl::kexpr_t* expr, mylib::Writer* f) {
  yaks_asdl::kexpr_t* UP_expr = nullptr;
  StackRoot _root0(&expr);
  StackRoot _root1(&f);
  StackRoot _root2(&UP_expr);

  UP_expr = expr;
  switch (expr->tag()) {
    case kexpr_e::Int: {
      Int* expr = static_cast<Int*>(UP_expr);
      f->write(StrFormat("%d", expr->i));
    }
      break;
    default: {
      assert(0);  // AssertionError
    }
  }
}

void GenStatement(yaks_asdl::stmt_t* st, mylib::Writer* f) {
  yaks_asdl::stmt_t* UP_st = nullptr;
  StackRoot _root0(&st);
  StackRoot _root1(&f);
  StackRoot _root2(&UP_st);

  UP_st = st;
  switch (st->tag()) {
    case stmt_e::Return: {
      stmt::Return* st = static_cast<stmt::Return*>(UP_st);
      f->write(str151);
      GenExpr(st->e, f);
      f->write(str152);
    }
      break;
  }
}

void GenFunction(mod_def::Func* func, mylib::Writer* f) {
  int i;
  StackRoot _root0(&func);
  StackRoot _root1(&f);

  GenType(func->sig->return_type, f);
  f->write(StrFormat(" %s(", func->name));
  i = 0;
  for (ListIter<yaks_asdl::NameType*> it(func->sig->params); !it.Done(); it.Next(), ++i) {
    yaks_asdl::NameType* p = it.Value();
    StackRoot _for(&p  );
    if (i != 0) {
      f->write(str154);
    }
    GenParam(p, f);
  }
  f->write(str155);
  for (ListIter<yaks_asdl::stmt_t*> it(func->statements); !it.Done(); it.Next()) {
    yaks_asdl::stmt_t* st = it.Value();
    StackRoot _for(&st  );
    GenStatement(st, f);
  }
  f->write(str156);
}

void GenCpp(yaks_asdl::Program* prog, mylib::Writer* f) {
  yaks_asdl::mod_def_t* UP_d = nullptr;
  StackRoot _root0(&prog);
  StackRoot _root1(&f);
  StackRoot _root2(&UP_d);

  f->write(str157);
  for (ListIter<yaks_asdl::Module*> it(prog->modules); !it.Done(); it.Next()) {
    yaks_asdl::Module* module = it.Value();
    StackRoot _for(&module  );
    f->write(StrFormat("namespace %s {\n", module->name));
    for (ListIter<yaks_asdl::mod_def_t*> it(module->defs); !it.Done(); it.Next()) {
      yaks_asdl::mod_def_t* d = it.Value();
      StackRoot _for(&d    );
      UP_d = d;
      switch (d->tag()) {
        case mod_def_e::Func: {
          mod_def::Func* d = static_cast<mod_def::Func*>(UP_d);
          GenFunction(d, f);
        }
          break;
      }
    }
    f->write(StrFormat("}  // namespace %s\n", module->name));
  }
}

}  // define namespace gen_cpp

namespace transform {  // define

using nil8_asdl::nvalue;
using nil8_asdl::nvalue_e;
using nil8_asdl::nvalue_t;
using yaks_asdl::Module;
using yaks_asdl::Program;
using yaks_asdl::mod_def;
using yaks_asdl::mod_def_t;
using yaks_asdl::ktype;
using yaks_asdl::ktype_t;
using yaks_asdl::stmt;
using yaks_asdl::stmt_t;
using yaks_asdl::kexpr_t;
using yaks_asdl::Int;
using yaks_asdl::Token;
using yaks_asdl::Signature;
using yaks_asdl::NameType;

BigStr* MustBeSymbol(nil8_asdl::nvalue_t* nval) {
  StackRoot _root0(&nval);

  if (nval->tag() != nvalue_e::Symbol) {
    assert(0);  // AssertionError
  }
  return static_cast<nvalue::Symbol*>(nval)->s;
}

List<nil8_asdl::nvalue_t*>* MustBeList(nil8_asdl::nvalue_t* nval) {
  StackRoot _root0(&nval);

  if (nval->tag() != nvalue_e::List) {
    assert(0);  // AssertionError
  }
  return static_cast<nvalue::List*>(nval)->items;
}

yaks_asdl::kexpr_t* TransformExpr(nil8_asdl::nvalue_t* nval) {
  nil8_asdl::nvalue_t* UP_nval = nullptr;
  yaks_asdl::Token* loc = nullptr;
  StackRoot _root0(&nval);
  StackRoot _root1(&UP_nval);
  StackRoot _root2(&loc);

  UP_nval = nval;
  switch (nval->tag()) {
    case nvalue_e::Int: {
      nvalue::Int* nval = static_cast<nvalue::Int*>(UP_nval);
      loc = Alloc<Token>(str162, str163, 0, 3);
      return Alloc<Int>(nval->i, loc);
    }
      break;
    default: {
      assert(0);  // AssertionError
    }
  }
}

yaks_asdl::ktype_t* TransformType(nil8_asdl::nvalue_t* nval) {
  nil8_asdl::nvalue_t* UP_nval = nullptr;
  BigStr* first = nullptr;
  StackRoot _root0(&nval);
  StackRoot _root1(&UP_nval);
  StackRoot _root2(&first);

  UP_nval = nval;
  switch (nval->tag()) {
    case nvalue_e::Symbol: {
      nvalue::Symbol* nval = static_cast<nvalue::Symbol*>(UP_nval);
      if (str_equals(nval->s, str164)) {
        return ktype::Bool;
      }
      else {
        if (str_equals(nval->s, str165)) {
          return ktype::Int;
        }
        else {
          if (str_equals(nval->s, str166)) {
            return ktype::Str;
          }
          else {
            assert(0);  // AssertionError
          }
        }
      }
    }
      break;
    case nvalue_e::List: {
      nvalue::List* nval = static_cast<nvalue::List*>(UP_nval);
      first = MustBeSymbol(nval->items->at(0));
      if (str_equals(first, str167)) {
        return Alloc<ktype::List>(TransformType(nval->items->at(1)));
      }
      else {
        if (str_equals(first, str168)) {
          return Alloc<ktype::Dict>(TransformType(nval->items->at(1)), TransformType(nval->items->at(2)));
        }
        else {
          assert(0);  // AssertionError
        }
      }
    }
      break;
    default: {
      assert(0);  // AssertionError
    }
  }
}

yaks_asdl::NameType* TransformParam(List<nil8_asdl::nvalue_t*>* param_n) {
  BigStr* name = nullptr;
  yaks_asdl::ktype_t* typ = nullptr;
  StackRoot _root0(&param_n);
  StackRoot _root1(&name);
  StackRoot _root2(&typ);

  if (len(param_n) != 2) {
    assert(0);  // AssertionError
  }
  name = MustBeSymbol(param_n->at(0));
  typ = TransformType(param_n->at(1));
  return Alloc<NameType>(name, typ);
}

List<yaks_asdl::NameType*>* TransformParams(List<nil8_asdl::nvalue_t*>* params_n) {
  List<yaks_asdl::NameType*>* result = nullptr;
  List<nil8_asdl::nvalue_t*>* param_n = nullptr;
  StackRoot _root0(&params_n);
  StackRoot _root1(&result);
  StackRoot _root2(&param_n);

  result = Alloc<List<yaks_asdl::NameType*>>();
  for (ListIter<nil8_asdl::nvalue_t*> it(params_n); !it.Done(); it.Next()) {
    nil8_asdl::nvalue_t* p = it.Value();
    StackRoot _for(&p  );
    param_n = MustBeList(p);
    result->append(TransformParam(param_n));
  }
  return result;
}

yaks_asdl::Signature* TransformSignature(nil8_asdl::nvalue_t* nval) {
  List<nil8_asdl::nvalue_t*>* sig_n = nullptr;
  BigStr* first = nullptr;
  List<nil8_asdl::nvalue_t*>* params_n = nullptr;
  StackRoot _root0(&nval);
  StackRoot _root1(&sig_n);
  StackRoot _root2(&first);
  StackRoot _root3(&params_n);

  sig_n = MustBeList(nval);
  if (len(sig_n) != 3) {
    assert(0);  // AssertionError
  }
  first = MustBeSymbol(sig_n->at(0));
  if (!(str_equals(first, str170))) {
    assert(0);  // AssertionError
  }
  params_n = MustBeList(sig_n->at(1));
  return Alloc<Signature>(TransformParams(params_n), TransformType(sig_n->at(2)));
}

mod_def::Func* TransformFunc(List<nil8_asdl::nvalue_t*>* func_n) {
  BigStr* func_name = nullptr;
  List<yaks_asdl::stmt_t*>* out_stmts = nullptr;
  yaks_asdl::Signature* sig = nullptr;
  mod_def::Func* func = nullptr;
  List<nil8_asdl::nvalue_t*>* stmts = nullptr;
  List<nil8_asdl::nvalue_t*>* stmt_n = nullptr;
  BigStr* first = nullptr;
  yaks_asdl::kexpr_t* expr = nullptr;
  StackRoot _root0(&func_n);
  StackRoot _root1(&func_name);
  StackRoot _root2(&out_stmts);
  StackRoot _root3(&sig);
  StackRoot _root4(&func);
  StackRoot _root5(&stmts);
  StackRoot _root6(&stmt_n);
  StackRoot _root7(&first);
  StackRoot _root8(&expr);

  func_name = MustBeSymbol(func_n->at(1));
  out_stmts = Alloc<List<yaks_asdl::stmt_t*>>();
  sig = TransformSignature(func_n->at(2));
  func = Alloc<mod_def::Func>(func_name, sig, out_stmts);
  stmts = func_n->slice(3);
  for (ListIter<nil8_asdl::nvalue_t*> it(stmts); !it.Done(); it.Next()) {
    nil8_asdl::nvalue_t* st = it.Value();
    StackRoot _for(&st  );
    stmt_n = MustBeList(st);
    if (len(stmt_n) == 0) {
      assert(0);  // AssertionError
    }
    first = MustBeSymbol(stmt_n->at(0));
    if (str_equals(first, str173)) {
      ;  // pass
    }
    else {
      if (str_equals(first, str174)) {
        ;  // pass
      }
      else {
        if (str_equals(first, str175)) {
          ;  // pass
        }
        else {
          if (str_equals(first, str176)) {
            expr = TransformExpr(stmt_n->at(1));
            out_stmts->append(Alloc<stmt::Return>(expr));
          }
          else {
            if (str_equals(first, str177)) {
              ;  // pass
            }
            else {
              if (str_equals(first, str178)) {
                ;  // pass
              }
              else {
                assert(0);  // AssertionError
              }
            }
          }
        }
      }
    }
  }
  return func;
}

yaks_asdl::Module* TransformModule(List<nil8_asdl::nvalue_t*>* mod_n) {
  BigStr* mod_name = nullptr;
  List<yaks_asdl::mod_def_t*>* out_defs = nullptr;
  yaks_asdl::Module* module = nullptr;
  List<nil8_asdl::nvalue_t*>* defs = nullptr;
  List<nil8_asdl::nvalue_t*>* def_n = nullptr;
  BigStr* first = nullptr;
  StackRoot _root0(&mod_n);
  StackRoot _root1(&mod_name);
  StackRoot _root2(&out_defs);
  StackRoot _root3(&module);
  StackRoot _root4(&defs);
  StackRoot _root5(&def_n);
  StackRoot _root6(&first);

  if (len(mod_n) < 2) {
    assert(0);  // AssertionError
  }
  mod_name = MustBeSymbol(mod_n->at(1));
  out_defs = Alloc<List<yaks_asdl::mod_def_t*>>();
  module = Alloc<Module>(mod_name, out_defs);
  defs = mod_n->slice(2);
  for (ListIter<nil8_asdl::nvalue_t*> it(defs); !it.Done(); it.Next()) {
    nil8_asdl::nvalue_t* d = it.Value();
    StackRoot _for(&d  );
    def_n = MustBeList(d);
    if (len(def_n) == 0) {
      assert(0);  // AssertionError
    }
    first = MustBeSymbol(def_n->at(0));
    if (str_equals(first, str182)) {
      ;  // pass
    }
    else {
      if (str_equals(first, str183)) {
        out_defs->append(TransformFunc(def_n));
      }
      else {
        if (str_equals(first, str184)) {
          ;  // pass
        }
        else {
          assert(0);  // AssertionError
        }
      }
    }
  }
  return module;
}

yaks_asdl::Program* Transform(nil8_asdl::nvalue_t* nval) {
  List<nil8_asdl::nvalue_t*>* mod_n = nullptr;
  yaks_asdl::Module* module = nullptr;
  yaks_asdl::Program* prog = nullptr;
  StackRoot _root0(&nval);
  StackRoot _root1(&mod_n);
  StackRoot _root2(&module);
  StackRoot _root3(&prog);

  mod_n = MustBeList(nval);
  module = TransformModule(mod_n);
  prog = Alloc<Program>(str186, NewList<yaks_asdl::Module*>(std::initializer_list<yaks_asdl::Module*>{module}));
  return prog;
}

}  // define namespace transform

namespace yaks_main {  // define

namespace fmt = format;

int main(List<BigStr*>* argv) {
  mylib::Writer* stderr_ = nullptr;
  BigStr* action = nullptr;
  BigStr* path = nullptr;
  List<BigStr*>* lines = nullptr;
  mylib::LineReader* f = nullptr;
  BigStr* line = nullptr;
  BigStr* contents = nullptr;
  j8::Nil8Parser* p = nullptr;
  nil8_asdl::nvalue_t* nval = nullptr;
  format::ColorOutput* pretty_f = nullptr;
  yaks_asdl::Program* prog = nullptr;
  yaks_asdl::Module* m = nullptr;
  StackRoot _root0(&argv);
  StackRoot _root1(&stderr_);
  StackRoot _root2(&action);
  StackRoot _root3(&path);
  StackRoot _root4(&lines);
  StackRoot _root5(&f);
  StackRoot _root6(&line);
  StackRoot _root7(&contents);
  StackRoot _root8(&p);
  StackRoot _root9(&nval);
  StackRoot _root10(&pretty_f);
  StackRoot _root11(&prog);
  StackRoot _root12(&m);

  stderr_ = mylib::Stderr();
  try {
    action = argv->at(1);
  }
  catch (IndexError*) {
    throw Alloc<RuntimeError>(str187);
  }
  if (str_equals(action, str188)) {
    path = argv->at(2);
    lines = Alloc<List<BigStr*>>();
    f = mylib::open(path);
    while (true) {
      line = f->readline();
      if (len(line) == 0) {
        break;
      }
      lines->append(line);
    }
    contents = str189->join(lines);
    p = Alloc<j8::Nil8Parser>(contents, true);
    try {
      nval = p->ParseNil8();
    }
    catch (error::Decode* e) {
      return 1;
    }
    pretty_f = fmt::DetectConsoleOutput(stderr_);
    fmt::PrintTree(nval->PrettyTree(), pretty_f);
    stderr_->write(str190);
    prog = transform::Transform(nval);
    fmt::PrintTree(prog->PrettyTree(), pretty_f);
    stderr_->write(str191);
    gen_cpp::GenCpp(prog, mylib::Stdout());
  }
  else {
    if (str_equals(action, str192)) {
      path = argv->at(2);
      m = Alloc<yaks_asdl::Module>(str193, Alloc<List<yaks_asdl::mod_def_t*>>());
      pretty_f = fmt::DetectConsoleOutput(stderr_);
      fmt::PrintTree(m->PrettyTree(), pretty_f);
      stderr_->write(str194);
    }
    else {
      throw Alloc<RuntimeError>(StrFormat("Invalid action %r", action));
    }
  }
  return 0;
}

}  // define namespace yaks_main

int main(int argc, char **argv) {
  mylib::InitCppOnly();  // Initializes gHeap

  auto* args = Alloc<List<BigStr*>>();
  for (int i = 0; i < argc; ++i) {
    args->append(StrFromC(argv[i]));
  }

  int status = yaks_main::main(args);

  gHeap.ProcessExit();

  return status;
}