1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120
|
#include "stdafx.h"
#include "ReplaceContext.h"
#include "ExactPart.h"
#include "Engine.h"
#include "Package.h"
#include "Code.h"
namespace storm {
ReplaceContext::ReplaceContext() {
typeEq = new (this) Map<Type *, Type *>();
}
Bool ReplaceContext::same(Type *a, Type *b) {
return typeEq->get(a, a) == typeEq->get(b, b);
}
Type *ReplaceContext::normalize(Type *t) {
if (t)
return typeEq->get(t, t);
else
return null;
}
Value ReplaceContext::normalize(Value v) {
v.type = typeEq->get(v.type, v.type);
return v;
}
Set<Type *> *ReplaceContext::allNewTypes() {
Set<Type *> *types = new (this) Set<Type *>();
for (Map<Type *, Type *>::Iter i = typeEq->begin(), end = typeEq->end(); i != end; ++i)
types->put(i.k());
return types;
}
void ReplaceContext::buildTypeEquivalence(NameSet *oldRoot, NameSet *newRoot) {
currentOldRoot = oldRoot;
try {
buildTypeEqRec(oldRoot, newRoot);
currentOldRoot = null;
} catch (...) {
currentOldRoot = null;
throw;
}
}
void ReplaceContext::addEquivalence(Type *oldType, Type *newType) {
typeEq->put(newType, oldType);
if (currentOldRoot) {
buildTypeEqRec(oldType, newType);
}
}
void ReplaceContext::buildTypeEqRec(NameSet *currOld, NameSet *currNew) {
currNew->forceLoad();
for (NameSet::Iter i = currNew->begin(), end = currNew->end(); i != end; ++i) {
Named *newEntity = i.v();
// Try to find a matching old entity:
ExactPart *p = new (this) ExactPart(newEntity->name, resolveParams(currentOldRoot, newEntity->params));
Named *oldEntity = currOld->find(p, Scope());
if (!oldEntity)
continue;
// Ask the entity to find mark all equivalent types.
newEntity->findEquivalentTypes(oldEntity, this);
}
}
Array<Value> *ReplaceContext::resolveParams(NameSet *root, Array<Value> *params) {
if (params->empty())
return params;
params = new (this) Array<Value>(*params);
for (Nat i = 0; i < params->count(); i++)
params->at(i) = resolveParam(root, params->at(i));
return params;
}
Value ReplaceContext::resolveParam(NameSet *root, Value param) {
if (param == Value())
return param;
// Do we know of this parameter already?
if (Type *t = typeEq->get(param.type, null)) {
param.type = t;
return t;
}
// No, we need to look it up ourselves. It has probably not been processed yet.
Array<Named *> *prev = new (this) Array<Named *>();
Named *current = param.type;
while (current && current == root) {
prev->push(current);
current = as<Named>(current->parent());
}
NameSet *back = as<NameSet>(current);
// No luck.
if (!back)
return param;
// Now, try to match each name in 'prev' inside 'root'.
while (prev->any() && back) {
Named *n = prev->last();
ExactPart *p = new (this) ExactPart(n->name, resolveParams(root, n->params));
back = as<NameSet>(back->find(p, Scope(back)));
prev->pop();
}
if (Type *t = as<Type>(back))
param.type = t;
return param;
}
}
|