// _gen/frontend/syntax.asdl.h is generated by asdl_main.py

#ifndef SYNTAX_ASDL
#define SYNTAX_ASDL

#include <cstdint>

#include "mycpp/runtime.h"
#include "asdl/cpp_runtime.h"
#include "_gen/frontend/id_kind.asdl.h"
using id_kind_asdl::Id_t;

namespace value_asdl { class value_t; class LiteralBlock; }

namespace syntax_asdl {

// use struct instead of namespace so 'using' works consistently
#define ASDL_NAMES struct

class BoolParamBox;
class IntParamBox;
class parse_result_t;
class source_t;
class SourceLine;
class Token;
class CompoundWord;
class loc_t;
class debug_frame_t;
class bracket_op_t;
class suffix_op_t;
class BracedVarSub;
class DoubleQuoted;
class SingleQuoted;
class SimpleVarSub;
class CommandSub;
class ShArrayLiteral;
class ArgList;
class AssocPair;
class word_part_t;
class rhs_word_t;
class word_t;
class sh_lhs_t;
class arith_expr_t;
class bool_expr_t;
class redir_loc_t;
class redir_param_t;
class Redir;
class AssignPair;
class EnvPair;
class condition_t;
class CaseArm;
class case_arg_t;
class EggexFlag;
class Eggex;
class pat_t;
class IfArm;
class for_iter_t;
class BraceGroup;
class Param;
class RestParam;
class ParamGroup;
class proc_sig_t;
class Proc;
class Func;
class ParsedAssignment;
class command_t;
class glob_part_t;
class printf_part_t;
class TypeExpr;
class NameType;
class Comprehension;
class NamedArg;
class Subscript;
class Attribute;
class y_lhs_t;
class place_op_t;
class expr_t;
class PosixClass;
class PerlClass;
class CharCode;
class CharRange;
class class_literal_term_t;
class char_class_term_t;
class re_repeat_t;
class re_t;

ASDL_NAMES parse_result_e {
  enum no_name {
  EmptyLine = 1,
  Eof = 2,
  Node = 3,
  };
};

BigStr* parse_result_str(int tag, bool dot = true);

class parse_result_t {
 protected:
  parse_result_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(parse_result_t)
};

class parse_result__EmptyLine : public parse_result_t {
 public:
  parse_result__EmptyLine() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(parse_result_e::EmptyLine), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(parse_result__EmptyLine)
};

class parse_result__Eof : public parse_result_t {
 public:
  parse_result__Eof() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(parse_result_e::Eof), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(parse_result__Eof)
};

class parse_result__Node : public parse_result_t {
 public:
  parse_result__Node(command_t* cmd)
      : cmd(cmd) {
  }

  static parse_result__Node* CreateNull(bool alloc_lists = false) { 
    return Alloc<parse_result__Node>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(parse_result_e::Node), 1);
  }

  command_t* cmd;

  DISALLOW_COPY_AND_ASSIGN(parse_result__Node)
};

extern GcGlobal<parse_result__EmptyLine> gparse_result__EmptyLine;
extern GcGlobal<parse_result__Eof> gparse_result__Eof;
ASDL_NAMES parse_result {
  static parse_result__EmptyLine* EmptyLine;
  static parse_result__Eof* Eof;
  typedef parse_result__Node Node;
};

ASDL_NAMES source_e {
  enum no_name {
  Interactive = 1,
  Headless = 2,
  Unused = 3,
  CFlag = 4,
  Stdin = 5,
  MainFile = 6,
  OtherFile = 7,
  Dynamic = 8,
  Variable = 9,
  VarRef = 10,
  Alias = 11,
  Reparsed = 12,
  Synthetic = 13,
  };
};

BigStr* source_str(int tag, bool dot = true);

class source_t {
 protected:
  source_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(source_t)
};

class source__Interactive : public source_t {
 public:
  source__Interactive() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Interactive),
                                0);
  }


  DISALLOW_COPY_AND_ASSIGN(source__Interactive)
};

class source__Headless : public source_t {
 public:
  source__Headless() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Headless), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(source__Headless)
};

class source__Unused : public source_t {
 public:
  source__Unused(BigStr* comment)
      : comment(comment) {
  }

  static source__Unused* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Unused>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Unused), 1);
  }

  BigStr* comment;

  DISALLOW_COPY_AND_ASSIGN(source__Unused)
};

class source__CFlag : public source_t {
 public:
  source__CFlag() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::CFlag), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(source__CFlag)
};

class source__Stdin : public source_t {
 public:
  source__Stdin(BigStr* comment)
      : comment(comment) {
  }

  static source__Stdin* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Stdin>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Stdin), 1);
  }

  BigStr* comment;

  DISALLOW_COPY_AND_ASSIGN(source__Stdin)
};

class source__MainFile : public source_t {
 public:
  source__MainFile(BigStr* path)
      : path(path) {
  }

  static source__MainFile* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__MainFile>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::MainFile), 1);
  }

  BigStr* path;

  DISALLOW_COPY_AND_ASSIGN(source__MainFile)
};

class source__OtherFile : public source_t {
 public:
  source__OtherFile(BigStr* path, loc_t* location)
      : path(path),
        location(location) {
  }

  static source__OtherFile* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__OtherFile>(kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::OtherFile), 2);
  }

  BigStr* path;
  loc_t* location;

  DISALLOW_COPY_AND_ASSIGN(source__OtherFile)
};

class source__Dynamic : public source_t {
 public:
  source__Dynamic(BigStr* what, loc_t* location)
      : what(what),
        location(location) {
  }

  static source__Dynamic* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Dynamic>(kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Dynamic), 2);
  }

  BigStr* what;
  loc_t* location;

  DISALLOW_COPY_AND_ASSIGN(source__Dynamic)
};

class source__Variable : public source_t {
 public:
  source__Variable(BigStr* var_name, loc_t* location)
      : var_name(var_name),
        location(location) {
  }

  static source__Variable* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Variable>(kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Variable), 2);
  }

  BigStr* var_name;
  loc_t* location;

  DISALLOW_COPY_AND_ASSIGN(source__Variable)
};

class source__VarRef : public source_t {
 public:
  source__VarRef(Token* orig_tok)
      : orig_tok(orig_tok) {
  }

  static source__VarRef* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__VarRef>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::VarRef), 1);
  }

  Token* orig_tok;

  DISALLOW_COPY_AND_ASSIGN(source__VarRef)
};

class source__Alias : public source_t {
 public:
  source__Alias(BigStr* argv0, loc_t* argv0_loc)
      : argv0(argv0),
        argv0_loc(argv0_loc) {
  }

  static source__Alias* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Alias>(kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Alias), 2);
  }

  BigStr* argv0;
  loc_t* argv0_loc;

  DISALLOW_COPY_AND_ASSIGN(source__Alias)
};

class source__Reparsed : public source_t {
 public:
  source__Reparsed(BigStr* what, Token* left_token, Token* right_token)
      : what(what),
        left_token(left_token),
        right_token(right_token) {
  }

  static source__Reparsed* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Reparsed>(kEmptyString, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Reparsed), 3);
  }

  BigStr* what;
  Token* left_token;
  Token* right_token;

  DISALLOW_COPY_AND_ASSIGN(source__Reparsed)
};

class source__Synthetic : public source_t {
 public:
  source__Synthetic(BigStr* s)
      : s(s) {
  }

  static source__Synthetic* CreateNull(bool alloc_lists = false) { 
    return Alloc<source__Synthetic>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(source_e::Synthetic), 1);
  }

  BigStr* s;

  DISALLOW_COPY_AND_ASSIGN(source__Synthetic)
};

extern GcGlobal<source__Interactive> gsource__Interactive;
extern GcGlobal<source__Headless> gsource__Headless;
extern GcGlobal<source__CFlag> gsource__CFlag;
ASDL_NAMES source {
  static source__Interactive* Interactive;
  static source__Headless* Headless;
  typedef source__Unused Unused;
  static source__CFlag* CFlag;
  typedef source__Stdin Stdin;
  typedef source__MainFile MainFile;
  typedef source__OtherFile OtherFile;
  typedef source__Dynamic Dynamic;
  typedef source__Variable Variable;
  typedef source__VarRef VarRef;
  typedef source__Alias Alias;
  typedef source__Reparsed Reparsed;
  typedef source__Synthetic Synthetic;
};

ASDL_NAMES loc_e {
  enum no_name {
  Missing = 1,
  Token = 67,
  ArgWord = 68,
  WordPart = 4,
  Word = 5,
  Arith = 6,
  Command = 7,
  TokenTooLong = 8,
  };
};

BigStr* loc_str(int tag, bool dot = true);

class loc_t {
 protected:
  loc_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(loc_t)
};

class loc__Missing : public loc_t {
 public:
  loc__Missing() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::Missing), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(loc__Missing)
};

class loc__WordPart : public loc_t {
 public:
  loc__WordPart(word_part_t* p)
      : p(p) {
  }

  static loc__WordPart* CreateNull(bool alloc_lists = false) { 
    return Alloc<loc__WordPart>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::WordPart), 1);
  }

  word_part_t* p;

  DISALLOW_COPY_AND_ASSIGN(loc__WordPart)
};

class loc__Word : public loc_t {
 public:
  loc__Word(word_t* w)
      : w(w) {
  }

  static loc__Word* CreateNull(bool alloc_lists = false) { 
    return Alloc<loc__Word>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::Word), 1);
  }

  word_t* w;

  DISALLOW_COPY_AND_ASSIGN(loc__Word)
};

class loc__Arith : public loc_t {
 public:
  loc__Arith(arith_expr_t* a)
      : a(a) {
  }

  static loc__Arith* CreateNull(bool alloc_lists = false) { 
    return Alloc<loc__Arith>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::Arith), 1);
  }

  arith_expr_t* a;

  DISALLOW_COPY_AND_ASSIGN(loc__Arith)
};

class loc__Command : public loc_t {
 public:
  loc__Command(command_t* c)
      : c(c) {
  }

  static loc__Command* CreateNull(bool alloc_lists = false) { 
    return Alloc<loc__Command>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::Command), 1);
  }

  command_t* c;

  DISALLOW_COPY_AND_ASSIGN(loc__Command)
};

class loc__TokenTooLong : public loc_t {
 public:
  loc__TokenTooLong(SourceLine* line, Id_t id, int length, int col)
      : line(line),
        id(id),
        length(length),
        col(col) {
  }

  static loc__TokenTooLong* CreateNull(bool alloc_lists = false) { 
    return Alloc<loc__TokenTooLong>(nullptr, -1, -1, -1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(loc_e::TokenTooLong), 1);
  }

  SourceLine* line;
  Id_t id;
  int length;
  int col;

  DISALLOW_COPY_AND_ASSIGN(loc__TokenTooLong)
};

extern GcGlobal<loc__Missing> gloc__Missing;
ASDL_NAMES loc {
  static loc__Missing* Missing;
  typedef loc__WordPart WordPart;
  typedef loc__Word Word;
  typedef loc__Arith Arith;
  typedef loc__Command Command;
  typedef loc__TokenTooLong TokenTooLong;
};

ASDL_NAMES debug_frame_e {
  enum no_name {
  Main = 1,
  Source = 2,
  Call = 3,
  };
};

BigStr* debug_frame_str(int tag, bool dot = true);

class debug_frame_t {
 protected:
  debug_frame_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(debug_frame_t)
};

class debug_frame__Main : public debug_frame_t {
 public:
  debug_frame__Main(BigStr* dollar0)
      : dollar0(dollar0) {
  }

  static debug_frame__Main* CreateNull(bool alloc_lists = false) { 
    return Alloc<debug_frame__Main>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(debug_frame_e::Main), 1);
  }

  BigStr* dollar0;

  DISALLOW_COPY_AND_ASSIGN(debug_frame__Main)
};

class debug_frame__Source : public debug_frame_t {
 public:
  debug_frame__Source(Token* call_tok, BigStr* source_name)
      : call_tok(call_tok),
        source_name(source_name) {
  }

  static debug_frame__Source* CreateNull(bool alloc_lists = false) { 
    return Alloc<debug_frame__Source>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(debug_frame_e::Source),
                                2);
  }

  Token* call_tok;
  BigStr* source_name;

  DISALLOW_COPY_AND_ASSIGN(debug_frame__Source)
};

class debug_frame__Call : public debug_frame_t {
 public:
  debug_frame__Call(Token* call_tok, Token* def_tok, BigStr* func_name)
      : call_tok(call_tok),
        def_tok(def_tok),
        func_name(func_name) {
  }

  static debug_frame__Call* CreateNull(bool alloc_lists = false) { 
    return Alloc<debug_frame__Call>(nullptr, nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(debug_frame_e::Call), 3);
  }

