#include "Node.h"

//  oop mValue;

BlockReturnNode::BlockReturnNode(oop value)
{
  mValue= value;
}

oop BlockReturnNode::withValue(oop value)
{
  return new BlockReturnNode(value);
}

int BlockReturnNode::isReturn(void)
{
  return 1;
}

oop BlockReturnNode::encode(oop encoder)
{
  mValue->encode(encoder);
  return this;
}

oop BlockReturnNode::gen(oop unit)
{
  mValue->gen(unit);
  unit->outputStream()->format("  return _%d;\n", mValue->location());
  return this;
}

oop BlockReturnNode::printOnIndent(oop stream, int indent)
{
  stream->space(indent * 2)->format("^")->nl();
  return mValue->printOnIndent(stream, indent + 1);
}

//  int mLevel;

ReturnNode::ReturnNode(oop value) : BlockReturnNode(value)
{
  mLevel= 0;
}

oop ReturnNode::withValue(oop value)
{
  return new ReturnNode(value);
}

oop ReturnNode::encode(oop encoder)
{
  oop outer;
  for (outer= encoder;  outer->parent();  outer= outer->parent())
    ++mLevel;
  if (mLevel)
    encoder->noteExportNLR();
  return BlockReturnNode::encode(encoder);
}

oop ReturnNode::gen(oop unit)
{
  if (mLevel)
    {
      oop stream= unit->outputStream();
      int i;
      mValue->gen(unit);
      stream->format("  return _nlReturn(_self, ((struct t_BlockClosureNLR *)");
      for (i= 1;  i < mLevel;  ++i)
	stream->format("((struct t_BlockClosure *)");
      stream->format("_self)");
      for (i= 1;  i < mLevel;  ++i)
	stream->format("->outer)");
      stream->format("->_envp, _%d);\n", mValue->location());
    }
  else
    BlockReturnNode::gen(unit);
  return this;
}
