// _gen/mycpp/examples/expr.asdl.cc is generated by asdl_main.py

#include "_gen/mycpp/examples/expr.asdl.h"
#include <assert.h>
#include "prebuilt/asdl/runtime.mycpp.h"  // generated code uses wrappers here

// Generated code uses these types
using hnode_asdl::hnode;
using hnode_asdl::Field;
using hnode_asdl::color_e;


namespace expr_asdl {

BigStr* tok_str(tok_e tag, bool dot) {
  char buf[32];
  const char* v = nullptr;
  switch (tag) {
  case tok_e::Const:
    v = "Const"; break;
  case tok_e::Var:
    v = "Var"; break;
  case tok_e::Op1:
    v = "Op1"; break;
  case tok_e::Op2:
    v = "Op2"; break;
  case tok_e::Paren:
    v = "Paren"; break;
  case tok_e::Eof:
    v = "Eof"; break;
  case tok_e::Invalid:
    v = "Invalid"; break;
  default:
    assert(0);
  }
  if (dot) {
    snprintf(buf, 32, "tok.%s", v);
    return StrFromC(buf);
  } else {
    return StrFromC(v);
  }
}
BigStr* expr_str(int tag, bool dot) {
  char buf[32];
  const char* v = nullptr;
  switch (tag) {
  case expr_e::Const:
    v = "Const"; break;
  case expr_e::Var:
    v = "Var"; break;
  case expr_e::Binary:
    v = "Binary"; break;
  default:
    assert(0);
  }
  if (dot) {
    snprintf(buf, 32, "expr.%s", v);
    return StrFromC(buf);
  } else {
    return StrFromC(v);
  }
}

hnode_t* expr__Const::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Record* out_node = runtime::NewRecord(expr_str(this->tag()));
  List<Field*>* L = out_node->fields;

  hnode_t* x0 = ToPretty(this->i);
  L->append(Alloc<Field>(StrFromC("i"), x0));

  return out_node;
}


hnode_t* expr__Var::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Record* out_node = runtime::NewRecord(expr_str(this->tag()));
  List<Field*>* L = out_node->fields;

  hnode_t* x0 = ToPretty(this->name);
  L->append(Alloc<Field>(StrFromC("name"), x0));

  return out_node;
}


hnode_t* expr__Binary::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Record* out_node = runtime::NewRecord(expr_str(this->tag()));
  List<Field*>* L = out_node->fields;

  hnode_t* x0 = ToPretty(this->op);
  L->append(Alloc<Field>(StrFromC("op"), x0));

  hnode_t* x1 = this->left->PrettyTree(do_abbrev, seen);
  L->append(Alloc<Field>(StrFromC("left"), x1));

  hnode_t* x2 = this->right->PrettyTree(do_abbrev, seen);
  L->append(Alloc<Field>(StrFromC("right"), x2));

  return out_node;
}


hnode_t* expr_t::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  switch (this->tag()) {
  case expr_e::Const: {
    expr__Const* obj = static_cast<expr__Const*>(this);
    return obj->PrettyTree(do_abbrev, seen);
  }
  case expr_e::Var: {
    expr__Var* obj = static_cast<expr__Var*>(this);
    return obj->PrettyTree(do_abbrev, seen);
  }
  case expr_e::Binary: {
    expr__Binary* obj = static_cast<expr__Binary*>(this);
    return obj->PrettyTree(do_abbrev, seen);
  }
  default:
    assert(0);
  }
}

hnode_t* CompoundWord::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Array* out_node = Alloc<hnode::Array>(Alloc<List<hnode_t*>>());
  for (ListIter<BigStr*> it(this); !it.Done(); it.Next()) {
    BigStr* v_ = it.Value();
    hnode_t* h = ToPretty(v_);
    out_node->children->append(h);
  }
  return out_node;
}


hnode_t* Measure_v::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Record* out_node = runtime::NewRecord(StrFromC("Measure_v"));
  List<Field*>* L = out_node->fields;

  hnode_t* x0 = ToPretty(this->a);
  L->append(Alloc<Field>(StrFromC("a"), x0));

  hnode_t* x1 = ToPretty(this->b);
  L->append(Alloc<Field>(StrFromC("b"), x1));

  return out_node;
}


hnode_t* MeasuredDoc::PrettyTree(bool do_abbrev, Dict<int, bool>* seen) {
  seen = seen ? seen : Alloc<Dict<int, bool>>();
  int heap_id = ObjectId(this);
  if (dict_contains(seen, heap_id)) {
    return Alloc<hnode::AlreadySeen>(heap_id);
  }
  seen->set(heap_id, true);

  hnode::Record* out_node = runtime::NewRecord(StrFromC("MeasuredDoc"));
  List<Field*>* L = out_node->fields;

  hnode_t* x0 = ToPretty(this->s);
  L->append(Alloc<Field>(StrFromC("s"), x0));

  hnode_t* x1 = this->measure->PrettyTree(do_abbrev, seen);
  L->append(Alloc<Field>(StrFromC("measure"), x1));

  return out_node;
}


}  // namespace expr_asdl