  Token* call_tok;
  Token* def_tok;
  BigStr* func_name;

  DISALLOW_COPY_AND_ASSIGN(debug_frame__Call)
};

ASDL_NAMES debug_frame {
  typedef debug_frame__Main Main;
  typedef debug_frame__Source Source;
  typedef debug_frame__Call Call;
};

ASDL_NAMES bracket_op_e {
  enum no_name {
  WholeArray = 1,
  ArrayIndex = 2,
  };
};

BigStr* bracket_op_str(int tag, bool dot = true);

class bracket_op_t {
 protected:
  bracket_op_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(bracket_op_t)
};

class bracket_op__WholeArray : public bracket_op_t {
 public:
  bracket_op__WholeArray(Id_t op_id)
      : op_id(op_id) {
  }

  static bracket_op__WholeArray* CreateNull(bool alloc_lists = false) { 
    return Alloc<bracket_op__WholeArray>(-1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(bracket_op_e::WholeArray), 0);
  }

  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(bracket_op__WholeArray)
};

class bracket_op__ArrayIndex : public bracket_op_t {
 public:
  bracket_op__ArrayIndex(arith_expr_t* expr)
      : expr(expr) {
  }

  static bracket_op__ArrayIndex* CreateNull(bool alloc_lists = false) { 
    return Alloc<bracket_op__ArrayIndex>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(bracket_op_e::ArrayIndex), 1);
  }

  arith_expr_t* expr;

  DISALLOW_COPY_AND_ASSIGN(bracket_op__ArrayIndex)
};

ASDL_NAMES bracket_op {
  typedef bracket_op__WholeArray WholeArray;
  typedef bracket_op__ArrayIndex ArrayIndex;
};

ASDL_NAMES suffix_op_e {
  enum no_name {
  Nullary = 67,
  Unary = 2,
  Static = 3,
  PatSub = 4,
  Slice = 5,
  };
};

BigStr* suffix_op_str(int tag, bool dot = true);

class suffix_op_t {
 protected:
  suffix_op_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(suffix_op_t)
};

class suffix_op__Unary : public suffix_op_t {
 public:
  suffix_op__Unary(Token* op, rhs_word_t* arg_word)
      : op(op),
        arg_word(arg_word) {
  }

  static suffix_op__Unary* CreateNull(bool alloc_lists = false) { 
    return Alloc<suffix_op__Unary>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(suffix_op_e::Unary), 2);
  }

  Token* op;
  rhs_word_t* arg_word;

  DISALLOW_COPY_AND_ASSIGN(suffix_op__Unary)
};

class suffix_op__Static : public suffix_op_t {
 public:
  suffix_op__Static(Token* tok, BigStr* arg)
      : tok(tok),
        arg(arg) {
  }

  static suffix_op__Static* CreateNull(bool alloc_lists = false) { 
    return Alloc<suffix_op__Static>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(suffix_op_e::Static), 2);
  }

  Token* tok;
  BigStr* arg;

  DISALLOW_COPY_AND_ASSIGN(suffix_op__Static)
};

class suffix_op__PatSub : public suffix_op_t {
 public:
  suffix_op__PatSub(CompoundWord* pat, rhs_word_t* replace, Id_t replace_mode,
                    Token* slash_tok)
      : pat(pat),
        replace(replace),
        slash_tok(slash_tok),
        replace_mode(replace_mode) {
  }

  static suffix_op__PatSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<suffix_op__PatSub>(nullptr, nullptr, -1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(suffix_op_e::PatSub), 3);
  }

  CompoundWord* pat;
  rhs_word_t* replace;
  Token* slash_tok;
  Id_t replace_mode;

  DISALLOW_COPY_AND_ASSIGN(suffix_op__PatSub)
};

class suffix_op__Slice : public suffix_op_t {
 public:
  suffix_op__Slice(arith_expr_t* begin, arith_expr_t* length)
      : begin(begin),
        length(length) {
  }

  static suffix_op__Slice* CreateNull(bool alloc_lists = false) { 
    return Alloc<suffix_op__Slice>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(suffix_op_e::Slice), 2);
  }

  arith_expr_t* begin;
  arith_expr_t* length;

  DISALLOW_COPY_AND_ASSIGN(suffix_op__Slice)
};

ASDL_NAMES suffix_op {
  typedef suffix_op__Unary Unary;
  typedef suffix_op__Static Static;
  typedef suffix_op__PatSub PatSub;
  typedef suffix_op__Slice Slice;
};

ASDL_NAMES word_part_e {
  enum no_name {
  ShArrayLiteral = 74,
  BashAssocLiteral = 2,
  Literal = 67,
  EscapedLiteral = 4,
  SingleQuoted = 71,
  DoubleQuoted = 70,
  SimpleVarSub = 72,
  BracedVarSub = 69,
  ZshVarSub = 9,
  CommandSub = 73,
  TildeSub = 11,
  ArithSub = 12,
  BracedTuple = 13,
  BracedRange = 14,
  ExtGlob = 15,
  BashRegexGroup = 16,
  Splice = 17,
  ExprSub = 18,
  };
};

BigStr* word_part_str(int tag, bool dot = true);

class word_part_t {
 protected:
  word_part_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(word_part_t)
};

class word_part__BashAssocLiteral : public word_part_t {
 public:
  word_part__BashAssocLiteral(Token* left, List<AssocPair*>* pairs, Token*
                              right)
      : left(left),
        pairs(pairs),
        right(right) {
  }

  static word_part__BashAssocLiteral* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__BashAssocLiteral>(nullptr, alloc_lists ?
                                              Alloc<List<AssocPair*>>() :
                                              nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::BashAssocLiteral), 3);
  }

  Token* left;
  List<AssocPair*>* pairs;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__BashAssocLiteral)
};

class word_part__EscapedLiteral : public word_part_t {
 public:
  word_part__EscapedLiteral(Token* token, BigStr* ch)
      : token(token),
        ch(ch) {
  }

  static word_part__EscapedLiteral* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__EscapedLiteral>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::EscapedLiteral), 2);
  }

  Token* token;
  BigStr* ch;

  DISALLOW_COPY_AND_ASSIGN(word_part__EscapedLiteral)
};

class word_part__ZshVarSub : public word_part_t {
 public:
  word_part__ZshVarSub(Token* left, CompoundWord* ignored, Token* right)
      : left(left),
        ignored(ignored),
        right(right) {
  }

  static word_part__ZshVarSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__ZshVarSub>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::ZshVarSub),
                                3);
  }

  Token* left;
  CompoundWord* ignored;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__ZshVarSub)
};

class word_part__TildeSub : public word_part_t {
 public:
  word_part__TildeSub(Token* left, Token* name, BigStr* user_name)
      : left(left),
        name(name),
        user_name(user_name) {
  }

  static word_part__TildeSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__TildeSub>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::TildeSub),
                                3);
  }

  Token* left;
  Token* name;
  BigStr* user_name;

  DISALLOW_COPY_AND_ASSIGN(word_part__TildeSub)
};

class word_part__ArithSub : public word_part_t {
 public:
  word_part__ArithSub(Token* left, arith_expr_t* anode, Token* right)
      : left(left),
        anode(anode),
        right(right) {
  }

  static word_part__ArithSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__ArithSub>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::ArithSub),
                                3);
  }

  Token* left;
  arith_expr_t* anode;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__ArithSub)
};

class word_part__BracedTuple : public word_part_t {
 public:
  word_part__BracedTuple(List<CompoundWord*>* words)
      : words(words) {
  }

  static word_part__BracedTuple* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__BracedTuple>(alloc_lists ?
                                         Alloc<List<CompoundWord*>>() :
                                         nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::BracedTuple), 1);
  }

  List<CompoundWord*>* words;

  DISALLOW_COPY_AND_ASSIGN(word_part__BracedTuple)
};

class word_part__BracedRange : public word_part_t {
 public:
  word_part__BracedRange(Token* blame_tok, Id_t kind, BigStr* start, BigStr*
                         end, int step)
      : blame_tok(blame_tok),
        start(start),
        end(end),
        kind(kind),
        step(step) {
  }

  static word_part__BracedRange* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__BracedRange>(nullptr, -1, kEmptyString,
                                         kEmptyString, -1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::BracedRange), 3);
  }

  Token* blame_tok;
  BigStr* start;
  BigStr* end;
  Id_t kind;
  int step;

  DISALLOW_COPY_AND_ASSIGN(word_part__BracedRange)
};

class word_part__ExtGlob : public word_part_t {
 public:
  word_part__ExtGlob(Token* op, List<CompoundWord*>* arms, Token* right)
      : op(op),
        arms(arms),
        right(right) {
  }

  static word_part__ExtGlob* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__ExtGlob>(nullptr, alloc_lists ?
                                     Alloc<List<CompoundWord*>>() : nullptr,
                                     nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::ExtGlob), 3);
  }

  Token* op;
  List<CompoundWord*>* arms;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__ExtGlob)
};

class word_part__BashRegexGroup : public word_part_t {
 public:
  word_part__BashRegexGroup(Token* left, CompoundWord* child, Token* right)
      : left(left),
        child(child),
        right(right) {
  }

  static word_part__BashRegexGroup* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__BashRegexGroup>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::BashRegexGroup), 3);
  }

  Token* left;
  CompoundWord* child;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__BashRegexGroup)
};

class word_part__Splice : public word_part_t {
 public:
  word_part__Splice(Token* blame_tok, BigStr* var_name)
      : blame_tok(blame_tok),
        var_name(var_name) {
  }

  static word_part__Splice* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__Splice>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::Splice), 2);
  }

  Token* blame_tok;
  BigStr* var_name;

  DISALLOW_COPY_AND_ASSIGN(word_part__Splice)
};

class word_part__ExprSub : public word_part_t {
 public:
  word_part__ExprSub(Token* left, expr_t* child, Token* right)
      : left(left),
        child(child),
        right(right) {
  }

  static word_part__ExprSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<word_part__ExprSub>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_part_e::ExprSub), 3);
  }

  Token* left;
  expr_t* child;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(word_part__ExprSub)
};

ASDL_NAMES word_part {
  typedef word_part__BashAssocLiteral BashAssocLiteral;
  typedef word_part__EscapedLiteral EscapedLiteral;
  typedef word_part__ZshVarSub ZshVarSub;
  typedef word_part__TildeSub TildeSub;
  typedef word_part__ArithSub ArithSub;
  typedef word_part__BracedTuple BracedTuple;
  typedef word_part__BracedRange BracedRange;
  typedef word_part__ExtGlob ExtGlob;
  typedef word_part__BashRegexGroup BashRegexGroup;
  typedef word_part__Splice Splice;
  typedef word_part__ExprSub ExprSub;
};

ASDL_NAMES rhs_word_e {
  enum no_name {
  Empty = 1,
  Compound = 68,
  };
};

BigStr* rhs_word_str(int tag, bool dot = true);

class rhs_word_t {
 protected:
  rhs_word_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(rhs_word_t)
};

class rhs_word__Empty : public rhs_word_t {
 public:
  rhs_word__Empty() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(rhs_word_e::Empty), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(rhs_word__Empty)
};

extern GcGlobal<rhs_word__Empty> grhs_word__Empty;
ASDL_NAMES rhs_word {
  static rhs_word__Empty* Empty;
};

ASDL_NAMES word_e {
  enum no_name {
  Operator = 67,
  Compound = 68,
  BracedTree = 3,
  String = 4,
  };
};

BigStr* word_str(int tag, bool dot = true);

class word_t {
 protected:
  word_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(word_t)
};

class word__BracedTree : public word_t {
 public:
  word__BracedTree(List<word_part_t*>* parts)
      : parts(parts) {
  }

  static word__BracedTree* CreateNull(bool alloc_lists = false) { 
    return Alloc<word__BracedTree>(alloc_lists ? Alloc<List<word_part_t*>>() :
                                   nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_e::BracedTree), 1);
  }

  List<word_part_t*>* parts;

  DISALLOW_COPY_AND_ASSIGN(word__BracedTree)
};

class word__String : public word_t {
 public:
  word__String(Id_t id, BigStr* s, CompoundWord* blame_loc)
      : s(s),
        blame_loc(blame_loc),
        id(id) {
  }

  static word__String* CreateNull(bool alloc_lists = false) { 
    return Alloc<word__String>(-1, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(word_e::String), 2);
  }

  BigStr* s;
  CompoundWord* blame_loc;
  Id_t id;

  DISALLOW_COPY_AND_ASSIGN(word__String)
};

ASDL_NAMES word {
  typedef word__BracedTree BracedTree;
  typedef word__String String;
};

