File: ReplaceContext.cpp

package info (click to toggle)
storm-lang 0.7.4-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 52,004 kB
  • sloc: ansic: 261,462; cpp: 140,405; sh: 14,891; perl: 9,846; python: 2,525; lisp: 2,504; asm: 860; makefile: 678; pascal: 70; java: 52; xml: 37; awk: 12
file content (120 lines) | stat: -rw-r--r-- 2,979 bytes parent folder | download
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;
	}

}