void VariableEntry::typePrint(ostream& out, int indent) const { out << type()->fullName() << " " << name(); if(initVal() != NULL) { out << " = "; initVal()->typePrint(out, indent); } }
CodeBlock* VariableEntry::codeGen(){ CodeBlock* var_block = new CodeBlock(); if(initVal() != NULL){ var_block->append(initVal()->codeGen()); ICode::ICodeType store_type = ICode::ICodeType::STI; ICode get_addr; if(varKind() == VariableEntry::VarKind::GLOBAL_VAR){ ICode::ICodeType mov_type = ICode::ICodeType::MOVI; get_addr = ICode(mov_type,new Value(offSet(),Type::TypeTag::INT),&mem_register_); } else { ICode::ICodeType add_type = ICode::ICodeType::ADD; get_addr = ICode(add_type,&MemoryMgr::basePointerRegister(),new Value(offSet(),Type::TypeTag::INT),&mem_register_); } if(type()->tag() == Type::TypeTag::BOOL){ CodeBlock* true_block = new CodeBlock(); ICode store_true_val(store_type,new Value(1,Type::TypeTag::UINT),&mem_register_); ICode jmp_end(ICode::ICodeType::JMP,endLabel()); true_block->setStartLabel(trueLabel()); true_block->append(get_addr); true_block->append(store_true_val); true_block->append(jmp_end); CodeBlock* false_block = new CodeBlock(); ICode store_false_val(store_type,new Value(0,Type::TypeTag::UINT),&mem_register_); false_block->setStartLabel(falseLabel()); false_block->append(get_addr); false_block->append(store_false_val); false_block->setEndLabel(endLabel()); var_block->append(true_block); var_block->append(false_block); } else { if(initVal()->reg().isFloat()){ store_type = ICode::ICodeType::STF; } ICode store_val(store_type,&initVal()->reg(),&mem_register_); var_block->append(get_addr); var_block->append(store_val); } } ICode incr_stack(ICode::ICodeType::ADD,&MemoryMgr::stackPointerRegister(),new Value(1,Type::TypeTag::INT),&MemoryMgr::stackPointerRegister()); var_block->append(incr_stack); return var_block; }
void VariableEntry::typePrint(ostream& out, int indent) const{ if(type()==NULL || (type()->tag()==Type::TypeTag::CLASS && type()->typeDesc()==NULL)){ return; } for(int i=0;i<indent;++i){ out << "\t"; } out << type()->fullName()<<" "<< name(); if(initVal()!=NULL){ out << " = "; initVal()->typePrint(out,0); } out << ";" << endl; }
std::tuple<T, T, T> properties(const Collection<T, TAlloc>& coll) { // Get min, max and sum of elements in a collection auto minmax = std::minmax_element(coll.begin(), coll.end()); T initVal(0); T sum = std::accumulate(coll.begin(), coll.end(), initVal); return std::make_tuple(*minmax.first, *minmax.second, sum); }
void VariableEntry::memAlloc(MemoryMgr &mm){ offSet(mm.getNextAddress()); if(initVal()!=NULL){ if(type()->tag() == Type::TypeTag::BOOL){ trueLabel(new Label(Label::LabelType::BOOL_TRUE)); falseLabel(new Label(Label::LabelType::BOOL_FALSE)); endLabel(new Label(Label::LabelType::BOOL_END)); initVal()->trueLabel(trueLabel()); initVal()->falseLabel(falseLabel()); } reg(mm.getNextRegister(true)); mm.addRegister(reg()); initVal()->memAlloc(mm); if(type()->tag() != Type::TypeTag::BOOL){ mm.freeRegister(initVal()->reg()); } mm.freeRegister(reg()); } }
void VariableEntry::print(ostream& out, int indent) const{ if(type()==NULL || (type()->tag()==Type::TypeTag::CLASS && type()->typeDesc()==NULL)){ return; } for(int i=0;i<indent;++i){ out << "\t"; } out << type()->fullName()<<" "<< name(); out << "(offset = " << offSet(); if(reg().isValid()){ out << ", mem_register = " << reg(); } out << ")"; if(initVal()!=NULL){ out << " = "; initVal()->print(out,0); } out << ";" << endl; }
Type* VariableEntry::typeCheck(){ if(initVal()!=NULL){ initVal()->typeCheck(); //Same as from OpNode()::typeCheck() isAssign() case Type* lhs_type = type(); Type* rhs_type = initVal()->type(); pair<bool,bool> check_subtype = Type::isSubType(lhs_type,rhs_type); if(check_subtype.first && check_subtype.second){ return NULL; } if(!check_subtype.first && check_subtype.second){ initVal()->coercedType(lhs_type); return NULL; } errMsg("Assignment between incompatible types",this); } return NULL; }
const Type* VariableEntry::typeCheck() { LOG(""); Type *init_type = NULL; const Type *return_type = NULL; if (initVal()) { init_type = (Type *)initVal()->typeCheck(); if (type()->isSubType(initVal()->type())) { if (!init_type->isSubType(type())) { initVal()->coercedType(type()); } return_type = type(); } else { return_type = new Type(Type::TypeTag::ERROR); errMsg("Assignment between incompatible types", initVal()); } } return return_type; }
ArrayData* StructArray::SetStr( ArrayData* ad, StringData* k, Cell v, bool copy ) { auto structArray = asStructArray(ad); auto shape = structArray->shape(); auto result = structArray; auto offset = shape->offsetFor(k); bool isNewProperty = offset == PropertyTable::kInvalidOffset; auto convertToMixedAndAdd = [&]() { auto mixed = copy ? ToMixedCopy(structArray) : ToMixed(structArray); return mixed->addValNoAsserts(k, v); }; if (isNewProperty) { StringData* staticKey; // We don't support adding non-static strings yet. if (k->isStatic()) { staticKey = k; } else { staticKey = lookupStaticString(k); if (!staticKey) return convertToMixedAndAdd(); } auto newShape = shape->transition(staticKey); if (!newShape) return convertToMixedAndAdd(); result = copy ? CopyAndResizeIfNeeded(structArray, newShape) : ResizeIfNeeded(structArray, newShape); offset = result->shape()->offsetFor(staticKey); assert(offset != PropertyTable::kInvalidOffset); // TODO(#3888164): we should restructure things so we don't have // to check KindOfUninit here. initVal(result->data()[offset], v); return result; } if (copy) { result = asStructArray(Copy(structArray)); } assert(offset != PropertyTable::kInvalidOffset); // TODO(#3888164): we should restructure things so we don't have to // check KindOfUninit here. setVal(result->data()[offset], v); return result; }
void VariableEntry::codeGen(IntermediateCodeGen * list) { LOG(""); int isInt, regPtr = -1, hackyReg = -1; Instruction *instr = NULL; Instruction *getParam = NULL; Instruction *hackyinstr = NULL; Instruction *instrAddOffset = NULL; Value *immediate = NULL; Value *immediate1 = NULL; if (type()->isIntegral(type()->tag()) || type()->isBool(type()->tag())) { setReg(get_vreg_int(), VREG_INT); isInt = 1; } else { setReg(get_vreg_float(), VREG_FLOAT); isInt = 0; } if (varKind() == VariableEntry::VarKind::PARAM_VAR) { immediate1 = new Value(1, Type::TypeTag::INT); instr = new Instruction(Instruction::Mnemonic::ADD); instr->operand_src1(get_vreg_temp_stack(), NULL, VREG_INT); instr->operand_src2(-1, immediate1, Instruction::OpType::IMM); instr->operand_dest(get_vreg_temp_stack(), NULL, VREG_INT); list->addInstruction(instr); getParam = new Instruction(Instruction::typedMnemonic(isInt, Instruction::Mnemonic::LDI)); getParam->operand_src1(get_vreg_temp_stack(), NULL, VREG_INT); getParam->operand_dest(getReg(), NULL, reg_type()); list->addInstruction(getParam); } else if (varKind() == VariableEntry::VarKind::LOCAL_VAR) { if (initVal()) { initVal()->codeGen(list); if (!isInt && initVal()->reg_type() == VREG_INT) { hackyinstr = new Instruction(Instruction::Mnemonic::MOVIF); hackyinstr->operand_src1(initVal()->getReg(), NULL, initVal()->reg_type()); hackyReg = get_vreg_float(); hackyinstr->operand_dest(hackyReg, NULL, VREG_FLOAT); list->addInstruction(hackyinstr); getParam = new Instruction(Instruction::typedMnemonic(isInt, Instruction::Mnemonic::STI)); getParam->operand_src1(hackyReg, NULL, VREG_FLOAT); getParam->operand_dest(get_vreg_sp(), NULL, VREG_INT); list->addInstruction(getParam); } else { getParam = new Instruction(Instruction::typedMnemonic(isInt, Instruction::Mnemonic::STI)); getParam->operand_src1(initVal()->getReg(), NULL, initVal()->reg_type()); getParam->operand_dest(get_vreg_sp(), NULL, VREG_INT); list->addInstruction(getParam); } } immediate1 = new Value(1, Type::TypeTag::INT); instr = new Instruction(Instruction::Mnemonic::SUB); instr->operand_src1(get_vreg_sp(), NULL, VREG_INT); instr->operand_src2(-1, immediate1, Instruction::OpType::IMM); instr->operand_dest(get_vreg_sp(), NULL, VREG_INT); list->addInstruction(instr); } else if (varKind() == VariableEntry::VarKind::GLOBAL_VAR) { instrAddOffset = new Instruction(); instrAddOffset->opcode(Instruction::Mnemonic::ADD); instrAddOffset->operand_src1(get_vreg_global(), NULL, VREG_INT); immediate = new Value(offSet(), Type::TypeTag::INT); instrAddOffset->operand_src2(-1, immediate, Instruction::OpType::IMM); regPtr = get_vreg_int(); instrAddOffset->operand_dest(regPtr, NULL, VREG_INT); list->addInstruction(instrAddOffset); if (initVal()) { initVal()->codeGen(list); instr = new Instruction(Instruction::typedMnemonic(isInt, Instruction::Mnemonic::STI)); instr->operand_dest(regPtr, NULL, VREG_INT); instr->operand_src1(initVal()->getReg(), NULL, initVal()->reg_type()); list->addInstruction(instr); } } return; }