ASDL_NAMES sh_lhs_e {
  enum no_name {
  Name = 1,
  IndexedName = 2,
  UnparsedIndex = 3,
  };
};

BigStr* sh_lhs_str(int tag, bool dot = true);

class sh_lhs_t {
 protected:
  sh_lhs_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(sh_lhs_t)
};

class sh_lhs__Name : public sh_lhs_t {
 public:
  sh_lhs__Name(Token* left, BigStr* name)
      : left(left),
        name(name) {
  }

  static sh_lhs__Name* CreateNull(bool alloc_lists = false) { 
    return Alloc<sh_lhs__Name>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(sh_lhs_e::Name), 2);
  }

  Token* left;
  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(sh_lhs__Name)
};

class sh_lhs__IndexedName : public sh_lhs_t {
 public:
  sh_lhs__IndexedName(Token* left, BigStr* name, arith_expr_t* index)
      : left(left),
        name(name),
        index(index) {
  }

  static sh_lhs__IndexedName* CreateNull(bool alloc_lists = false) { 
    return Alloc<sh_lhs__IndexedName>(nullptr, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(sh_lhs_e::IndexedName),
                                3);
  }

  Token* left;
  BigStr* name;
  arith_expr_t* index;

  DISALLOW_COPY_AND_ASSIGN(sh_lhs__IndexedName)
};

class sh_lhs__UnparsedIndex : public sh_lhs_t {
 public:
  sh_lhs__UnparsedIndex(Token* left, BigStr* name, BigStr* index)
      : left(left),
        name(name),
        index(index) {
  }

  static sh_lhs__UnparsedIndex* CreateNull(bool alloc_lists = false) { 
    return Alloc<sh_lhs__UnparsedIndex>(nullptr, kEmptyString, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(sh_lhs_e::UnparsedIndex),
                                3);
  }

  Token* left;
  BigStr* name;
  BigStr* index;

  DISALLOW_COPY_AND_ASSIGN(sh_lhs__UnparsedIndex)
};

ASDL_NAMES sh_lhs {
  typedef sh_lhs__Name Name;
  typedef sh_lhs__IndexedName IndexedName;
  typedef sh_lhs__UnparsedIndex UnparsedIndex;
};

ASDL_NAMES arith_expr_e {
  enum no_name {
  EmptyZero = 1,
  EmptyOne = 2,
  VarSub = 67,
  Word = 68,
  UnaryAssign = 5,
  BinaryAssign = 6,
  Unary = 7,
  Binary = 8,
  TernaryOp = 9,
  };
};

BigStr* arith_expr_str(int tag, bool dot = true);

class arith_expr_t {
 protected:
  arith_expr_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(arith_expr_t)
};

class arith_expr__EmptyZero : public arith_expr_t {
 public:
  arith_expr__EmptyZero() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::EmptyZero),
                                0);
  }


  DISALLOW_COPY_AND_ASSIGN(arith_expr__EmptyZero)
};

class arith_expr__EmptyOne : public arith_expr_t {
 public:
  arith_expr__EmptyOne() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::EmptyOne),
                                0);
  }


  DISALLOW_COPY_AND_ASSIGN(arith_expr__EmptyOne)
};

class arith_expr__UnaryAssign : public arith_expr_t {
 public:
  arith_expr__UnaryAssign(Id_t op_id, arith_expr_t* child)
      : child(child),
        op_id(op_id) {
  }

  static arith_expr__UnaryAssign* CreateNull(bool alloc_lists = false) { 
    return Alloc<arith_expr__UnaryAssign>(-1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::UnaryAssign), 1);
  }

  arith_expr_t* child;
  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(arith_expr__UnaryAssign)
};

class arith_expr__BinaryAssign : public arith_expr_t {
 public:
  arith_expr__BinaryAssign(Id_t op_id, arith_expr_t* left, arith_expr_t* right)
      : left(left),
        right(right),
        op_id(op_id) {
  }

  static arith_expr__BinaryAssign* CreateNull(bool alloc_lists = false) { 
    return Alloc<arith_expr__BinaryAssign>(-1, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::BinaryAssign), 2);
  }

  arith_expr_t* left;
  arith_expr_t* right;
  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(arith_expr__BinaryAssign)
};

class arith_expr__Unary : public arith_expr_t {
 public:
  arith_expr__Unary(Id_t op_id, arith_expr_t* child)
      : child(child),
        op_id(op_id) {
  }

  static arith_expr__Unary* CreateNull(bool alloc_lists = false) { 
    return Alloc<arith_expr__Unary>(-1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::Unary), 1);
  }

  arith_expr_t* child;
  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(arith_expr__Unary)
};

class arith_expr__Binary : public arith_expr_t {
 public:
  arith_expr__Binary(Token* op, arith_expr_t* left, arith_expr_t* right)
      : op(op),
        left(left),
        right(right) {
  }

  static arith_expr__Binary* CreateNull(bool alloc_lists = false) { 
    return Alloc<arith_expr__Binary>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::Binary), 3);
  }

  Token* op;
  arith_expr_t* left;
  arith_expr_t* right;

  DISALLOW_COPY_AND_ASSIGN(arith_expr__Binary)
};

class arith_expr__TernaryOp : public arith_expr_t {
 public:
  arith_expr__TernaryOp(arith_expr_t* cond, arith_expr_t* true_expr,
                        arith_expr_t* false_expr)
      : cond(cond),
        true_expr(true_expr),
        false_expr(false_expr) {
  }

  static arith_expr__TernaryOp* CreateNull(bool alloc_lists = false) { 
    return Alloc<arith_expr__TernaryOp>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(arith_expr_e::TernaryOp),
                                3);
  }

  arith_expr_t* cond;
  arith_expr_t* true_expr;
  arith_expr_t* false_expr;

  DISALLOW_COPY_AND_ASSIGN(arith_expr__TernaryOp)
};

extern GcGlobal<arith_expr__EmptyZero> garith_expr__EmptyZero;
extern GcGlobal<arith_expr__EmptyOne> garith_expr__EmptyOne;
ASDL_NAMES arith_expr {
  static arith_expr__EmptyZero* EmptyZero;
  static arith_expr__EmptyOne* EmptyOne;
  typedef arith_expr__UnaryAssign UnaryAssign;
  typedef arith_expr__BinaryAssign BinaryAssign;
  typedef arith_expr__Unary Unary;
  typedef arith_expr__Binary Binary;
  typedef arith_expr__TernaryOp TernaryOp;
};

ASDL_NAMES bool_expr_e {
  enum no_name {
  WordTest = 1,
  Binary = 2,
  Unary = 3,
  LogicalNot = 4,
  LogicalAnd = 5,
  LogicalOr = 6,
  };
};

BigStr* bool_expr_str(int tag, bool dot = true);

class bool_expr_t {
 protected:
  bool_expr_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(bool_expr_t)
};

class bool_expr__WordTest : public bool_expr_t {
 public:
  bool_expr__WordTest(word_t* w)
      : w(w) {
  }

  static bool_expr__WordTest* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__WordTest>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::WordTest),
                                1);
  }

  word_t* w;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__WordTest)
};

class bool_expr__Binary : public bool_expr_t {
 public:
  bool_expr__Binary(Id_t op_id, word_t* left, word_t* right)
      : left(left),
        right(right),
        op_id(op_id) {
  }

  static bool_expr__Binary* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__Binary>(-1, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::Binary), 2);
  }

  word_t* left;
  word_t* right;
  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__Binary)
};

class bool_expr__Unary : public bool_expr_t {
 public:
  bool_expr__Unary(Id_t op_id, word_t* child)
      : child(child),
        op_id(op_id) {
  }

  static bool_expr__Unary* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__Unary>(-1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::Unary), 1);
  }

  word_t* child;
  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__Unary)
};

class bool_expr__LogicalNot : public bool_expr_t {
 public:
  bool_expr__LogicalNot(bool_expr_t* child)
      : child(child) {
  }

  static bool_expr__LogicalNot* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__LogicalNot>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::LogicalNot),
                                1);
  }

  bool_expr_t* child;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__LogicalNot)
};

class bool_expr__LogicalAnd : public bool_expr_t {
 public:
  bool_expr__LogicalAnd(bool_expr_t* left, bool_expr_t* right)
      : left(left),
        right(right) {
  }

  static bool_expr__LogicalAnd* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__LogicalAnd>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::LogicalAnd),
                                2);
  }

  bool_expr_t* left;
  bool_expr_t* right;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__LogicalAnd)
};

class bool_expr__LogicalOr : public bool_expr_t {
 public:
  bool_expr__LogicalOr(bool_expr_t* left, bool_expr_t* right)
      : left(left),
        right(right) {
  }

  static bool_expr__LogicalOr* CreateNull(bool alloc_lists = false) { 
    return Alloc<bool_expr__LogicalOr>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(bool_expr_e::LogicalOr),
                                2);
  }

  bool_expr_t* left;
  bool_expr_t* right;

  DISALLOW_COPY_AND_ASSIGN(bool_expr__LogicalOr)
};

ASDL_NAMES bool_expr {
  typedef bool_expr__WordTest WordTest;
  typedef bool_expr__Binary Binary;
  typedef bool_expr__Unary Unary;
  typedef bool_expr__LogicalNot LogicalNot;
  typedef bool_expr__LogicalAnd LogicalAnd;
  typedef bool_expr__LogicalOr LogicalOr;
};

ASDL_NAMES redir_loc_e {
  enum no_name {
  Fd = 1,
  VarName = 2,
  };
};

BigStr* redir_loc_str(int tag, bool dot = true);

class redir_loc_t {
 protected:
  redir_loc_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(redir_loc_t)
};

class redir_loc__Fd : public redir_loc_t {
 public:
  redir_loc__Fd(int fd)
      : fd(fd) {
  }

  static redir_loc__Fd* CreateNull(bool alloc_lists = false) { 
    return Alloc<redir_loc__Fd>(-1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(redir_loc_e::Fd), 0);
  }

  int fd;

  DISALLOW_COPY_AND_ASSIGN(redir_loc__Fd)
};

class redir_loc__VarName : public redir_loc_t {
 public:
  redir_loc__VarName(BigStr* name)
      : name(name) {
  }

  static redir_loc__VarName* CreateNull(bool alloc_lists = false) { 
    return Alloc<redir_loc__VarName>(kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(redir_loc_e::VarName), 1);
  }

  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(redir_loc__VarName)
};

ASDL_NAMES redir_loc {
  typedef redir_loc__Fd Fd;
  typedef redir_loc__VarName VarName;
};

ASDL_NAMES redir_param_e {
  enum no_name {
  Word = 68,
  HereWord = 2,
  HereDoc = 3,
  };
};

BigStr* redir_param_str(int tag, bool dot = true);

class redir_param_t {
 protected:
  redir_param_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(redir_param_t)
};

class redir_param__HereWord : public redir_param_t {
 public:
  redir_param__HereWord(CompoundWord* w, bool is_multiline)
      : w(w),
        is_multiline(is_multiline) {
  }

  static redir_param__HereWord* CreateNull(bool alloc_lists = false) { 
    return Alloc<redir_param__HereWord>(nullptr, false);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(redir_param_e::HereWord),
                                1);
  }

  CompoundWord* w;
  bool is_multiline;

  DISALLOW_COPY_AND_ASSIGN(redir_param__HereWord)
};

class redir_param__HereDoc : public redir_param_t {
 public:
  redir_param__HereDoc(word_t* here_begin, Token* here_end_tok,
                       List<word_part_t*>* stdin_parts)
      : here_begin(here_begin),
        here_end_tok(here_end_tok),
        stdin_parts(stdin_parts) {
  }

  static redir_param__HereDoc* CreateNull(bool alloc_lists = false) { 
    return Alloc<redir_param__HereDoc>(nullptr, nullptr, alloc_lists ?
                                       Alloc<List<word_part_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(redir_param_e::HereDoc),
                                3);
  }

  word_t* here_begin;
  Token* here_end_tok;
  List<word_part_t*>* stdin_parts;

  DISALLOW_COPY_AND_ASSIGN(redir_param__HereDoc)
};

ASDL_NAMES redir_param {
  typedef redir_param__HereWord HereWord;
  typedef redir_param__HereDoc HereDoc;
};

enum class assign_op_e {
  Equal = 1,
  PlusEqual = 2,
};
typedef assign_op_e assign_op_t;

BigStr* assign_op_str(assign_op_e tag, bool dot = true);

ASDL_NAMES condition_e {
  enum no_name {
  Shell = 80,
  YshExpr = 2,
  };
};

BigStr* condition_str(int tag, bool dot = true);

