示例#1
0
std::shared_ptr<cs6300::BasicBlock> cs6300::CallExpression::emit() const
{
  auto result = std::make_shared<BasicBlock>();

  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::StoreFrame, 0, 0, 0));

  for(auto&& arg:actualArguments)
  {
    auto code = arg->emit();
    std::copy(code->instructions.begin(),
              code->instructions.end(),
              std::back_inserter(result->instructions));
    result->instructions.emplace_back(ThreeAddressInstruction::CopyArgument,
                                      0 /*TODO:Placeholder for argument*/,
                                      arg->getLabel(),
                                      0);
  }

  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::CallFunction, 0, funcLabel, 0)); // set fp and jump
  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::Return, getLabel(), 0, 0)); // get return value into register

  // TODO: move sp back according to arguments size

  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::RestoreFrame, 0, 0, 0));

  return result;
}
示例#2
0
cs6300::FlowGraph cs6300::Write::emit()
{
  auto block = std::make_shared<BasicBlock>();
  block->instructions.push_back(
    ThreeAddressInstruction("Begin Write", file, line));
  for (auto&& val : values)
  {
    auto b = val->emit();
    std::copy(b->instructions.begin(),
              b->instructions.end(),
              std::back_inserter(block->instructions));
    auto type = val->type();
    auto rtype = std::dynamic_pointer_cast<ReferenceType>(type);
    if (rtype) type = rtype->type;
    if (type == BuiltInType::getInt())
    {
      block->instructions.push_back(ThreeAddressInstruction(
        ThreeAddressInstruction::WriteInt, 0, val->getLabel(), 0));
    }
    else if (type == BuiltInType::getChar())
    {
      block->instructions.push_back(ThreeAddressInstruction(
        ThreeAddressInstruction::WriteChar, 0, val->getLabel(), 0));
    }
    else if (type == BuiltInType::getBool())
    {
      block->instructions.push_back(ThreeAddressInstruction(
        ThreeAddressInstruction::WriteBool, 0, val->getLabel(), 0));
    }
    else if (type == BuiltInType::getStr())
    {
      block->instructions.push_back(ThreeAddressInstruction(
        ThreeAddressInstruction::WriteStr, 0, val->value(), 0));
    }
    else
    {
      if (type)
        LOG(FATAL) << "Unsupported print type " << type->name() << " "
                   << val->name();
      else
        LOG(FATAL) << "Unsupported print type NULL";
    }
  }

  block->instructions.push_back(ThreeAddressInstruction("End Write"));
  return std::make_pair(block, block);
}
示例#3
0
std::shared_ptr<cs6300::BasicBlock> cs6300::CallExpression::emit() const
{
  auto result = std::make_shared<BasicBlock>();

  for (auto&& arg : actualArguments)
  {
    auto code = arg->emit();
    std::copy(code->instructions.begin(),
              code->instructions.end(),
              std::back_inserter(result->instructions));
  }

  int stack_offset = -symbolTable->stackSpace();
  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::StoreFrame, 0, stack_offset, 0));

  int offset = 0;
  for (auto&& arg : actualArguments)
  {
    offset -= arg->type()->size();
    if (std::dynamic_pointer_cast<ArrayType>(arg->type()) ||
        std::dynamic_pointer_cast<RecordType>(arg->type()))
    {
      auto tlabel = Expression::getNextLabel();
      result->instructions.emplace_back(ThreeAddressInstruction(
        "Deep copying. Size " + std::to_string(arg->type()->size())));

      int max = arg->type()->size() / 4;
      for (int i = 0; i < max; i++)
      {
        result->instructions.emplace_back(
          ThreeAddressInstruction::LoadMemory, tlabel, arg->getLabel(), i * 4);

        result->instructions.emplace_back(ThreeAddressInstruction::CopyArgument,
                                          cs6300::STACK,
                                          tlabel,
                                          offset + i * 4);
      }
    }
    else
    {
      result->instructions.emplace_back(ThreeAddressInstruction::CopyArgument,
                                        cs6300::STACK,
                                        arg->getLabel(),
                                        offset);
    }
  }

  result->instructions.push_back(
    ThreeAddressInstruction(ThreeAddressInstruction::CallFunction,
                            0,
                            funcLabel,
                            offset)); // set fp and jump

  result->instructions.push_back(ThreeAddressInstruction(
    ThreeAddressInstruction::RestoreFrame, 0, stack_offset, 0));

  result->instructions.push_back(
    ThreeAddressInstruction(ThreeAddressInstruction::Return,
                            getLabel(),
                            0,
                            0)); // get return value into register

  return result;
}