/* Copyright (C) 1998-2004 Scott Dattalo This file is part of gpsim. gpsim is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation; either version 2, or (at your option) any later version. gpsim is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with gpsim; see the file COPYING. If not, write to the Free Software Foundation, 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ValueCollections.h" #include "symbol.h" IIndexedCollection::IIndexedCollection(int iAddressRadix) { SetAddressRadix(iAddressRadix); } void IIndexedCollection::SetAddressRadix(int iRadix) { m_iAddressRadix = iRadix; if(iRadix == 16) { strcpy(m_szPrefix, "$"); } else { m_szPrefix[0] = 0; } } void IIndexedCollection::Set(Value * pValue) { unsigned int uUpper = GetUpperBound() + 1; for(unsigned int uIndex = GetLowerBound(); uIndex < uUpper; uIndex++) { SetAt(uIndex, pValue); } } void IIndexedCollection::SetAt(ExprList_t* pIndexers, Expression *pExpr) { ExprList_t::iterator it; ExprList_t::iterator itEnd = pIndexers->end(); Value * pValue = pExpr->evaluate(); // _CT * pCTValue = dynamic_cast<_CT*>(pValue); // if(pCTValue != NULL) { for(it = pIndexers->begin(); it != itEnd; it++) { Value * pIndex = (*it)->evaluate(); Integer *pIntIndex = dynamic_cast(pIndex); if(pIntIndex != NULL) { SetAt(int(*pIntIndex), pValue); } else { AbstractRange *pRange = dynamic_cast(pIndex); if(pRange) { unsigned uEnd = pRange->get_rightVal() + 1; for(unsigned int uIndex = pRange->get_leftVal(); uIndex < uEnd; uIndex++) { SetAt(uIndex, pValue); } } else { register_symbol *pReg = dynamic_cast(pIndex); if(pReg) { SetAt(pReg->getReg()->address, pValue); } else { throw Error("indexer not valid"); } } } if(pIndex != NULL) { delete pIndex; } } // } // else { // } delete pValue; } char *IIndexedCollection::toString(char *pBuffer, int len) { return strncpy(pBuffer, toString().c_str(), len); } string IIndexedCollection::toString() { int iColumnWidth = 0; vector asIndexes; vector asValue; ConsolidateValues(iColumnWidth, asIndexes, asValue); return toString(iColumnWidth, asIndexes, asValue); } #if 1 string IIndexedCollection::toString(ExprList_t* pIndexerExprs) { try { ostringstream sOut; if(pIndexerExprs==NULL) { sOut << toString() << ends; return sOut.str(); } else { ExprList_t::iterator it; ExprList_t::iterator itEnd = pIndexerExprs->end(); for(it = pIndexerExprs->begin(); it != itEnd; it++) { Value * pIndex = (*it)->evaluate(); AbstractRange *pRange = dynamic_cast(pIndex); if(pRange) { unsigned uEnd = pRange->get_rightVal() + 1; for(unsigned int uIndex = pRange->get_leftVal(); uIndex < uEnd; uIndex++) { Value &Value = GetAt(uIndex); sOut << Value.name() << " = " << Value.toString() << endl; } continue; } Integer *pInt; String *pName = dynamic_cast(pIndex); if(pName) { pInt = get_symbol_table().findInteger(pName->getVal()); } else { pInt = dynamic_cast(pIndex); } Integer temp(0); if(pInt == NULL) { // This is a temp workaround. I would expect a register symbol // evaluate to an Integer object containing the value of the // register. It currently returns an object that is a copy // of the register_symbol object. register_symbol *pReg = dynamic_cast(pIndex); if(pReg) { gint64 i; pReg->get(i); temp.set(i); pInt = &temp; } } if(pInt) { unsigned int uIndex = (unsigned int)pInt->getVal(); if(bIsIndexInRange(uIndex)) { Value &Value = GetAt(uIndex); sOut << Value.name() << " = " << Value.toString() << endl; } else { sOut << "Error: Index " << uIndex << " is out of range" << endl; } } else { sOut << "Error: The index specified for '" << name() << "' does not contain a valid index." << endl; } delete pIndex; } } sOut << ends; return sOut.str(); } catch(Error e) { return e.toString(); } } #endif void IIndexedCollection::PushValue(int iFirstIndex, int iCurrentIndex, Value *pValue, vector &asIndexes, vector &asValue) { ostringstream sIndex; if(m_iAddressRadix == 16) { sIndex << hex; } sIndex << Value::name() << "[" << m_szPrefix << iFirstIndex; if(iFirstIndex != iCurrentIndex) { sIndex << ".." << m_szPrefix << iCurrentIndex; } sIndex << "]" << ends; asIndexes.push_back(string(sIndex.str())); asValue.push_back(pValue->toString()); } string IIndexedCollection::ElementIndexedName(unsigned int iIndex) { ostringstream sIndex; if(m_iAddressRadix == 16) { sIndex << hex; } sIndex << Value::name() << "[" << m_szPrefix << iIndex; sIndex << "]" << ends; return sIndex.str(); } string IIndexedCollection::toString(int iColumnWidth, vector &asIndexes, vector &asValue) { ostringstream sOut; vector::iterator itValue; vector::iterator itElement; vector::iterator itElementEnd = asIndexes.end(); // Dump the consolidated element list for(itElement = asIndexes.begin(), itValue = asValue.begin(); itElement != itElementEnd; itElement++, itValue++) { sOut.width(iColumnWidth); sOut.setf(ios_base::left); sOut << (*itElement); sOut << " = "; sOut << (*itValue); if(itElement + 1 != itElementEnd) sOut << endl; } sOut << ends; return sOut.str(); } Integer * IIndexedCollection::FindInteger(const char *s) { return get_symbol_table().findInteger(s); }