class condition_t {
 protected:
  condition_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(condition_t)
};

class condition__YshExpr : public condition_t {
 public:
  condition__YshExpr(expr_t* e)
      : e(e) {
  }

  static condition__YshExpr* CreateNull(bool alloc_lists = false) { 
    return Alloc<condition__YshExpr>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(condition_e::YshExpr), 1);
  }

  expr_t* e;

  DISALLOW_COPY_AND_ASSIGN(condition__YshExpr)
};

ASDL_NAMES condition {
  typedef condition__YshExpr YshExpr;
};

ASDL_NAMES case_arg_e {
  enum no_name {
  Word = 1,
  YshExpr = 2,
  };
};

BigStr* case_arg_str(int tag, bool dot = true);

class case_arg_t {
 protected:
  case_arg_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(case_arg_t)
};

class case_arg__Word : public case_arg_t {
 public:
  case_arg__Word(word_t* w)
      : w(w) {
  }

  static case_arg__Word* CreateNull(bool alloc_lists = false) { 
    return Alloc<case_arg__Word>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(case_arg_e::Word), 1);
  }

  word_t* w;

  DISALLOW_COPY_AND_ASSIGN(case_arg__Word)
};

class case_arg__YshExpr : public case_arg_t {
 public:
  case_arg__YshExpr(expr_t* e)
      : e(e) {
  }

  static case_arg__YshExpr* CreateNull(bool alloc_lists = false) { 
    return Alloc<case_arg__YshExpr>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(case_arg_e::YshExpr), 1);
  }

  expr_t* e;

  DISALLOW_COPY_AND_ASSIGN(case_arg__YshExpr)
};

ASDL_NAMES case_arg {
  typedef case_arg__Word Word;
  typedef case_arg__YshExpr YshExpr;
};

ASDL_NAMES pat_e {
  enum no_name {
  Else = 1,
  Words = 2,
  YshExprs = 3,
  Eggex = 83,
  };
};

BigStr* pat_str(int tag, bool dot = true);

class pat_t {
 protected:
  pat_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(pat_t)
};

class pat__Else : public pat_t {
 public:
  pat__Else() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(pat_e::Else), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(pat__Else)
};

class pat__Words : public pat_t {
 public:
  pat__Words(List<word_t*>* words)
      : words(words) {
  }

  static pat__Words* CreateNull(bool alloc_lists = false) { 
    return Alloc<pat__Words>(alloc_lists ? Alloc<List<word_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(pat_e::Words), 1);
  }

  List<word_t*>* words;

  DISALLOW_COPY_AND_ASSIGN(pat__Words)
};

class pat__YshExprs : public pat_t {
 public:
  pat__YshExprs(List<expr_t*>* exprs)
      : exprs(exprs) {
  }

  static pat__YshExprs* CreateNull(bool alloc_lists = false) { 
    return Alloc<pat__YshExprs>(alloc_lists ? Alloc<List<expr_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(pat_e::YshExprs), 1);
  }

  List<expr_t*>* exprs;

  DISALLOW_COPY_AND_ASSIGN(pat__YshExprs)
};

extern GcGlobal<pat__Else> gpat__Else;
ASDL_NAMES pat {
  static pat__Else* Else;
  typedef pat__Words Words;
  typedef pat__YshExprs YshExprs;
};

ASDL_NAMES for_iter_e {
  enum no_name {
  Args = 1,
  Words = 2,
  YshExpr = 3,
  };
};

BigStr* for_iter_str(int tag, bool dot = true);

class for_iter_t {
 protected:
  for_iter_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(for_iter_t)
};

class for_iter__Args : public for_iter_t {
 public:
  for_iter__Args() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(for_iter_e::Args), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(for_iter__Args)
};

class for_iter__Words : public for_iter_t {
 public:
  for_iter__Words(List<word_t*>* words)
      : words(words) {
  }

  static for_iter__Words* CreateNull(bool alloc_lists = false) { 
    return Alloc<for_iter__Words>(alloc_lists ? Alloc<List<word_t*>>() :
                                  nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(for_iter_e::Words), 1);
  }

  List<word_t*>* words;

  DISALLOW_COPY_AND_ASSIGN(for_iter__Words)
};

class for_iter__YshExpr : public for_iter_t {
 public:
  for_iter__YshExpr(expr_t* e, Token* blame)
      : e(e),
        blame(blame) {
  }

  static for_iter__YshExpr* CreateNull(bool alloc_lists = false) { 
    return Alloc<for_iter__YshExpr>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(for_iter_e::YshExpr), 2);
  }

  expr_t* e;
  Token* blame;

  DISALLOW_COPY_AND_ASSIGN(for_iter__YshExpr)
};

extern GcGlobal<for_iter__Args> gfor_iter__Args;
ASDL_NAMES for_iter {
  static for_iter__Args* Args;
  typedef for_iter__Words Words;
  typedef for_iter__YshExpr YshExpr;
};

ASDL_NAMES proc_sig_e {
  enum no_name {
  Open = 1,
  Closed = 2,
  };
};

BigStr* proc_sig_str(int tag, bool dot = true);

class proc_sig_t {
 protected:
  proc_sig_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(proc_sig_t)
};

class proc_sig__Open : public proc_sig_t {
 public:
  proc_sig__Open() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(proc_sig_e::Open), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(proc_sig__Open)
};

class proc_sig__Closed : public proc_sig_t {
 public:
  proc_sig__Closed(ParamGroup* word, ParamGroup* positional, ParamGroup* named,
                   Param* block_param)
      : word(word),
        positional(positional),
        named(named),
        block_param(block_param) {
  }

  static proc_sig__Closed* CreateNull(bool alloc_lists = false) { 
    return Alloc<proc_sig__Closed>(nullptr, nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(proc_sig_e::Closed), 4);
  }

  ParamGroup* word;
  ParamGroup* positional;
  ParamGroup* named;
  Param* block_param;

  DISALLOW_COPY_AND_ASSIGN(proc_sig__Closed)
};

extern GcGlobal<proc_sig__Open> gproc_sig__Open;
ASDL_NAMES proc_sig {
  static proc_sig__Open* Open;
  typedef proc_sig__Closed Closed;
};

ASDL_NAMES command_e {
  enum no_name {
  NoOp = 1,
  Redirect = 2,
  Simple = 3,
  ExpandedAlias = 4,
  Sentence = 5,
  ShAssignment = 6,
  ControlFlow = 7,
  Pipeline = 8,
  AndOr = 9,
  DoGroup = 10,
  BraceGroup = 85,
  Subshell = 12,
  DParen = 13,
  DBracket = 14,
  ForEach = 15,
  ForExpr = 16,
  WhileUntil = 17,
  If = 18,
  Case = 19,
  ShFunction = 20,
  TimeBlock = 21,
  CommandList = 22,
  VarDecl = 23,
  BareDecl = 24,
  Mutation = 25,
  Expr = 26,
  Proc = 89,
  Func = 90,
  Retval = 29,
  };
};

BigStr* command_str(int tag, bool dot = true);

class command_t {
 protected:
  command_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(command_t)
};

class command__NoOp : public command_t {
 public:
  command__NoOp() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::NoOp), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(command__NoOp)
};

class command__Redirect : public command_t {
 public:
  command__Redirect(command_t* child, List<Redir*>* redirects)
      : child(child),
        redirects(redirects) {
  }

  static command__Redirect* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Redirect>(nullptr, alloc_lists ?
                                    Alloc<List<Redir*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Redirect), 2);
  }

  command_t* child;
  List<Redir*>* redirects;

  DISALLOW_COPY_AND_ASSIGN(command__Redirect)
};

class command__Simple : public command_t {
 public:
  command__Simple(Token* blame_tok, List<EnvPair*>* more_env, List<word_t*>*
                  words, ArgList* typed_args, value_asdl::LiteralBlock* block,
                  bool is_last_cmd)
      : blame_tok(blame_tok),
        more_env(more_env),
        words(words),
        typed_args(typed_args),
        block(block),
        is_last_cmd(is_last_cmd) {
  }

  static command__Simple* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Simple>(nullptr, alloc_lists ?
                                  Alloc<List<EnvPair*>>() : nullptr,
                                  alloc_lists ? Alloc<List<word_t*>>() :
                                  nullptr, nullptr, nullptr, false);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Simple), 5);
  }

  Token* blame_tok;
  List<EnvPair*>* more_env;
  List<word_t*>* words;
  ArgList* typed_args;
  value_asdl::LiteralBlock* block;
  bool is_last_cmd;

  DISALLOW_COPY_AND_ASSIGN(command__Simple)
};

class command__ExpandedAlias : public command_t {
 public:
  command__ExpandedAlias(command_t* child, List<EnvPair*>* more_env)
      : child(child),
        more_env(more_env) {
  }

  static command__ExpandedAlias* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ExpandedAlias>(nullptr, alloc_lists ?
                                         Alloc<List<EnvPair*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ExpandedAlias), 2);
  }

  command_t* child;
  List<EnvPair*>* more_env;

  DISALLOW_COPY_AND_ASSIGN(command__ExpandedAlias)
};

class command__Sentence : public command_t {
 public:
  command__Sentence(command_t* child, Token* terminator)
      : child(child),
        terminator(terminator) {
  }

  static command__Sentence* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Sentence>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Sentence), 2);
  }

  command_t* child;
  Token* terminator;

  DISALLOW_COPY_AND_ASSIGN(command__Sentence)
};

class command__ShAssignment : public command_t {
 public:
  command__ShAssignment(Token* left, List<AssignPair*>* pairs)
      : left(left),
        pairs(pairs) {
  }

  static command__ShAssignment* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ShAssignment>(nullptr, alloc_lists ?
                                        Alloc<List<AssignPair*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ShAssignment),
                                2);
  }

  Token* left;
  List<AssignPair*>* pairs;

  DISALLOW_COPY_AND_ASSIGN(command__ShAssignment)
};

class command__ControlFlow : public command_t {
 public:
  command__ControlFlow(Token* keyword, word_t* arg_word)
      : keyword(keyword),
        arg_word(arg_word) {
  }

  static command__ControlFlow* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ControlFlow>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ControlFlow),
                                2);
  }

  Token* keyword;
  word_t* arg_word;

  DISALLOW_COPY_AND_ASSIGN(command__ControlFlow)
};

class command__Pipeline : public command_t {
 public:
  command__Pipeline(Token* negated, List<command_t*>* children, List<Token*>*
                    ops)
      : negated(negated),
        children(children),
        ops(ops) {
  }

  static command__Pipeline* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Pipeline>(nullptr, alloc_lists ?
                                    Alloc<List<command_t*>>() : nullptr,
                                    alloc_lists ? Alloc<List<Token*>>() :
                                    nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Pipeline), 3);
  }

  Token* negated;
  List<command_t*>* children;
  List<Token*>* ops;

  DISALLOW_COPY_AND_ASSIGN(command__Pipeline)
};

class command__AndOr : public command_t {
 public:
  command__AndOr(List<command_t*>* children, List<Token*>* ops)
      : children(children),
        ops(ops) {
  }

  static command__AndOr* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__AndOr>(alloc_lists ? Alloc<List<command_t*>>() :
                                 nullptr, alloc_lists ? Alloc<List<Token*>>() :
                                 nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::AndOr), 2);
  }

  List<command_t*>* children;
  List<Token*>* ops;

  DISALLOW_COPY_AND_ASSIGN(command__AndOr)
};

class command__DoGroup : public command_t {
 public:
  command__DoGroup(Token* left, List<command_t*>* children, Token* right)
      : left(left),
        children(children),
        right(right) {
  }

  static command__DoGroup* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__DoGroup>(nullptr, alloc_lists ?
                                   Alloc<List<command_t*>>() : nullptr,
                                   nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::DoGroup), 3);
  }

  Token* left;
  List<command_t*>* children;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(command__DoGroup)
};

class command__Subshell : public command_t {
 public:
  command__Subshell(Token* left, command_t* child, Token* right, bool
                    is_last_cmd)
      : left(left),
        child(child),
        right(right),
        is_last_cmd(is_last_cmd) {
  }

  static command__Subshell* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Subshell>(nullptr, nullptr, nullptr, false);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Subshell), 3);
  }

  Token* left;
  command_t* child;
  Token* right;
  bool is_last_cmd;

  DISALLOW_COPY_AND_ASSIGN(command__Subshell)
};

class command__DParen : public command_t {
 public:
  command__DParen(Token* left, arith_expr_t* child, Token* right)
      : left(left),
        child(child),
        right(right) {
  }

  static command__DParen* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__DParen>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::DParen), 3);
  }

  Token* left;
  arith_expr_t* child;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(command__DParen)
};

