// _gen/core/value.asdl.h is generated by asdl_main.py

#ifndef VALUE_ASDL
#define VALUE_ASDL

#include <cstdint>

#include "mycpp/runtime.h"
#include "_gen/asdl/hnode.asdl.h"
using hnode_asdl::hnode_t;

namespace syntax_asdl { class loc_t; class Token; class expr_t; class command_t; class DoubleQuoted; class re_t; class proc_sig_t; class LiteralBlock; class Func; class NameType; class EggexFlag; }

namespace runtime_asdl { class Cell; }

namespace value_asdl {

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

class IntBox;
class ProcDefaults;
class LeftName;
class y_lvalue_t;
class sh_lvalue_t;
class eggex_ops_t;
class RegexMatch;
class regex_match_t;
class value_t;

ASDL_NAMES y_lvalue_e {
  enum no_name {
  Local = 66,
  Container = 2,
  };
};

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

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

class y_lvalue__Container : public y_lvalue_t {
 public:
  y_lvalue__Container(value_t* obj, value_t* index)
      : obj(obj),
        index(index) {
  }

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

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

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

  value_t* obj;
  value_t* index;

  DISALLOW_COPY_AND_ASSIGN(y_lvalue__Container)
};

ASDL_NAMES y_lvalue {
  typedef y_lvalue__Container Container;
};

ASDL_NAMES sh_lvalue_e {
  enum no_name {
  Var = 66,
  Indexed = 2,
  Keyed = 3,
  };
};

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

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

class sh_lvalue__Indexed : public sh_lvalue_t {
 public:
  sh_lvalue__Indexed(BigStr* name, int index, syntax_asdl::loc_t* blame_loc)
      : name(name),
        blame_loc(blame_loc),
        index(index) {
  }

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

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

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

  BigStr* name;
  syntax_asdl::loc_t* blame_loc;
  int index;

  DISALLOW_COPY_AND_ASSIGN(sh_lvalue__Indexed)
};

class sh_lvalue__Keyed : public sh_lvalue_t {
 public:
  sh_lvalue__Keyed(BigStr* name, BigStr* key, syntax_asdl::loc_t* blame_loc)
      : name(name),
        key(key),
        blame_loc(blame_loc) {
  }

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

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

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

  BigStr* name;
  BigStr* key;
  syntax_asdl::loc_t* blame_loc;

  DISALLOW_COPY_AND_ASSIGN(sh_lvalue__Keyed)
};

ASDL_NAMES sh_lvalue {
  typedef sh_lvalue__Indexed Indexed;
  typedef sh_lvalue__Keyed Keyed;
};

ASDL_NAMES eggex_ops_e {
  enum no_name {
  No = 1,
  Yes = 2,
  };
};

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

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

class eggex_ops__No : public eggex_ops_t {
 public:
  eggex_ops__No() {}

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

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


  DISALLOW_COPY_AND_ASSIGN(eggex_ops__No)
};

class eggex_ops__Yes : public eggex_ops_t {
 public:
  eggex_ops__Yes(List<value_t*>* convert_funcs, List<syntax_asdl::Token*>*
                 convert_toks, List<BigStr*>* capture_names)
      : convert_funcs(convert_funcs),
        convert_toks(convert_toks),
        capture_names(capture_names) {
  }

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

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

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

  List<value_t*>* convert_funcs;
  List<syntax_asdl::Token*>* convert_toks;
  List<BigStr*>* capture_names;

  DISALLOW_COPY_AND_ASSIGN(eggex_ops__Yes)
};

extern GcGlobal<eggex_ops__No> geggex_ops__No;
ASDL_NAMES eggex_ops {
  static eggex_ops__No* No;
  typedef eggex_ops__Yes Yes;
};

ASDL_NAMES regex_match_e {
  enum no_name {
  No = 1,
  Yes = 67,
  };
};

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

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

class regex_match__No : public regex_match_t {
 public:
  regex_match__No() {}

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

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


