File: NameSet.h

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 (300 lines) | stat: -rw-r--r-- 9,453 bytes parent folder | download | duplicates (2)
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
#pragma once
#include "Named.h"
#include "Template.h"
#include "Core/Array.h"
#include "Core/Map.h"

namespace storm {
	STORM_PKG(core.lang);

	class NameSet;

	/**
	 * Interface receiving differences between two NameSets.
	 *
	 * Not intended to be used from Storm; only intended for reload internals.
	 */
	class NameDiff {
	public:
		// Called for each entity that was added.
		virtual void added(Named *item) = 0;
		virtual void added(Template *item) = 0;

		// Called for each entity that was removed.
		virtual void removed(Named *item) = 0;
		virtual void removed(Template *item) = 0;

		// Called for each entity that exists in both versions. Note: We can't diff templates, so
		// they are never treated as being 'equal'.
		virtual void changed(Named *old, Named *changed) = 0;
	};

	/**
	 * A set of named objects, all with the same name but with different parameters.
	 */
	class NameOverloads : public ObjectOn<Compiler> {
		STORM_CLASS;
	public:
		// Create.
		STORM_CTOR NameOverloads();

		// Is this instance empty? (ie. not even any template?)
		Bool STORM_FN empty() const;

		// Get the number of items in here. Note: May return 0 even if 'empty' returns false.
		Nat STORM_FN count() const;

		// Get item #n in here.
		Named *STORM_FN operator [](Nat id) const;
		Named *at(Nat id) const;

		// Check if an element is in here.
		MAYBE(Named *) STORM_FN has(Named *item);

		// Add an element.
		void STORM_FN add(Named *item);

		// Add a template.
		void STORM_FN add(Template *item);

		// Remove an element. Returns true on success.
		Bool STORM_FN remove(Named *item);

		// Remove a template. Returns true on success.
		Bool STORM_FN remove(Template *item);

		// Merge from another NameOverloads.
		void STORM_FN merge(NameOverloads *from);

		// Diff in various situations.
		void diff(NameOverloads *with, NameDiff &callback, ReplaceContext *ctx);
		void diffAdded(NameDiff &callback);
		void diffRemoved(NameDiff &callback);
		void diffTemplatesAdded(NameDiff &callback);
		void diffTemplatesRemoved(NameDiff &callback);

		// Does this object contain any templates?
		Bool STORM_FN anyTemplates() const;

		// Generate a matching template. Does *not* add it to this object.
		// TODO: More care should be taking when dealing with templates and overload resolution!
		MAYBE(Named *) STORM_FN createTemplate(NameSet *owner, SimplePart *from, Scope source);

		// To string.
		virtual void STORM_FN toS(StrBuf *to) const;

	private:
		// All named items.
		Array<Named *> *items;

		// Templates with this name. Might be null.
		Array<Template *> *templates;
	};

	/**
	 * A named object containing other named objects. Used for building recursive trees inside the
	 * compiler.
	 *
	 * Implements support for lazy-loading. At creation, the NameSet assumes there is some amount of
	 * content that can be loaded on demand. When someone tries to access the content in the
	 * NameSet, it tries to load as little as possible while still determining if the content exists.
	 *
	 * Lazy-loading happens in two steps:
	 * 1: The NameSet asks the derived class to load a specific Name that does not yet exist.
	 * 2: The NameSet asks the derived class to load all content.
	 *
	 * The first step does not need to be implemented, while the second step is mandatory. As soon
	 * as #2 has been called, the NameSet assumes that all content is loaded, and will therefore
	 * never call #1 again. Pay attention if you implement both, that #2 may not load things that #1
	 * have previously loaded.
	 *
	 * Content can of course be added eagerly by calling 'add'. This does not affect the
	 * lazy-loading process in any way.
	 */
	class NameSet : public Named {
		STORM_CLASS;
	public:
		// Create.
		STORM_CTOR NameSet(Str *name);
		STORM_CTOR NameSet(Str *name, Array<Value> *params);
		STORM_CTOR NameSet(SrcPos pos, Str *name);
		STORM_CTOR NameSet(SrcPos pos, Str *name, Array<Value> *params);

		// Check if this name set has a Named with the exact parameters as the provided
		// entity. I.e., would it be possible to store 'item' here without issues?
		virtual MAYBE(Named *) STORM_FN has(Named *item) const;

		// Add a named object.
		virtual void STORM_FN add(Named *item);

		// Add a template.
		virtual void STORM_FN add(Template *item);

		// Remove a named object from here.
		virtual Bool STORM_FN remove(Named *item);

		// Remove a template from here.
		virtual Bool STORM_FN remove(Template *item);

		// Get an anonymous name for this NameSet.
		virtual Str *STORM_FN anonName();

		// Get all members.
		virtual Array<Named *> *STORM_FN content();

		// Find all entities that might be generated by a template.
		Array<NameOverloads *> *STORM_FN templateOverloads();