class command__DBracket : public command_t {
 public:
  command__DBracket(Token* left, bool_expr_t* expr, Token* right)
      : left(left),
        expr(expr),
        right(right) {
  }

  static command__DBracket* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__DBracket>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::DBracket), 3);
  }

  Token* left;
  bool_expr_t* expr;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(command__DBracket)
};

class command__ForEach : public command_t {
 public:
  command__ForEach(Token* keyword, List<BigStr*>* iter_names, for_iter_t*
                   iterable, Token* semi_tok, command_t* body)
      : keyword(keyword),
        iter_names(iter_names),
        iterable(iterable),
        semi_tok(semi_tok),
        body(body) {
  }

  static command__ForEach* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ForEach>(nullptr, alloc_lists ?
                                   Alloc<List<BigStr*>>() : nullptr, nullptr,
                                   nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ForEach), 5);
  }

  Token* keyword;
  List<BigStr*>* iter_names;
  for_iter_t* iterable;
  Token* semi_tok;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(command__ForEach)
};

class command__ForExpr : public command_t {
 public:
  command__ForExpr(Token* keyword, arith_expr_t* init, arith_expr_t* cond,
                   arith_expr_t* update, command_t* body)
      : keyword(keyword),
        init(init),
        cond(cond),
        update(update),
        body(body) {
  }

  static command__ForExpr* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ForExpr>(nullptr, nullptr, nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ForExpr), 5);
  }

  Token* keyword;
  arith_expr_t* init;
  arith_expr_t* cond;
  arith_expr_t* update;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(command__ForExpr)
};

class command__WhileUntil : public command_t {
 public:
  command__WhileUntil(Token* keyword, condition_t* cond, command_t* body)
      : keyword(keyword),
        cond(cond),
        body(body) {
  }

  static command__WhileUntil* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__WhileUntil>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::WhileUntil),
                                3);
  }

  Token* keyword;
  condition_t* cond;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(command__WhileUntil)
};

class command__If : public command_t {
 public:
  command__If(Token* if_kw, List<IfArm*>* arms, Token* else_kw,
              List<command_t*>* else_action, Token* fi_kw)
      : if_kw(if_kw),
        arms(arms),
        else_kw(else_kw),
        else_action(else_action),
        fi_kw(fi_kw) {
  }

  static command__If* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__If>(nullptr, alloc_lists ? Alloc<List<IfArm*>>() :
                              nullptr, nullptr, alloc_lists ?
                              Alloc<List<command_t*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::If), 5);
  }

  Token* if_kw;
  List<IfArm*>* arms;
  Token* else_kw;
  List<command_t*>* else_action;
  Token* fi_kw;

  DISALLOW_COPY_AND_ASSIGN(command__If)
};

class command__Case : public command_t {
 public:
  command__Case(Token* case_kw, case_arg_t* to_match, Token* arms_start,
                List<CaseArm*>* arms, Token* arms_end)
      : case_kw(case_kw),
        to_match(to_match),
        arms_start(arms_start),
        arms(arms),
        arms_end(arms_end) {
  }

  static command__Case* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Case>(nullptr, nullptr, nullptr, alloc_lists ?
                                Alloc<List<CaseArm*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Case), 5);
  }

  Token* case_kw;
  case_arg_t* to_match;
  Token* arms_start;
  List<CaseArm*>* arms;
  Token* arms_end;

  DISALLOW_COPY_AND_ASSIGN(command__Case)
};

class command__ShFunction : public command_t {
 public:
  command__ShFunction(Token* keyword, Token* name_tok, BigStr* name, command_t*
                      body)
      : keyword(keyword),
        name_tok(name_tok),
        name(name),
        body(body) {
  }

  static command__ShFunction* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__ShFunction>(nullptr, nullptr, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::ShFunction),
                                4);
  }

  Token* keyword;
  Token* name_tok;
  BigStr* name;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(command__ShFunction)
};

class command__TimeBlock : public command_t {
 public:
  command__TimeBlock(Token* keyword, command_t* pipeline)
      : keyword(keyword),
        pipeline(pipeline) {
  }

  static command__TimeBlock* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__TimeBlock>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::TimeBlock), 2);
  }

  Token* keyword;
  command_t* pipeline;

  DISALLOW_COPY_AND_ASSIGN(command__TimeBlock)
};

class command__CommandList : public command_t {
 public:
  command__CommandList(List<command_t*>* children)
      : children(children) {
  }

  static command__CommandList* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__CommandList>(alloc_lists ? Alloc<List<command_t*>>()
                                       : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::CommandList),
                                1);
  }

  List<command_t*>* children;

  DISALLOW_COPY_AND_ASSIGN(command__CommandList)
};

class command__VarDecl : public command_t {
 public:
  command__VarDecl(Token* keyword, List<NameType*>* lhs, expr_t* rhs)
      : keyword(keyword),
        lhs(lhs),
        rhs(rhs) {
  }

  static command__VarDecl* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__VarDecl>(nullptr, alloc_lists ?
                                   Alloc<List<NameType*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::VarDecl), 3);
  }

  Token* keyword;
  List<NameType*>* lhs;
  expr_t* rhs;

  DISALLOW_COPY_AND_ASSIGN(command__VarDecl)
};

class command__BareDecl : public command_t {
 public:
  command__BareDecl(Token* lhs, expr_t* rhs)
      : lhs(lhs),
        rhs(rhs) {
  }

  static command__BareDecl* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__BareDecl>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::BareDecl), 2);
  }

  Token* lhs;
  expr_t* rhs;

  DISALLOW_COPY_AND_ASSIGN(command__BareDecl)
};

class command__Mutation : public command_t {
 public:
  command__Mutation(Token* keyword, List<y_lhs_t*>* lhs, Token* op, expr_t* rhs)
      : keyword(keyword),
        lhs(lhs),
        op(op),
        rhs(rhs) {
  }

  static command__Mutation* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Mutation>(nullptr, alloc_lists ?
                                    Alloc<List<y_lhs_t*>>() : nullptr, nullptr,
                                    nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Mutation), 4);
  }

  Token* keyword;
  List<y_lhs_t*>* lhs;
  Token* op;
  expr_t* rhs;

  DISALLOW_COPY_AND_ASSIGN(command__Mutation)
};

class command__Expr : public command_t {
 public:
  command__Expr(Token* keyword, expr_t* e)
      : keyword(keyword),
        e(e) {
  }

  static command__Expr* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Expr>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Expr), 2);
  }

  Token* keyword;
  expr_t* e;

  DISALLOW_COPY_AND_ASSIGN(command__Expr)
};

class command__Retval : public command_t {
 public:
  command__Retval(Token* keyword, expr_t* val)
      : keyword(keyword),
        val(val) {
  }

  static command__Retval* CreateNull(bool alloc_lists = false) { 
    return Alloc<command__Retval>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(command_e::Retval), 2);
  }

  Token* keyword;
  expr_t* val;

  DISALLOW_COPY_AND_ASSIGN(command__Retval)
};

extern GcGlobal<command__NoOp> gcommand__NoOp;
ASDL_NAMES command {
  static command__NoOp* NoOp;
  typedef command__Redirect Redirect;
  typedef command__Simple Simple;
  typedef command__ExpandedAlias ExpandedAlias;
  typedef command__Sentence Sentence;
  typedef command__ShAssignment ShAssignment;
  typedef command__ControlFlow ControlFlow;
  typedef command__Pipeline Pipeline;
  typedef command__AndOr AndOr;
  typedef command__DoGroup DoGroup;
  typedef command__Subshell Subshell;
  typedef command__DParen DParen;
  typedef command__DBracket DBracket;
  typedef command__ForEach ForEach;
  typedef command__ForExpr ForExpr;
  typedef command__WhileUntil WhileUntil;
  typedef command__If If;
  typedef command__Case Case;
  typedef command__ShFunction ShFunction;
  typedef command__TimeBlock TimeBlock;
  typedef command__CommandList CommandList;
  typedef command__VarDecl VarDecl;
  typedef command__BareDecl BareDecl;
  typedef command__Mutation Mutation;
  typedef command__Expr Expr;
  typedef command__Retval Retval;
};

ASDL_NAMES glob_part_e {
  enum no_name {
  Literal = 1,
  Operator = 2,
  CharClass = 3,
  };
};

BigStr* glob_part_str(int tag, bool dot = true);

class glob_part_t {
 protected:
  glob_part_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(glob_part_t)
};

class glob_part__Literal : public glob_part_t {
 public:
  glob_part__Literal(Id_t id, BigStr* s)
      : s(s),
        id(id) {
  }

  static glob_part__Literal* CreateNull(bool alloc_lists = false) { 
    return Alloc<glob_part__Literal>(-1, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(glob_part_e::Literal), 1);
  }

  BigStr* s;
  Id_t id;

  DISALLOW_COPY_AND_ASSIGN(glob_part__Literal)
};

class glob_part__Operator : public glob_part_t {
 public:
  glob_part__Operator(Id_t op_id)
      : op_id(op_id) {
  }

  static glob_part__Operator* CreateNull(bool alloc_lists = false) { 
    return Alloc<glob_part__Operator>(-1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(glob_part_e::Operator),
                                0);
  }

  Id_t op_id;

  DISALLOW_COPY_AND_ASSIGN(glob_part__Operator)
};

class glob_part__CharClass : public glob_part_t {
 public:
  glob_part__CharClass(bool negated, List<BigStr*>* strs)
      : strs(strs),
        negated(negated) {
  }

  static glob_part__CharClass* CreateNull(bool alloc_lists = false) { 
    return Alloc<glob_part__CharClass>(false, alloc_lists ?
                                       Alloc<List<BigStr*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(glob_part_e::CharClass),
                                1);
  }

  List<BigStr*>* strs;
  bool negated;

  DISALLOW_COPY_AND_ASSIGN(glob_part__CharClass)
};

ASDL_NAMES glob_part {
  typedef glob_part__Literal Literal;
  typedef glob_part__Operator Operator;
  typedef glob_part__CharClass CharClass;
};

ASDL_NAMES printf_part_e {
  enum no_name {
  Literal = 67,
  Percent = 2,
  };
};

BigStr* printf_part_str(int tag, bool dot = true);

class printf_part_t {
 protected:
  printf_part_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(printf_part_t)
};

class printf_part__Percent : public printf_part_t {
 public:
  printf_part__Percent(List<Token*>* flags, Token* width, Token* precision,
                       Token* type)
      : flags(flags),
        width(width),
        precision(precision),
        type(type) {
  }

  static printf_part__Percent* CreateNull(bool alloc_lists = false) { 
    return Alloc<printf_part__Percent>(alloc_lists ? Alloc<List<Token*>>() :
                                       nullptr, nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(printf_part_e::Percent),
                                4);
  }

  List<Token*>* flags;
  Token* width;
  Token* precision;
  Token* type;

  DISALLOW_COPY_AND_ASSIGN(printf_part__Percent)
};

ASDL_NAMES printf_part {
  typedef printf_part__Percent Percent;
};

enum class expr_context_e {
  Load = 1,
  Store = 2,
  Del = 3,
  AugLoad = 4,
  AugStore = 5,
  Param = 6,
};
typedef expr_context_e expr_context_t;

BigStr* expr_context_str(expr_context_e tag, bool dot = true);

ASDL_NAMES y_lhs_e {
  enum no_name {
  Var = 67,
  Subscript = 96,
  Attribute = 97,
  };
};

BigStr* y_lhs_str(int tag, bool dot = true);

class y_lhs_t {
 protected:
  y_lhs_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(y_lhs_t)
};

ASDL_NAMES y_lhs {
};

ASDL_NAMES place_op_e {
  enum no_name {
  Subscript = 1,
  Attribute = 2,
  };
};

BigStr* place_op_str(int tag, bool dot = true);

class place_op_t {
 protected:
  place_op_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(place_op_t)
};

class place_op__Subscript : public place_op_t {
 public:
  place_op__Subscript(Token* op, expr_t* index)
      : op(op),
        index(index) {
  }

  static place_op__Subscript* CreateNull(bool alloc_lists = false) { 
    return Alloc<place_op__Subscript>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(place_op_e::Subscript),
                                2);
  }

  Token* op;
  expr_t* index;

  DISALLOW_COPY_AND_ASSIGN(place_op__Subscript)
};

class place_op__Attribute : public place_op_t {
 public:
  place_op__Attribute(Token* op, Token* attr)
      : op(op),
        attr(attr) {
  }

  static place_op__Attribute* CreateNull(bool alloc_lists = false) { 
    return Alloc<place_op__Attribute>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(place_op_e::Attribute),
                                2);
  }

  Token* op;
  Token* attr;

  DISALLOW_COPY_AND_ASSIGN(place_op__Attribute)
};