  DISALLOW_COPY_AND_ASSIGN(regex_match__No)
};

extern GcGlobal<regex_match__No> gregex_match__No;
ASDL_NAMES regex_match {
  static regex_match__No* No;
};

ASDL_NAMES value_e {
  enum no_name {
  Interrupted = 1,
  Undef = 2,
  Str = 3,
  BashArray = 4,
  SparseArray = 5,
  BashAssoc = 6,
  Null = 7,
  Bool = 8,
  Int = 9,
  Float = 10,
  List = 11,
  Dict = 12,
  Eggex = 13,
  Match = 67,
  Expr = 15,
  Command = 16,
  Block = 17,
  Place = 18,
  Module = 19,
  IO = 20,
  Guts = 21,
  BuiltinFunc = 22,
  BoundFunc = 23,
  Proc = 24,
  Func = 25,
  Slice = 26,
  Range = 27,
  };
};

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

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

class value__Interrupted : public value_t {
 public:
  value__Interrupted() {}

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

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


  DISALLOW_COPY_AND_ASSIGN(value__Interrupted)
};

class value__Undef : public value_t {
 public:
  value__Undef() {}

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

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


  DISALLOW_COPY_AND_ASSIGN(value__Undef)
};

class value__Str : public value_t {
 public:
  value__Str(BigStr* s)
      : s(s) {
  }

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

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

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

  BigStr* s;

  DISALLOW_COPY_AND_ASSIGN(value__Str)
};

class value__BashArray : public value_t {
 public:
  value__BashArray(List<BigStr*>* strs)
      : strs(strs) {
  }

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

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

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

  List<BigStr*>* strs;

  DISALLOW_COPY_AND_ASSIGN(value__BashArray)
};

class value__SparseArray : public value_t {
 public:
  value__SparseArray(Dict<mops::BigInt, BigStr*>* d, mops::BigInt max_index)
      : d(d),
        max_index(max_index) {
  }

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

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

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

  Dict<mops::BigInt, BigStr*>* d;
  mops::BigInt max_index;

  DISALLOW_COPY_AND_ASSIGN(value__SparseArray)
};

class value__BashAssoc : public value_t {
 public:
  value__BashAssoc(Dict<BigStr*, BigStr*>* d)
      : d(d) {
  }

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

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

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

  Dict<BigStr*, BigStr*>* d;

  DISALLOW_COPY_AND_ASSIGN(value__BashAssoc)
};

class value__Null : public value_t {
 public:
  value__Null() {}

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

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


  DISALLOW_COPY_AND_ASSIGN(value__Null)
};

class value__Bool : public value_t {
 public:
  value__Bool(bool b)
      : b(b) {
  }

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

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

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

  bool b;

  DISALLOW_COPY_AND_ASSIGN(value__Bool)
};

class value__Int : public value_t {
 public:
  value__Int(mops::BigInt i)
      : i(i) {
  }

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

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

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

  mops::BigInt i;

  DISALLOW_COPY_AND_ASSIGN(value__Int)
};

class value__Float : public value_t {
 public:
  value__Float(double f)
      : f(f) {
  }

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

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

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

  double f;

  DISALLOW_COPY_AND_ASSIGN(value__Float)
};

class value__List : public value_t {
 public:
  value__List(List<value_t*>* items)
      : items(items) {
  }

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

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

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

  List<value_t*>* items;

  DISALLOW_COPY_AND_ASSIGN(value__List)
};

class value__Dict : public value_t {
 public:
  value__Dict(Dict<BigStr*, value_t*>* d)
      : d(d) {
  }

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

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

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

  Dict<BigStr*, value_t*>* d;

  DISALLOW_COPY_AND_ASSIGN(value__Dict)
};

class value__Eggex : public value_t {
 public:
  value__Eggex(syntax_asdl::re_t* spliced, BigStr* canonical_flags,
               List<value_t*>* convert_funcs, List<syntax_asdl::Token*>*
               convert_toks, BigStr* as_ere, List<BigStr*>* capture_names)
      : spliced(spliced),
        canonical_flags(canonical_flags),
        convert_funcs(convert_funcs),
        convert_toks(convert_toks),
        as_ere(as_ere),
        capture_names(capture_names) {
  }