		// Find all overloads for a particular name.
		MAYBE(NameOverloads *) STORM_FN allOverloads(Str *name);

		// Force loading this NameSet.
		void STORM_FN forceLoad();

		// Find a named entity in the name set. Overloads the `find` function in `NameLookup`.
		virtual MAYBE(Named *) STORM_FN find(SimplePart *part, Scope source);
		using Named::find;

		// Watch this NameSet for new additions.
		virtual void STORM_FN watchAdd(Named *notifyTo);

		// Remove a previously added watch.
		virtual void STORM_FN watchRemove(Named *notifyTo);

		// Output.
		virtual void STORM_FN toS(StrBuf *to) const;

		// Late initialization.
		virtual void lateInit();

		// Force compilation.
		virtual void STORM_FN compile();

		// Discard source information.
		virtual void STORM_FN discardSource();

		// Iterator. TODO: How to do wrt threading?
		class Iter {
			STORM_VALUE;
			friend class NameSet;
		public:
			// Create an iterator pointing to the end.
			STORM_CTOR Iter();

			// Compare.
			Bool STORM_FN operator ==(const Iter &o) const;
			Bool STORM_FN operator !=(const Iter &o) const;

			// Get the value.
			Named *STORM_FN v() const;

			// Increment.
			Iter &STORM_FN operator ++();
			Iter STORM_FN operator ++(int d);

		private:
			// Create an iterator to the start.
			Iter(Map<Str *, NameOverloads *> *c, NameSet *next);

			// Current position in the map.
			typedef Map<Str *, NameOverloads *>::Iter MapIter;
			UNKNOWN(MapBase::Iter) MapIter name;

			// Next NameSet to visit (if any).
			MAYBE(NameSet *) nextSet;

			// Current position in NameOverloads at 'pos'.
			Nat pos;

			// Advance 'name' until we find something!
			void advance();
		};

		// Get iterators to the begin and end of the contents.
		virtual Iter STORM_FN begin() const;
		virtual Iter STORM_FN end() const;

		// Get all overloads for a specific name.
		Array<Named *> *STORM_FN findName(Str *name) const;

		// Dump the internal contents of the NameSet for debugging.
		void dbg_dump() const;

	protected:
		/**
		 * Lazy-loading callbacks.
		 */

		// Attempt to load a single missing name. Assumed to call `add()` on one or more candidates
		// for `part`, and then return true. It is acceptable to add no candidates and return `true`,
		// which is interpreted as `no matches can be lazy-loaded`. If there may be candidates, but
		// none can be loaded from here, return `false`. This causes `loadAll` to be called instead.
		virtual Bool STORM_FN loadName(SimplePart *part);

		// Called when we need to load all content. Assumed to call `add()` on all entities. Returns
		// false or throws an exception on failure. Failure will re-try loading at a later time.
		virtual Bool STORM_FN loadAll();

		// Check if this `NameSet` is loaded fully.
		inline Bool STORM_FN allLoaded() const { return loaded; }

		// Find a name part in this `NameSet`, but do not perform lazy-loading.
		MAYBE(Named *) STORM_FN tryFind(SimplePart *part, Scope source);

		// Find a named in the NameSet. Use the SimplePart to determine which one to choose, and how
		// to respect visibility.
		MAYBE(Named *) STORM_FN tryFind(SimplePart *part, Scope source, NameOverloads *from);


		// Find a name in the NameSet. Use the SimplePart to determine which to choose. Only
		// examines one level of NameParts.
		MAYBE(Named *) STORM_FN tryFindSingle(SimplePart *part, Scope source, NameOverloads *from);

		// Get an iterator that visits another name set after the current one.
		Iter STORM_FN begin(NameSet *after) const;

		// Import entities from another NameSet.
		void STORM_FN merge(NameSet *from);

		// Find differences between two NameSets. For terminology, assumes that 'with' is the "new" version.
		// If 'ctx' is not null, it is used to resolve equivalences between new and old trees.
		void diff(NameSet *with, NameDiff &callback, ReplaceContext *ctx);

		// Stop auto-discarding source when items are added. This effectively undoes what
		// `discardSource` does, but it only applies for newly added entities.
		void STORM_FN stopDiscardSource();

	private:
		// Overloads.
		typedef Map<Str *, NameOverloads *> Overloads;
		Map<Str *, NameOverloads *> *overloads;

		// Lazy-loading done?
		Bool loaded;

		// Lazy-loading in progress?
		Bool loading;

		// Asked to discard sources?
		Bool sourceDiscarded;

		// Identifier for the next anonymous thing.
		Nat nextAnon;

		// Initialize.
		void init();

		// Recursive helper to the public function.
		void templateOverloads(Array<NameOverloads *> *result);

		// All Named object who want notifications from us. May be null.
		WeakSet<Named> *notify;

		// Notify something has been added.
		void notifyAdd(Named *what);

		// Notify something has been removed.
		void notifyRemove(Named *what);
	};

}