ASDL_NAMES place_op {
  typedef place_op__Subscript Subscript;
  typedef place_op__Attribute Attribute;
};

ASDL_NAMES expr_e {
  enum no_name {
  Var = 1,
  Const = 2,
  Place = 3,
  ShArrayLiteral = 74,
  Eggex = 83,
  SimpleVarSub = 72,
  BracedVarSub = 69,
  CommandSub = 73,
  SingleQuoted = 71,
  DoubleQuoted = 70,
  Literal = 11,
  Lambda = 12,
  Unary = 13,
  Binary = 14,
  Compare = 15,
  FuncCall = 16,
  IfExp = 17,
  Tuple = 18,
  List = 19,
  Dict = 20,
  Implicit = 21,
  ListComp = 22,
  DictComp = 23,
  GeneratorExp = 24,
  Range = 25,
  Slice = 26,
  Subscript = 96,
  Attribute = 97,
  Spread = 29,
  };
};

BigStr* expr_str(int tag, bool dot = true);

class expr_t {
 protected:
  expr_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(expr_t)
};

class expr__Var : public expr_t {
 public:
  expr__Var(Token* left, BigStr* name)
      : left(left),
        name(name) {
  }

  static expr__Var* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Var>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Var), 2);
  }

  Token* left;
  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(expr__Var)
};

class expr__Const : public expr_t {
 public:
  expr__Const(Token* c, value_asdl::value_t* val)
      : c(c),
        val(val) {
  }

  static expr__Const* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Const>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Const), 2);
  }

  Token* c;
  value_asdl::value_t* val;

  DISALLOW_COPY_AND_ASSIGN(expr__Const)
};

class expr__Place : public expr_t {
 public:
  expr__Place(Token* blame_tok, BigStr* var_name, List<place_op_t*>* ops)
      : blame_tok(blame_tok),
        var_name(var_name),
        ops(ops) {
  }

  static expr__Place* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Place>(nullptr, kEmptyString, alloc_lists ?
                              Alloc<List<place_op_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Place), 3);
  }

  Token* blame_tok;
  BigStr* var_name;
  List<place_op_t*>* ops;

  DISALLOW_COPY_AND_ASSIGN(expr__Place)
};

class expr__Literal : public expr_t {
 public:
  expr__Literal(expr_t* inner)
      : inner(inner) {
  }

  static expr__Literal* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Literal>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Literal), 1);
  }

  expr_t* inner;

  DISALLOW_COPY_AND_ASSIGN(expr__Literal)
};

class expr__Lambda : public expr_t {
 public:
  expr__Lambda(List<NameType*>* params, expr_t* body)
      : params(params),
        body(body) {
  }

  static expr__Lambda* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Lambda>(alloc_lists ? Alloc<List<NameType*>>() :
                               nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Lambda), 2);
  }

  List<NameType*>* params;
  expr_t* body;

  DISALLOW_COPY_AND_ASSIGN(expr__Lambda)
};

class expr__Unary : public expr_t {
 public:
  expr__Unary(Token* op, expr_t* child)
      : op(op),
        child(child) {
  }

  static expr__Unary* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Unary>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Unary), 2);
  }

  Token* op;
  expr_t* child;

  DISALLOW_COPY_AND_ASSIGN(expr__Unary)
};

class expr__Binary : public expr_t {
 public:
  expr__Binary(Token* op, expr_t* left, expr_t* right)
      : op(op),
        left(left),
        right(right) {
  }

  static expr__Binary* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Binary>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Binary), 3);
  }

  Token* op;
  expr_t* left;
  expr_t* right;

  DISALLOW_COPY_AND_ASSIGN(expr__Binary)
};

class expr__Compare : public expr_t {
 public:
  expr__Compare(expr_t* left, List<Token*>* ops, List<expr_t*>* comparators)
      : left(left),
        ops(ops),
        comparators(comparators) {
  }

  static expr__Compare* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Compare>(nullptr, alloc_lists ? Alloc<List<Token*>>() :
                                nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                                nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Compare), 3);
  }

  expr_t* left;
  List<Token*>* ops;
  List<expr_t*>* comparators;

  DISALLOW_COPY_AND_ASSIGN(expr__Compare)
};

class expr__FuncCall : public expr_t {
 public:
  expr__FuncCall(expr_t* func, ArgList* args)
      : func(func),
        args(args) {
  }

  static expr__FuncCall* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__FuncCall>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::FuncCall), 2);
  }

  expr_t* func;
  ArgList* args;

  DISALLOW_COPY_AND_ASSIGN(expr__FuncCall)
};

class expr__IfExp : public expr_t {
 public:
  expr__IfExp(expr_t* test, expr_t* body, expr_t* orelse)
      : test(test),
        body(body),
        orelse(orelse) {
  }

  static expr__IfExp* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__IfExp>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::IfExp), 3);
  }

  expr_t* test;
  expr_t* body;
  expr_t* orelse;

  DISALLOW_COPY_AND_ASSIGN(expr__IfExp)
};

class expr__Tuple : public expr_t {
 public:
  expr__Tuple(Token* left, List<expr_t*>* elts, expr_context_t ctx)
      : left(left),
        elts(elts),
        ctx(ctx) {
  }

  static expr__Tuple* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Tuple>(nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                              nullptr, expr_context_e::Load);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Tuple), 2);
  }

  Token* left;
  List<expr_t*>* elts;
  expr_context_t ctx;

  DISALLOW_COPY_AND_ASSIGN(expr__Tuple)
};

class expr__List : public expr_t {
 public:
  expr__List(Token* left, List<expr_t*>* elts, expr_context_t ctx)
      : left(left),
        elts(elts),
        ctx(ctx) {
  }

  static expr__List* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__List>(nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                             nullptr, expr_context_e::Load);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::List), 2);
  }

  Token* left;
  List<expr_t*>* elts;
  expr_context_t ctx;

  DISALLOW_COPY_AND_ASSIGN(expr__List)
};

class expr__Dict : public expr_t {
 public:
  expr__Dict(Token* left, List<expr_t*>* keys, List<expr_t*>* values)
      : left(left),
        keys(keys),
        values(values) {
  }

  static expr__Dict* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Dict>(nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                             nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                             nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Dict), 3);
  }

  Token* left;
  List<expr_t*>* keys;
  List<expr_t*>* values;

  DISALLOW_COPY_AND_ASSIGN(expr__Dict)
};

class expr__Implicit : public expr_t {
 public:
  expr__Implicit() {}

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Implicit), 0);
  }


  DISALLOW_COPY_AND_ASSIGN(expr__Implicit)
};

class expr__ListComp : public expr_t {
 public:
  expr__ListComp(Token* left, expr_t* elt, List<Comprehension*>* generators)
      : left(left),
        elt(elt),
        generators(generators) {
  }

  static expr__ListComp* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__ListComp>(nullptr, nullptr, alloc_lists ?
                                 Alloc<List<Comprehension*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::ListComp), 3);
  }

  Token* left;
  expr_t* elt;
  List<Comprehension*>* generators;

  DISALLOW_COPY_AND_ASSIGN(expr__ListComp)
};

class expr__DictComp : public expr_t {
 public:
  expr__DictComp(Token* left, expr_t* key, expr_t* value, List<Comprehension*>*
                 generators)
      : left(left),
        key(key),
        value(value),
        generators(generators) {
  }

  static expr__DictComp* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__DictComp>(nullptr, nullptr, nullptr, alloc_lists ?
                                 Alloc<List<Comprehension*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::DictComp), 4);
  }

  Token* left;
  expr_t* key;
  expr_t* value;
  List<Comprehension*>* generators;

  DISALLOW_COPY_AND_ASSIGN(expr__DictComp)
};

class expr__GeneratorExp : public expr_t {
 public:
  expr__GeneratorExp(expr_t* elt, List<Comprehension*>* generators)
      : elt(elt),
        generators(generators) {
  }

  static expr__GeneratorExp* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__GeneratorExp>(nullptr, alloc_lists ?
                                     Alloc<List<Comprehension*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::GeneratorExp), 2);
  }

  expr_t* elt;
  List<Comprehension*>* generators;

  DISALLOW_COPY_AND_ASSIGN(expr__GeneratorExp)
};

class expr__Range : public expr_t {
 public:
  expr__Range(expr_t* lower, Token* op, expr_t* upper)
      : lower(lower),
        op(op),
        upper(upper) {
  }

  static expr__Range* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Range>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Range), 3);
  }

  expr_t* lower;
  Token* op;
  expr_t* upper;

  DISALLOW_COPY_AND_ASSIGN(expr__Range)
};

class expr__Slice : public expr_t {
 public:
  expr__Slice(expr_t* lower, Token* op, expr_t* upper)
      : lower(lower),
        op(op),
        upper(upper) {
  }

  static expr__Slice* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Slice>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Slice), 3);
  }

  expr_t* lower;
  Token* op;
  expr_t* upper;

  DISALLOW_COPY_AND_ASSIGN(expr__Slice)
};

class expr__Spread : public expr_t {
 public:
  expr__Spread(Token* left, expr_t* child)
      : left(left),
        child(child) {
  }

  static expr__Spread* CreateNull(bool alloc_lists = false) { 
    return Alloc<expr__Spread>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(expr_e::Spread), 2);
  }

  Token* left;
  expr_t* child;

  DISALLOW_COPY_AND_ASSIGN(expr__Spread)
};

extern GcGlobal<expr__Implicit> gexpr__Implicit;
ASDL_NAMES expr {
  typedef expr__Var Var;
  typedef expr__Const Const;
  typedef expr__Place Place;
  typedef expr__Literal Literal;
  typedef expr__Lambda Lambda;
  typedef expr__Unary Unary;
  typedef expr__Binary Binary;
  typedef expr__Compare Compare;
  typedef expr__FuncCall FuncCall;
  typedef expr__IfExp IfExp;
  typedef expr__Tuple Tuple;
  typedef expr__List List;
  typedef expr__Dict Dict;
  static expr__Implicit* Implicit;
  typedef expr__ListComp ListComp;
  typedef expr__DictComp DictComp;
  typedef expr__GeneratorExp GeneratorExp;
  typedef expr__Range Range;
  typedef expr__Slice Slice;
  typedef expr__Spread Spread;
};

ASDL_NAMES class_literal_term_e {
  enum no_name {
  PosixClass = 98,
  PerlClass = 99,
  CharRange = 101,
  CharCode = 100,
  SingleQuoted = 71,
  Splice = 6,
  };
};

BigStr* class_literal_term_str(int tag, bool dot = true);

class class_literal_term_t {
 protected:
  class_literal_term_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(class_literal_term_t)
};

class class_literal_term__Splice : public class_literal_term_t {
 public:
  class_literal_term__Splice(Token* name, BigStr* var_name)
      : name(name),
        var_name(var_name) {
  }

  static class_literal_term__Splice* CreateNull(bool alloc_lists = false) { 
    return Alloc<class_literal_term__Splice>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return
ObjHeader::AsdlClass(static_cast<uint16_t>(class_literal_term_e::Splice), 2);
  }

  Token* name;
  BigStr* var_name;

  DISALLOW_COPY_AND_ASSIGN(class_literal_term__Splice)
};

ASDL_NAMES class_literal_term {
  typedef class_literal_term__Splice Splice;
};

ASDL_NAMES char_class_term_e {
  enum no_name {
  PosixClass = 98,
  PerlClass = 99,
  CharRange = 101,
  CharCode = 100,
  };
};

BigStr* char_class_term_str(int tag, bool dot = true);

class char_class_term_t {
 protected:
  char_class_term_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(char_class_term_t)
};

ASDL_NAMES char_class_term {
};

ASDL_NAMES re_repeat_e {
  enum no_name {
  Op = 67,
  Range = 2,
  };
};

BigStr* re_repeat_str(int tag, bool dot = true);

class re_repeat_t {
 protected:
  re_repeat_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(re_repeat_t)
};

class re_repeat__Range : public re_repeat_t {
 public:
  re_repeat__Range(Token* left, BigStr* lower, BigStr* upper, Token* right)
      : left(left),
        lower(lower),
        upper(upper),
        right(right) {
  }

  static re_repeat__Range* CreateNull(bool alloc_lists = false) { 
    return Alloc<re_repeat__Range>(nullptr, kEmptyString, kEmptyString,
                                   nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_repeat_e::Range), 4);
  }

  Token* left;
  BigStr* lower;
  BigStr* upper;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(re_repeat__Range)
};

ASDL_NAMES re_repeat {
  typedef re_repeat__Range Range;
};

