void AssignmentStatement::evaluate(SymTab &symTab, std::unique_ptr<FuncTab> &funcTab) { if(_lhsExpression == nullptr) { symTab.setValueFor(lhsVariable(), rhsExpression()->evaluate(symTab, funcTab)); } else { auto lhsindex = dynamic_cast<NumberDescriptor*> (_lhsExpression->evaluate(symTab, funcTab).get()); if(lhsindex->type() != TypeDescriptor::INTEGER) { std::cout << "AssignmentStatement::evaluate error index must be"; std::cout << " an integer\n"; exit(1); } int index = lhsindex->value.intValue; auto lhs = symTab.getValueFor(lhsVariable()); auto rhs = _rhsExpression->evaluate(symTab, funcTab); if(lhs->type() == TypeDescriptor::STRINGARRAY) { if(rhs->type() != TypeDescriptor::STRING){ std::cout<<"array value not of compatible types"<<std::endl; exit(1); } auto desc = dynamic_cast<StringDescriptor*>(rhs.get()); std::string val = desc->value; dynamic_cast<StringArray*>(lhs.get())->setSubStr(index, val); } else if(lhs->type() == TypeDescriptor::NUMBERARRAY) { if(rhs->type() != TypeDescriptor::INTEGER){ std::cout<<"array value not of compatible types"<<std::endl; exit(1); } auto desc = dynamic_cast<NumberDescriptor*>(rhs.get()); int val = desc->value.intValue; dynamic_cast<NumberArray*>(lhs.get())->setSubNum(index, val); } } }
void ArrayOps::evaluate(SymTab & symTab, std::unique_ptr<FuncTab> &funcTab) { auto type = symTab.getValueFor(_id)->type(); if(_op == "append") { if(_test == nullptr) { std::cout << "ArrayOps::evaluate append, no element provided\n"; exit(1); } auto element = _test->evaluate(symTab, funcTab); if( type == TypeDescriptor::NUMBERARRAY ) { if(element->type() == TypeDescriptor::INTEGER) { auto nDesc = dynamic_cast<NumberDescriptor*>(element.get()); auto narray = dynamic_cast<NumberArray*> (symTab.getValueFor(_id).get()); narray->nAppend(nDesc->value.intValue); } else { std::cout << "ArrayOps::append error: members must be of "; std::cout << "the same type\n"; exit(1); } } else if(type == TypeDescriptor::STRINGARRAY) { if(element->type() == TypeDescriptor::STRING) { auto sDesc = dynamic_cast<StringDescriptor*>(element.get()); auto sarray = dynamic_cast<StringArray*> (symTab.getValueFor(_id).get()); sarray->sAppend(sDesc->value); } else { std::cout << "ArrayOps::append error: members must be of "; std::cout << "the same type\n"; exit(1); } } else if (type == TypeDescriptor::NULLARRAY) { if(element->type() == TypeDescriptor::INTEGER) { auto nDesc = dynamic_cast<NumberDescriptor*>(element.get()); if(nDesc == nullptr) { std::cout << "ArrayOps::evaluate error: invalid cast"; exit(1); } std::shared_ptr<NumberArray> narray = std::make_shared<NumberArray>(TypeDescriptor::NUMBERARRAY); narray->nAppend(nDesc->value.intValue); symTab.setValueFor(_id, narray); } else if(element->type() == TypeDescriptor::STRING) { auto sDesc = dynamic_cast<StringDescriptor*>(element.get()); if(sDesc == nullptr) { std::cout << "ArrayOps::evaluate error: invalid cast"; exit(1); } std::shared_ptr<StringArray> sarray = std::make_shared<StringArray>(TypeDescriptor::STRINGARRAY); sarray->sAppend(sDesc->value); symTab.setValueFor(_id, sarray); } else { std::cout << "append() is not supported for this type\n"; exit(1); } } else { std::cout << "append() is not supported for this type\n"; exit(1); } } else if (_op == "pop") { if( type == TypeDescriptor::NUMBERARRAY ) { auto narray = dynamic_cast<NumberArray*> (symTab.getValueFor(_id).get()); if(narray != nullptr) { if(_test == nullptr) narray->nPop(); else { auto element = _test->evaluate(symTab, funcTab); narray->nPopIndex(element.get()); } } } else if(type == TypeDescriptor::STRINGARRAY) { auto sarray = dynamic_cast<StringArray*> (symTab.getValueFor(_id).get()); if(sarray != nullptr) { if(_test == nullptr) sarray->sPop(); else { auto element = _test->evaluate(symTab, funcTab); sarray->sPopIndex(element.get()); } } } else { std::cout << "pop is not supported for this type\n"; exit(1); } } }