void ActionListSwitch::GenerateCaseMap() { Datum& cases = Actions(); Datum::DatumType switchType = Datum::DatumType::UNKNOWN; if (cases.Size() > 0) { delete mCaseMap; mCaseMap = new Hashmap<Datum, ActionListSwitchCase*>(cases.Size()); Datum* conditionDatum = Search((*this)[ATTRIBUTE_SWITCH_VALUE].Get<std::string>()); if (conditionDatum == nullptr) { std::stringstream str; str << "Undefined variable: " << (*this)[ATTRIBUTE_SWITCH_VALUE].Get<std::string>(); throw std::exception(str.str().c_str()); } switchType = conditionDatum->Type(); } for (uint32_t i = 0; i < cases.Size(); i++) { ActionListSwitchCase* switchCase = cases.Get<Scope>(i).As<ActionListSwitchCase>(); if (switchCase == nullptr) continue; if (switchCase->DefaultCase) { Adopt(ActionListSwitchCase::ATTRIBUTE_DEFAULT, *switchCase); } else { Datum d; d.SetType(switchType); d.SetFromString(switchCase->operator[](ActionListSwitchCase::ATTRIBUTE_CASE_VALUE).Get<std::string>()); mCaseMap->Insert(d, switchCase); } } }
//Add a fresh scope with a given name Scope& Scope::AppendScope(const std::string& name) { Datum d; d.SetType(Datum::TABLE); Scope *s = new Scope(10); s->mParent = this; d.Set(s); std::pair <std::string, Datum> newItem(name, d); Hashmap<std::string, Datum>::Iterator newLocation = mHashMap.Insert(newItem); std::pair <std::string, Datum> *itemAdress = &(*newLocation); mOrderVector.PushBack(itemAdress); return *s; }
//Add a scope to our table with a given name and index void Scope::Adopt(Scope* newChild, const std::string& name, std::uint32_t index) { newChild->Orphan(); Hashmap<std::string, Datum>::Iterator it = mHashMap.Find(name); //If the new item isn't present, add it to the hash map if (it == mHashMap.end()) { newChild->mParent = this; Datum d; d.SetType(Datum::TABLE); d.Set(newChild); std::pair <std::string, Datum> newItem(name, d); Hashmap<std::string, Datum>::Iterator newLocation = mHashMap.Insert(newItem); std::pair <std::string, Datum> *itemAdress = &((*newLocation)); mOrderVector.PushBack(itemAdress); } //Otherwise, set the scope item to the given index in the datum else { //Ensure that the datum we're adopting into doesn't have external memory if ((*it).second.IsExternal()) { return; } (*it).second.Set(newChild, index); } }