ASDL_NAMES re_e {
  enum no_name {
  Primitive = 1,
  PosixClass = 98,
  PerlClass = 99,
  CharClassLiteral = 4,
  CharClass = 5,
  Splice = 6,
  SingleQuoted = 71,
  Repeat = 8,
  Seq = 9,
  Alt = 10,
  Group = 11,
  Capture = 12,
  Backtracking = 13,
  LiteralChars = 14,
  };
};

BigStr* re_str(int tag, bool dot = true);

class re_t {
 protected:
  re_t() {
  }
 public:
  int tag() const {
    return ObjHeader::FromObject(this)->type_tag;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);
  DISALLOW_COPY_AND_ASSIGN(re_t)
};

class re__Primitive : public re_t {
 public:
  re__Primitive(Token* blame_tok, Id_t id)
      : blame_tok(blame_tok),
        id(id) {
  }

  static re__Primitive* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Primitive>(nullptr, -1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Primitive), 1);
  }

  Token* blame_tok;
  Id_t id;

  DISALLOW_COPY_AND_ASSIGN(re__Primitive)
};

class re__CharClassLiteral : public re_t {
 public:
  re__CharClassLiteral(bool negated, List<class_literal_term_t*>* terms)
      : terms(terms),
        negated(negated) {
  }

  static re__CharClassLiteral* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__CharClassLiteral>(false, alloc_lists ?
                                       Alloc<List<class_literal_term_t*>>() :
                                       nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::CharClassLiteral),
                                1);
  }

  List<class_literal_term_t*>* terms;
  bool negated;

  DISALLOW_COPY_AND_ASSIGN(re__CharClassLiteral)
};

class re__CharClass : public re_t {
 public:
  re__CharClass(bool negated, List<char_class_term_t*>* terms)
      : terms(terms),
        negated(negated) {
  }

  static re__CharClass* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__CharClass>(false, alloc_lists ?
                                Alloc<List<char_class_term_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::CharClass), 1);
  }

  List<char_class_term_t*>* terms;
  bool negated;

  DISALLOW_COPY_AND_ASSIGN(re__CharClass)
};

class re__Splice : public re_t {
 public:
  re__Splice(Token* name, BigStr* var_name)
      : name(name),
        var_name(var_name) {
  }

  static re__Splice* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Splice>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Splice), 2);
  }

  Token* name;
  BigStr* var_name;

  DISALLOW_COPY_AND_ASSIGN(re__Splice)
};

class re__Repeat : public re_t {
 public:
  re__Repeat(re_t* child, re_repeat_t* op)
      : child(child),
        op(op) {
  }

  static re__Repeat* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Repeat>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Repeat), 2);
  }

  re_t* child;
  re_repeat_t* op;

  DISALLOW_COPY_AND_ASSIGN(re__Repeat)
};

class re__Seq : public re_t {
 public:
  re__Seq(List<re_t*>* children)
      : children(children) {
  }

  static re__Seq* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Seq>(alloc_lists ? Alloc<List<re_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Seq), 1);
  }

  List<re_t*>* children;

  DISALLOW_COPY_AND_ASSIGN(re__Seq)
};

class re__Alt : public re_t {
 public:
  re__Alt(List<re_t*>* children)
      : children(children) {
  }

  static re__Alt* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Alt>(alloc_lists ? Alloc<List<re_t*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Alt), 1);
  }

  List<re_t*>* children;

  DISALLOW_COPY_AND_ASSIGN(re__Alt)
};

class re__Group : public re_t {
 public:
  re__Group(re_t* child)
      : child(child) {
  }

  static re__Group* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Group>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Group), 1);
  }

  re_t* child;

  DISALLOW_COPY_AND_ASSIGN(re__Group)
};

class re__Capture : public re_t {
 public:
  re__Capture(re_t* child, Token* name, Token* func_name)
      : child(child),
        name(name),
        func_name(func_name) {
  }

  static re__Capture* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Capture>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Capture), 3);
  }

  re_t* child;
  Token* name;
  Token* func_name;

  DISALLOW_COPY_AND_ASSIGN(re__Capture)
};

class re__Backtracking : public re_t {
 public:
  re__Backtracking(bool negated, Token* name, re_t* child)
      : name(name),
        child(child),
        negated(negated) {
  }

  static re__Backtracking* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__Backtracking>(false, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::Backtracking), 2);
  }

  Token* name;
  re_t* child;
  bool negated;

  DISALLOW_COPY_AND_ASSIGN(re__Backtracking)
};

class re__LiteralChars : public re_t {
 public:
  re__LiteralChars(Token* blame_tok, BigStr* s)
      : blame_tok(blame_tok),
        s(s) {
  }

  static re__LiteralChars* CreateNull(bool alloc_lists = false) { 
    return Alloc<re__LiteralChars>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(re_e::LiteralChars), 2);
  }

  Token* blame_tok;
  BigStr* s;

  DISALLOW_COPY_AND_ASSIGN(re__LiteralChars)
};

ASDL_NAMES re {
  typedef re__Primitive Primitive;
  typedef re__CharClassLiteral CharClassLiteral;
  typedef re__CharClass CharClass;
  typedef re__Splice Splice;
  typedef re__Repeat Repeat;
  typedef re__Seq Seq;
  typedef re__Alt Alt;
  typedef re__Group Group;
  typedef re__Capture Capture;
  typedef re__Backtracking Backtracking;
  typedef re__LiteralChars LiteralChars;
};

class BoolParamBox {
 public:
  BoolParamBox(bool b)
      : b(b) {
  }

  static BoolParamBox* CreateNull(bool alloc_lists = false) { 
    return Alloc<BoolParamBox>(false);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(64, 0);
  }

  bool b;

  DISALLOW_COPY_AND_ASSIGN(BoolParamBox)
};

class IntParamBox {
 public:
  IntParamBox(int i)
      : i(i) {
  }

  static IntParamBox* CreateNull(bool alloc_lists = false) { 
    return Alloc<IntParamBox>(-1);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(65, 0);
  }

  int i;

  DISALLOW_COPY_AND_ASSIGN(IntParamBox)
};

class SourceLine {
 public:
  SourceLine(int line_num, BigStr* content, source_t* src)
      : content(content),
        src(src),
        line_num(line_num) {
  }