  static value__Eggex* CreateNull(bool alloc_lists = false) { 
    return Alloc<value__Eggex>(nullptr, kEmptyString, alloc_lists ?
                               Alloc<List<value_t*>>() : nullptr, alloc_lists ?
                               Alloc<List<syntax_asdl::Token*>>() : nullptr,
                               nullptr, alloc_lists ? Alloc<List<BigStr*>>() :
                               nullptr);
  }

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

  static constexpr ObjHeader obj_header() {
    return ObjHeader::AsdlClass(static_cast<uint16_t>(value_e::Eggex), 6);
  }

  syntax_asdl::re_t* spliced;
  BigStr* canonical_flags;
  List<value_t*>* convert_funcs;
  List<syntax_asdl::Token*>* convert_toks;
  BigStr* as_ere;
  List<BigStr*>* capture_names;

  DISALLOW_COPY_AND_ASSIGN(value__Eggex)
};

class value__Expr : public value_t {
 public:
  value__Expr(syntax_asdl::expr_t* e)
      : e(e) {
  }

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

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

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

  syntax_asdl::expr_t* e;

  DISALLOW_COPY_AND_ASSIGN(value__Expr)
};

class value__Command : public value_t {
 public:
  value__Command(syntax_asdl::command_t* c)
      : c(c) {
  }

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

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

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

  syntax_asdl::command_t* c;

  DISALLOW_COPY_AND_ASSIGN(value__Command)
};

class value__Block : public value_t {
 public:
  value__Block(syntax_asdl::LiteralBlock* block)
      : block(block) {
  }

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

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

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

  syntax_asdl::LiteralBlock* block;

  DISALLOW_COPY_AND_ASSIGN(value__Block)
};

class value__Place : public value_t {
 public:
  value__Place(y_lvalue_t* lval, Dict<BigStr*, runtime_asdl::Cell*>* frame)
      : lval(lval),
        frame(frame) {
  }

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

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

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

  y_lvalue_t* lval;
  Dict<BigStr*, runtime_asdl::Cell*>* frame;

  DISALLOW_COPY_AND_ASSIGN(value__Place)
};

class value__Module : public value_t {
 public:
  value__Module(Dict<BigStr*, value_t*>* defs)
      : defs(defs) {
  }

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

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

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

  Dict<BigStr*, value_t*>* defs;

  DISALLOW_COPY_AND_ASSIGN(value__Module)
};

class value__IO : public value_t {
 public:
  value__IO(void* cmd_ev, void* prompt_ev)
      : cmd_ev(cmd_ev),
        prompt_ev(prompt_ev) {
  }

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

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

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

  void* cmd_ev;
  void* prompt_ev;

  DISALLOW_COPY_AND_ASSIGN(value__IO)
};

class value__Guts : public value_t {
 public:
  value__Guts(void* vm)
      : vm(vm) {
  }

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

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

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

  void* vm;

  DISALLOW_COPY_AND_ASSIGN(value__Guts)
};

class value__BuiltinFunc : public value_t {
 public:
  value__BuiltinFunc(void* callable)
      : callable(callable) {
  }

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

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

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

  void* callable;

  DISALLOW_COPY_AND_ASSIGN(value__BuiltinFunc)
};

class value__BoundFunc : public value_t {
 public:
  value__BoundFunc(value_t* me, value_t* func)
      : me(me),
        func(func) {
  }

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

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

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

  value_t* me;
  value_t* func;

  DISALLOW_COPY_AND_ASSIGN(value__BoundFunc)
};

class value__Proc : public value_t {
 public:
  value__Proc(BigStr* name, syntax_asdl::Token* name_tok,
              syntax_asdl::proc_sig_t* sig, syntax_asdl::command_t* body,
              ProcDefaults* defaults, bool sh_compat)
      : name(name),
        name_tok(name_tok),
        sig(sig),
        body(body),
        defaults(defaults),
        sh_compat(sh_compat) {
  }

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

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

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

  BigStr* name;
  syntax_asdl::Token* name_tok;
  syntax_asdl::proc_sig_t* sig;
  syntax_asdl::command_t* body;
  ProcDefaults* defaults;
  bool sh_compat;

