bool isSubtypeOf(const Type& a, const Type& b) { // make sure they are both in the same environment auto& environment = a.getTypeEnvironment(); assert(environment.isType(a) && environment.isType(b)); // first check - a type is a sub-type of itself if (a == b) return true; // check for predefined types if (b == environment.getNumberType()) return isNumberType(a); if (b == environment.getSymbolType()) return isSymbolType(a); // check primitive type chains if (isA<PrimitiveType>(a)) { if (isSubtypeOf(as<PrimitiveType>(a).getBaseType(), b)){ return true; } } // next - if b is a union type if (isUnion(b)) { return isSubType(a, as<UnionType>(b)); } // done return false; }
// Adds a subtype to the list, and associated it with a parent type. //The association can happen only once, a subtype is then definitely associated to its parent type. // If you associate "goblin" to "creature", trying to associate "goblin" to "land" afterwards will fail. "goblin" will stay associated to its first parent. int Subtypes::add(string value, unsigned int parentType) { unsigned int subtype = find(value); if (parentType && isSubType(subtype)) { if ((unsigned int)(subtypesToType.size()) < subtype + 1) subtypesToType.resize(1 + subtype * 2, 0); //multiplying by 2 to avoid resizing at every insertion subtypesToType[subtype] = parentType; } if (isSubType(subtype) && (parentType == TYPE_CREATURE)) { if(value != "forest" && value != "Forest")//http://gatherer.wizards.com/Pages/Card/Details.aspx?multiverseid=136196 one creature with a land subtype exist, but the card has special ruling. subtypesCreature.push_back(value); } return subtype; }