  static SourceLine* CreateNull(bool alloc_lists = false) { 
    return Alloc<SourceLine>(-1, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(66, 2);
  }

  BigStr* content;
  source_t* src;
  int line_num;

  DISALLOW_COPY_AND_ASSIGN(SourceLine)
};

class Token : public loc_t, public suffix_op_t, public word_part_t, public
word_t, public arith_expr_t, public printf_part_t, public y_lhs_t, public
re_repeat_t {
 public:
  Token(Id_t id, uint16_t length, int col, SourceLine* line, BigStr* tval)
      : line(line),
        tval(tval),
        id(id),
        length(length),
        col(col) {
  }

  static Token* CreateNull(bool alloc_lists = false) { 
    return Alloc<Token>(-1, -1, -1, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(67, 2);
  }

  SourceLine* line;
  BigStr* tval;
  Id_t id;
  uint16_t length;
  int col;

  DISALLOW_COPY_AND_ASSIGN(Token)
};

class CompoundWord : public loc_t, public rhs_word_t, public word_t, public
arith_expr_t, public redir_param_t {
 public:
  CompoundWord(List<word_part_t*>* parts)
      : parts(parts) {
  }

  static CompoundWord* CreateNull(bool alloc_lists = false) { 
    return Alloc<CompoundWord>(alloc_lists ? Alloc<List<word_part_t*>>() :
                               nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(68, 1);
  }

  List<word_part_t*>* parts;

  DISALLOW_COPY_AND_ASSIGN(CompoundWord)
};

class BracedVarSub : public word_part_t, public expr_t {
 public:
  BracedVarSub(Token* left, Token* name_tok, BigStr* var_name, Token*
               prefix_op, bracket_op_t* bracket_op, suffix_op_t* suffix_op,
               Token* right)
      : left(left),
        name_tok(name_tok),
        var_name(var_name),
        prefix_op(prefix_op),
        bracket_op(bracket_op),
        suffix_op(suffix_op),
        right(right) {
  }

  static BracedVarSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<BracedVarSub>(nullptr, nullptr, kEmptyString, nullptr,
                               nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(69, 7);
  }

  Token* left;
  Token* name_tok;
  BigStr* var_name;
  Token* prefix_op;
  bracket_op_t* bracket_op;
  suffix_op_t* suffix_op;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(BracedVarSub)
};

class DoubleQuoted : public word_part_t, public expr_t {
 public:
  DoubleQuoted(Token* left, List<word_part_t*>* parts, Token* right)
      : left(left),
        parts(parts),
        right(right) {
  }

  static DoubleQuoted* CreateNull(bool alloc_lists = false) { 
    return Alloc<DoubleQuoted>(nullptr, alloc_lists ?
                               Alloc<List<word_part_t*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(70, 3);
  }

  Token* left;
  List<word_part_t*>* parts;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(DoubleQuoted)
};

class SingleQuoted : public word_part_t, public expr_t, public
class_literal_term_t, public re_t {
 public:
  SingleQuoted(Token* left, BigStr* sval, Token* right)
      : left(left),
        sval(sval),
        right(right) {
  }

  static SingleQuoted* CreateNull(bool alloc_lists = false) { 
    return Alloc<SingleQuoted>(nullptr, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(71, 3);
  }

  Token* left;
  BigStr* sval;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(SingleQuoted)
};

class SimpleVarSub : public word_part_t, public expr_t {
 public:
  SimpleVarSub(Token* tok)
      : tok(tok) {
  }

  static SimpleVarSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<SimpleVarSub>(nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(72, 1);
  }

  Token* tok;

  DISALLOW_COPY_AND_ASSIGN(SimpleVarSub)
};

class CommandSub : public word_part_t, public expr_t {
 public:
  CommandSub(Token* left_token, command_t* child, Token* right)
      : left_token(left_token),
        child(child),
        right(right) {
  }

  static CommandSub* CreateNull(bool alloc_lists = false) { 
    return Alloc<CommandSub>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(73, 3);
  }

  Token* left_token;
  command_t* child;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(CommandSub)
};

class ShArrayLiteral : public word_part_t, public expr_t {
 public:
  ShArrayLiteral(Token* left, List<word_t*>* words, Token* right)
      : left(left),
        words(words),
        right(right) {
  }

  static ShArrayLiteral* CreateNull(bool alloc_lists = false) { 
    return Alloc<ShArrayLiteral>(nullptr, alloc_lists ? Alloc<List<word_t*>>()
                                 : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(74, 3);
  }

  Token* left;
  List<word_t*>* words;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(ShArrayLiteral)
};

class ArgList {
 public:
  ArgList(Token* left, List<expr_t*>* pos_args, Token* semi_tok,
          List<NamedArg*>* named_args, Token* semi_tok2, expr_t* block_expr,
          Token* right)
      : left(left),
        pos_args(pos_args),
        semi_tok(semi_tok),
        named_args(named_args),
        semi_tok2(semi_tok2),
        block_expr(block_expr),
        right(right) {
  }

  static ArgList* CreateNull(bool alloc_lists = false) { 
    return Alloc<ArgList>(nullptr, alloc_lists ? Alloc<List<expr_t*>>() :
                          nullptr, nullptr, alloc_lists ?
                          Alloc<List<NamedArg*>>() : nullptr, nullptr, nullptr,
                          nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(75, 7);
  }

  Token* left;
  List<expr_t*>* pos_args;
  Token* semi_tok;
  List<NamedArg*>* named_args;
  Token* semi_tok2;
  expr_t* block_expr;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(ArgList)
};

class AssocPair {
 public:
  AssocPair(CompoundWord* key, CompoundWord* value)
      : key(key),
        value(value) {
  }

  static AssocPair* CreateNull(bool alloc_lists = false) { 
    return Alloc<AssocPair>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(76, 2);
  }

  CompoundWord* key;
  CompoundWord* value;

  DISALLOW_COPY_AND_ASSIGN(AssocPair)
};

class Redir {
 public:
  Redir(Token* op, redir_loc_t* loc, redir_param_t* arg)
      : op(op),
        loc(loc),
        arg(arg) {
  }

  static Redir* CreateNull(bool alloc_lists = false) { 
    return Alloc<Redir>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(77, 3);
  }

  Token* op;
  redir_loc_t* loc;
  redir_param_t* arg;

  DISALLOW_COPY_AND_ASSIGN(Redir)
};

class AssignPair {
 public:
  AssignPair(Token* left, sh_lhs_t* lhs, assign_op_t op, rhs_word_t* rhs)
      : left(left),
        lhs(lhs),
        rhs(rhs),
        op(op) {
  }

  static AssignPair* CreateNull(bool alloc_lists = false) { 
    return Alloc<AssignPair>(nullptr, nullptr, assign_op_e::Equal, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(78, 3);
  }

  Token* left;
  sh_lhs_t* lhs;
  rhs_word_t* rhs;
  assign_op_t op;

  DISALLOW_COPY_AND_ASSIGN(AssignPair)
};

class EnvPair {
 public:
  EnvPair(Token* left, BigStr* name, rhs_word_t* val)
      : left(left),
        name(name),
        val(val) {
  }

  static EnvPair* CreateNull(bool alloc_lists = false) { 
    return Alloc<EnvPair>(nullptr, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(79, 3);
  }

  Token* left;
  BigStr* name;
  rhs_word_t* val;

  DISALLOW_COPY_AND_ASSIGN(EnvPair)
};

class CaseArm {
 public:
  CaseArm(Token* left, pat_t* pattern, Token* middle, List<command_t*>* action,
          Token* right)
      : left(left),
        pattern(pattern),
        middle(middle),
        action(action),
        right(right) {
  }

  static CaseArm* CreateNull(bool alloc_lists = false) { 
    return Alloc<CaseArm>(nullptr, nullptr, nullptr, alloc_lists ?
                          Alloc<List<command_t*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(81, 5);
  }

  Token* left;
  pat_t* pattern;
  Token* middle;
  List<command_t*>* action;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(CaseArm)
};

class EggexFlag {
 public:
  EggexFlag(bool negated, Token* flag)
      : flag(flag),
        negated(negated) {
  }

  static EggexFlag* CreateNull(bool alloc_lists = false) { 
    return Alloc<EggexFlag>(false, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(82, 1);
  }

  Token* flag;
  bool negated;

  DISALLOW_COPY_AND_ASSIGN(EggexFlag)
};

class Eggex : public pat_t, public expr_t {
 public:
  Eggex(Token* left, re_t* regex, List<EggexFlag*>* flags, Token* trans_pref,
        BigStr* canonical_flags)
      : left(left),
        regex(regex),
        flags(flags),
        trans_pref(trans_pref),
        canonical_flags(canonical_flags) {
  }

  static Eggex* CreateNull(bool alloc_lists = false) { 
    return Alloc<Eggex>(nullptr, nullptr, alloc_lists ?
                        Alloc<List<EggexFlag*>>() : nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(83, 5);
  }

  Token* left;
  re_t* regex;
  List<EggexFlag*>* flags;
  Token* trans_pref;
  BigStr* canonical_flags;

  DISALLOW_COPY_AND_ASSIGN(Eggex)
};

class IfArm {
 public:
  IfArm(Token* keyword, condition_t* cond, Token* then_kw, List<command_t*>*
        action, Token* then_tok)
      : keyword(keyword),
        cond(cond),
        then_kw(then_kw),
        action(action),
        then_tok(then_tok) {
  }

  static IfArm* CreateNull(bool alloc_lists = false) { 
    return Alloc<IfArm>(nullptr, nullptr, nullptr, alloc_lists ?
                        Alloc<List<command_t*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(84, 5);
  }

  Token* keyword;
  condition_t* cond;
  Token* then_kw;
  List<command_t*>* action;
  Token* then_tok;

  DISALLOW_COPY_AND_ASSIGN(IfArm)
};

class BraceGroup : public command_t {
 public:
  BraceGroup(Token* left, Token* doc_token, List<command_t*>* children, Token*
             right)
      : left(left),
        doc_token(doc_token),
        children(children),
        right(right) {
  }

  static BraceGroup* CreateNull(bool alloc_lists = false) { 
    return Alloc<BraceGroup>(nullptr, nullptr, alloc_lists ?
                             Alloc<List<command_t*>>() : nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(85, 4);
  }

  Token* left;
  Token* doc_token;
  List<command_t*>* children;
  Token* right;

  DISALLOW_COPY_AND_ASSIGN(BraceGroup)
};

class Param {
 public:
  Param(Token* blame_tok, BigStr* name, TypeExpr* type, expr_t* default_val)
      : blame_tok(blame_tok),
        name(name),
        type(type),
        default_val(default_val) {
  }

  static Param* CreateNull(bool alloc_lists = false) { 
    return Alloc<Param>(nullptr, kEmptyString, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(86, 4);
  }

  Token* blame_tok;
  BigStr* name;
  TypeExpr* type;
  expr_t* default_val;

  DISALLOW_COPY_AND_ASSIGN(Param)
};

class RestParam {
 public:
  RestParam(Token* blame_tok, BigStr* name)
      : blame_tok(blame_tok),
        name(name) {
  }

  static RestParam* CreateNull(bool alloc_lists = false) { 
    return Alloc<RestParam>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(87, 2);
  }

  Token* blame_tok;
  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(RestParam)
};

class ParamGroup {
 public:
  ParamGroup(List<Param*>* params, RestParam* rest_of)
      : params(params),
        rest_of(rest_of) {
  }

  static ParamGroup* CreateNull(bool alloc_lists = false) { 
    return Alloc<ParamGroup>(alloc_lists ? Alloc<List<Param*>>() : nullptr,
                             nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(88, 2);
  }

  List<Param*>* params;
  RestParam* rest_of;

  DISALLOW_COPY_AND_ASSIGN(ParamGroup)
};

class Proc : public command_t {
 public:
  Proc(Token* keyword, Token* name, proc_sig_t* sig, command_t* body)
      : keyword(keyword),
        name(name),
        sig(sig),
        body(body) {
  }

  static Proc* CreateNull(bool alloc_lists = false) { 
    return Alloc<Proc>(nullptr, nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(89, 4);
  }

  Token* keyword;
  Token* name;
  proc_sig_t* sig;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(Proc)
};

class Func : public command_t {
 public:
  Func(Token* keyword, Token* name, ParamGroup* positional, ParamGroup* named,
       command_t* body)
      : keyword(keyword),
        name(name),
        positional(positional),
        named(named),
        body(body) {
  }

  static Func* CreateNull(bool alloc_lists = false) { 
    return Alloc<Func>(nullptr, nullptr, nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(90, 5);
  }

  Token* keyword;
  Token* name;
  ParamGroup* positional;
  ParamGroup* named;
  command_t* body;

  DISALLOW_COPY_AND_ASSIGN(Func)
};

class ParsedAssignment {
 public:
  ParsedAssignment(Token* left, Token* close, int part_offset, CompoundWord* w)
      : left(left),
        close(close),
        w(w),
        part_offset(part_offset) {
  }

  static ParsedAssignment* CreateNull(bool alloc_lists = false) { 
    return Alloc<ParsedAssignment>(nullptr, nullptr, -1, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(91, 3);
  }

  Token* left;
  Token* close;
  CompoundWord* w;
  int part_offset;

  DISALLOW_COPY_AND_ASSIGN(ParsedAssignment)
};

class TypeExpr {
 public:
  TypeExpr(Token* tok, BigStr* name, List<TypeExpr*>* params)
      : tok(tok),
        name(name),
        params(params) {
  }

  static TypeExpr* CreateNull(bool alloc_lists = false) { 
    return Alloc<TypeExpr>(nullptr, kEmptyString, alloc_lists ?
                           Alloc<List<TypeExpr*>>() : nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(92, 3);
  }

  Token* tok;
  BigStr* name;
  List<TypeExpr*>* params;

  DISALLOW_COPY_AND_ASSIGN(TypeExpr)
};

class NameType {
 public:
  NameType(Token* left, BigStr* name, TypeExpr* typ)
      : left(left),
        name(name),
        typ(typ) {
  }

  static NameType* CreateNull(bool alloc_lists = false) { 
    return Alloc<NameType>(nullptr, kEmptyString, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(93, 3);
  }

  Token* left;
  BigStr* name;
  TypeExpr* typ;

  DISALLOW_COPY_AND_ASSIGN(NameType)
};

class Comprehension {
 public:
  Comprehension(List<NameType*>* lhs, expr_t* iter, expr_t* cond)
      : lhs(lhs),
        iter(iter),
        cond(cond) {
  }

  static Comprehension* CreateNull(bool alloc_lists = false) { 
    return Alloc<Comprehension>(alloc_lists ? Alloc<List<NameType*>>() :
                                nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(94, 3);
  }

  List<NameType*>* lhs;
  expr_t* iter;
  expr_t* cond;

  DISALLOW_COPY_AND_ASSIGN(Comprehension)
};

class NamedArg {
 public:
  NamedArg(Token* name, expr_t* value)
      : name(name),
        value(value) {
  }

  static NamedArg* CreateNull(bool alloc_lists = false) { 
    return Alloc<NamedArg>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(95, 2);
  }

  Token* name;
  expr_t* value;

  DISALLOW_COPY_AND_ASSIGN(NamedArg)
};

class Subscript : public y_lhs_t, public expr_t {
 public:
  Subscript(Token* left, expr_t* obj, expr_t* index)
      : left(left),
        obj(obj),
        index(index) {
  }

  static Subscript* CreateNull(bool alloc_lists = false) { 
    return Alloc<Subscript>(nullptr, nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(96, 3);
  }

  Token* left;
  expr_t* obj;
  expr_t* index;

  DISALLOW_COPY_AND_ASSIGN(Subscript)
};

class Attribute : public y_lhs_t, public expr_t {
 public:
  Attribute(expr_t* obj, Token* op, Token* attr, BigStr* attr_name,
            expr_context_t ctx)
      : obj(obj),
        op(op),
        attr(attr),
        attr_name(attr_name),
        ctx(ctx) {
  }

  static Attribute* CreateNull(bool alloc_lists = false) { 
    return Alloc<Attribute>(nullptr, nullptr, nullptr, kEmptyString,
                            expr_context_e::Load);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(97, 4);
  }

  expr_t* obj;
  Token* op;
  Token* attr;
  BigStr* attr_name;
  expr_context_t ctx;

  DISALLOW_COPY_AND_ASSIGN(Attribute)
};

class PosixClass : public class_literal_term_t, public char_class_term_t,
public re_t {
 public:
  PosixClass(Token* negated, BigStr* name)
      : negated(negated),
        name(name) {
  }

  static PosixClass* CreateNull(bool alloc_lists = false) { 
    return Alloc<PosixClass>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(98, 2);
  }

  Token* negated;
  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(PosixClass)
};

class PerlClass : public class_literal_term_t, public char_class_term_t, public
re_t {
 public:
  PerlClass(Token* negated, BigStr* name)
      : negated(negated),
        name(name) {
  }

  static PerlClass* CreateNull(bool alloc_lists = false) { 
    return Alloc<PerlClass>(nullptr, kEmptyString);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(99, 2);
  }

  Token* negated;
  BigStr* name;

  DISALLOW_COPY_AND_ASSIGN(PerlClass)
};

class CharCode : public class_literal_term_t, public char_class_term_t {
 public:
  CharCode(Token* blame_tok, int i, bool u_braced)
      : blame_tok(blame_tok),
        i(i),
        u_braced(u_braced) {
  }

  static CharCode* CreateNull(bool alloc_lists = false) { 
    return Alloc<CharCode>(nullptr, -1, false);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(100, 1);
  }

  Token* blame_tok;
  int i;
  bool u_braced;

  DISALLOW_COPY_AND_ASSIGN(CharCode)
};

class CharRange : public class_literal_term_t, public char_class_term_t {
 public:
  CharRange(CharCode* start, CharCode* end)
      : start(start),
        end(end) {
  }

  static CharRange* CreateNull(bool alloc_lists = false) { 
    return Alloc<CharRange>(nullptr, nullptr);
  }

  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(101, 2);
  }

  CharCode* start;
  CharCode* end;

  DISALLOW_COPY_AND_ASSIGN(CharRange)
};

class List_of_command : public condition_t, public List<command_t*> {
 public:
  List_of_command() : List<command_t*>() {
  }
  List_of_command(List<command_t*>* plain_list) : List<command_t*>(plain_list) {
  }
  static List_of_command* New() {
    return Alloc<List_of_command>();
  }
  static List_of_command* Take(List<command_t*>* plain_list) {
    auto* result = Alloc<List_of_command>(plain_list);
    plain_list->SetTaken();
    return result;
  }
  hnode_t* PrettyTree(bool do_abbrev, Dict<int, bool>* seen = nullptr);

  static constexpr ObjHeader obj_header() {
    return ObjHeader::TaggedSubtype(80, field_mask());
  }

  DISALLOW_COPY_AND_ASSIGN(List_of_command)
};


}  // namespace syntax_asdl

#endif  // SYNTAX_ASDL