  DISALLOW_COPY_AND_ASSIGN(value__Proc)
};

class value__Func : public value_t {
 public:
  value__Func(BigStr* name, syntax_asdl::Func* parsed, List<value_t*>*
              pos_defaults, Dict<BigStr*, value_t*>* named_defaults,
              Dict<BigStr*, runtime_asdl::Cell*>* module_)
      : name(name),
        parsed(parsed),
        pos_defaults(pos_defaults),
        named_defaults(named_defaults),
        module_(module_) {
  }

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

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

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

  BigStr* name;
  syntax_asdl::Func* parsed;
  List<value_t*>* pos_defaults;
  Dict<BigStr*, value_t*>* named_defaults;
  Dict<BigStr*, runtime_asdl::Cell*>* module_;

  DISALLOW_COPY_AND_ASSIGN(value__Func)
};

class value__Slice : public value_t {
 public:
  value__Slice(IntBox* lower, IntBox* upper)
      : lower(lower),
        upper(upper) {
  }

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

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

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

  IntBox* lower;
  IntBox* upper;

  DISALLOW_COPY_AND_ASSIGN(value__Slice)
};

class value__Range : public value_t {
 public:
  value__Range(int lower, int upper)
      : lower(lower),
        upper(upper) {
  }

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

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

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

  int lower;
  int upper;

  DISALLOW_COPY_AND_ASSIGN(value__Range)
};

extern GcGlobal<value__Interrupted> gvalue__Interrupted;
extern GcGlobal<value__Undef> gvalue__Undef;
extern GcGlobal<value__Null> gvalue__Null;
ASDL_NAMES value {
  static value__Interrupted* Interrupted;
  static value__Undef* Undef;
  typedef value__Str Str;
  typedef value__BashArray BashArray;
  typedef value__SparseArray SparseArray;
  typedef value__BashAssoc BashAssoc;
  static value__Null* Null;
  typedef value__Bool Bool;
  typedef value__Int Int;
  typedef value__Float Float;
  typedef value__List List;
  typedef value__Dict Dict;
  typedef value__Eggex Eggex;
  typedef value__Expr Expr;
  typedef value__Command Command;
  typedef value__Block Block;
  typedef value__Place Place;
  typedef value__Module Module;
  typedef value__IO IO;
  typedef value__Guts Guts;
  typedef value__BuiltinFunc BuiltinFunc;
  typedef value__BoundFunc BoundFunc;
  typedef value__Proc Proc;
  typedef value__Func Func;
  typedef value__Slice Slice;
  typedef value__Range Range;
};

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

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

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

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

  int i;

  DISALLOW_COPY_AND_ASSIGN(IntBox)
};

class ProcDefaults {
 public:
  ProcDefaults(List<value_t*>* for_word, List<value_t*>* for_typed,
               Dict<BigStr*, value_t*>* for_named, value_t* for_block)
      : for_word(for_word),
        for_typed(for_typed),
        for_named(for_named),
        for_block(for_block) {
  }

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

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

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

  List<value_t*>* for_word;
  List<value_t*>* for_typed;
  Dict<BigStr*, value_t*>* for_named;
  value_t* for_block;

  DISALLOW_COPY_AND_ASSIGN(ProcDefaults)
};

class LeftName : public y_lvalue_t, public sh_lvalue_t {
 public:
  LeftName(BigStr* name, syntax_asdl::loc_t* blame_loc)
      : name(name),
        blame_loc(blame_loc) {
  }

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

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

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

  BigStr* name;
  syntax_asdl::loc_t* blame_loc;

  DISALLOW_COPY_AND_ASSIGN(LeftName)
};

class RegexMatch : public regex_match_t, public value_t {
 public:
  RegexMatch(BigStr* s, List<int>* indices, eggex_ops_t* ops)
      : s(s),
        indices(indices),
        ops(ops) {
  }

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

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

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

  BigStr* s;
  List<int>* indices;
  eggex_ops_t* ops;

  DISALLOW_COPY_AND_ASSIGN(RegexMatch)
};


}  // namespace value_asdl

#endif  // VALUE_ASDL
