Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
ObjectExNihilo.cs
1using System;
3using System.Threading.Tasks;
9
11{
16 {
17 private readonly ChunkedList<KeyValuePair<string, ScriptNode>> members;
18 private readonly bool hasWildcards = false;
19 private Dictionary<string, ScriptNode> quick = null;
20 private bool isAsync;
21
29 public ObjectExNihilo(ChunkedList<KeyValuePair<string, ScriptNode>> Members, int Start, int Length, Expression Expression)
30 : this(Members, false, Start,Length, Expression)
31 {
32 }
33
42 public ObjectExNihilo(ChunkedList<KeyValuePair<string, ScriptNode>> Members,
44 : base(Start, Length, Expression)
45 {
46 this.members = Members;
47 this.hasWildcards = HasWildcards;
48
49 foreach (KeyValuePair<string, ScriptNode> P in Members)
50 P.Value?.SetParent(this);
51
52 this.CalcIsAsync();
53 }
54
58 public bool HasWildcards => this.hasWildcards;
59
60 private void CalcIsAsync()
61 {
62 this.isAsync = false;
63
64 foreach (KeyValuePair<string, ScriptNode> P in this.members)
65 {
66 if (P.Value?.IsAsynchronous ?? false)
67 {
68 this.isAsync = true;
69 break;
70 }
71 }
72 }
73
78
83 public override bool IsAsynchronous => this.isAsync;
84
91 {
92 Dictionary<string, IElement> Result = new Dictionary<string, IElement>();
93
94 foreach (KeyValuePair<string, ScriptNode> P in this.members)
95 Result[P.Key] = P.Value.Evaluate(Variables);
96
97 return new ObjectValue(Result);
98 }
99
105 public override async Task<IElement> EvaluateAsync(Variables Variables)
106 {
107 if (!this.isAsync)
108 return this.Evaluate(Variables);
109
110 Dictionary<string, IElement> Result = new Dictionary<string, IElement>();
111
112 foreach (KeyValuePair<string, ScriptNode> P in this.members)
113 Result[P.Key] = await P.Value.EvaluateAsync(Variables);
114
115 return new ObjectValue(Result);
116 }
117
125 public override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
126 {
128 int i, c;
129
130 if (Order == SearchMethod.DepthFirst)
131 {
132 Loop = this.members?.FirstChunk;
133
134 while (!(Loop is null))
135 {
136 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
137 {
138 if (!(Loop[i].Value?.ForAllChildNodes(Callback, State, Order) ?? false))
139 return false;
140 }
141
142 Loop = Loop.Next;
143 }
144 }
145
146 bool RecalcIsAsync = false;
147
148 if (!this.members.Update((ref KeyValuePair<string, ScriptNode> P, out bool Keep) =>
149 {
150 Keep = true;
151
152 ScriptNode Node = P.Value;
153 if (!(Node is null))
154 {
155 bool Result = Callback(Node, out ScriptNode NewNode, State);
156 if (!(NewNode is null))
157 {
158 P = new KeyValuePair<string, ScriptNode>(P.Key, NewNode);
159 NewNode.SetParent(this);
160 Node = NewNode;
161
162 RecalcIsAsync = true;
163 }
164
165 if (!Result || (Order == SearchMethod.TreeOrder && !Node.ForAllChildNodes(Callback, State, Order)))
166 {
167 if (RecalcIsAsync)
168 this.CalcIsAsync();
169
170 return false;
171 }
172 }
173
174 return true;
175 }))
176 {
177 return false;
178 }
179
180 if (RecalcIsAsync)
181 this.CalcIsAsync();
182
183 if (Order == SearchMethod.BreadthFirst)
184 {
185 Loop = this.members?.FirstChunk;
186
187 while (!(Loop is null))
188 {
189 for (i = Loop.Start, c = Loop.Pos; i < c; i++)
190 {
191 if (!(Loop[i].Value?.ForAllChildNodes(Callback, State, Order) ?? false))
192 return false;
193 }
194
195 Loop = Loop.Next;
196 }
197 }
198
199 return true;
200 }
201
203 public override bool Equals(object obj)
204 {
205 if (!(obj is ObjectExNihilo O) ||
206 this.hasWildcards != O.hasWildcards ||
207 !base.Equals(obj))
208 {
209 return false;
210 }
211
212 IEnumerator<KeyValuePair<string, ScriptNode>> e1 = this.members.GetEnumerator();
213 IEnumerator<KeyValuePair<string, ScriptNode>> e2 = O.members.GetEnumerator();
214
215 try
216 {
217 while (true)
218 {
219 bool b1 = e1.MoveNext();
220 bool b2 = e2.MoveNext();
221
222 if (b1 ^ b2)
223 return false;
224
225 if (!b1)
226 return true;
227
228 KeyValuePair<string, ScriptNode> Item1 = e1.Current;
229 KeyValuePair<string, ScriptNode> Item2 = e2.Current;
230
231 if (!Item1.Key.Equals(Item2.Key) ||
232 !Item1.Value.Equals(Item2.Value))
233 {
234 return false;
235 }
236 }
237 }
238 finally
239 {
240 e1.Dispose();
241 e2.Dispose();
242 }
243 }
244
246 public override int GetHashCode()
247 {
248 int Result = base.GetHashCode();
249
250 Result ^= Result << 5 ^ this.hasWildcards.GetHashCode();
251
252 foreach (KeyValuePair<string, ScriptNode> P in this.members)
253 {
254 Result ^= Result << 5 ^ P.Key.GetHashCode();
255 Result ^= Result << 5 ^ P.Value.GetHashCode();
256 }
257
258 return Result;
259 }
260
267 public override PatternMatchResult PatternMatch(IElement CheckAgainst, Dictionary<string, IElement> AlreadyFound)
268 {
269 PatternMatchResult Result;
270
271 if (CheckAgainst.AssociatedObjectValue is IDictionary<string, IElement> Object)
272 {
273 this.CheckQuick();
274
275 if (!this.hasWildcards)
276 {
277 foreach (KeyValuePair<string, IElement> P in Object)
278 {
279 if (!this.quick.ContainsKey(P.Key))
280 return PatternMatchResult.NoMatch;
281 }
282 }
283
284 foreach (KeyValuePair<string, ScriptNode> P in this.members)
285 {
286 if (Object.TryGetValue(P.Key, out IElement E))
287 Result = P.Value.PatternMatch(E, AlreadyFound);
288 else
289 Result = P.Value.PatternMatch(ObjectValue.Null, AlreadyFound);
290
291 if (Result != PatternMatchResult.Match)
292 return Result;
293 }
294 }
295 else if (CheckAgainst.AssociatedObjectValue is IDictionary<string, object> Object2)
296 {
297 this.CheckQuick();
298
299 if (!this.hasWildcards)
300 {
301 foreach (KeyValuePair<string, object> P in Object2)
302 {
303 if (!this.quick.ContainsKey(P.Key))
304 return PatternMatchResult.NoMatch;
305 }
306 }
307
308 foreach (KeyValuePair<string, ScriptNode> P in this.members)
309 {
310 if (Object2.TryGetValue(P.Key, out object E))
311 {
312 if (E is Array A)
313 Result = P.Value.PatternMatch(VectorDefinition.Encapsulate(A, false, this), AlreadyFound);
314 else
315 Result = P.Value.PatternMatch(Expression.Encapsulate(E), AlreadyFound);
316 }
317 else
318 Result = P.Value.PatternMatch(ObjectValue.Null, AlreadyFound);
319
320 if (Result != PatternMatchResult.Match)
321 return Result;
322 }
323 }
324 else if (CheckAgainst.AssociatedObjectValue is IDictionary<string, string> Object3)
325 {
326 this.CheckQuick();
327
328 if (!this.hasWildcards)
329 {
330 foreach (KeyValuePair<string, string> P in Object3)
331 {
332 if (!this.quick.ContainsKey(P.Key))
333 return PatternMatchResult.NoMatch;
334 }
335 }
336
337 foreach (KeyValuePair<string, ScriptNode> P in this.members)
338 {
339 if (Object3.TryGetValue(P.Key, out string s))
340 Result = P.Value.PatternMatch(new StringValue(s), AlreadyFound);
341 else
342 Result = P.Value.PatternMatch(ObjectValue.Null, AlreadyFound);
343
344 if (Result != PatternMatchResult.Match)
345 return Result;
346 }
347 }
348 else
349 return PatternMatchResult.NoMatch;
350
351 return PatternMatchResult.Match;
352 }
353
354 private void CheckQuick()
355 {
356 if (this.quick is null)
357 {
358 Dictionary<string, ScriptNode> Quick = new Dictionary<string, ScriptNode>();
359
360 foreach (KeyValuePair<string, ScriptNode> N in this.members)
361 Quick[N.Key] = N.Value;
362
363 this.quick = Quick;
364 }
365 }
366
367 }
368}
Node referencing a chunk in a ChunkedList<T>
Definition: ChunkNode.cs:11
ChunkNode< T > Next
Next chunk
Definition: ChunkNode.cs:26
int Pos
Index after the last element in chunk.
Definition: ChunkNode.cs:51
int Start
Index of first element in chunk.
Definition: ChunkNode.cs:46
A chunked list is a linked list of chunks of objects of type T .
Definition: ChunkedList.cs:54
Class managing a script expression.
Definition: Expression.cs:41
static IElement Encapsulate(object Value)
Encapsulates an object.
Definition: Expression.cs:5241
Base class for all nodes in a parsed script tree.
Definition: ScriptNode.cs:69
int Length
Length of expression covered by node.
Definition: ScriptNode.cs:101
int Start
Start position in script expression.
Definition: ScriptNode.cs:92
static readonly ObjectValue Null
Null value.
Definition: ObjectValue.cs:88
Creates an object from nothing.
override bool IsAsynchronous
If the node (or its decendants) include asynchronous evaluation. Asynchronous nodes should be evaluat...
ObjectExNihilo(ChunkedList< KeyValuePair< string, ScriptNode > > Members, int Start, int Length, Expression Expression)
Creates an object from nothing.
override bool ForAllChildNodes(ScriptNodeEventHandler Callback, object State, SearchMethod Order)
Calls the callback method for all child nodes.
override bool Equals(object obj)
ChunkedList< KeyValuePair< string, ScriptNode > > Members
Members, in order of definition.
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
bool HasWildcards
If the object definition includes wildcards.
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
override PatternMatchResult PatternMatch(IElement CheckAgainst, Dictionary< string, IElement > AlreadyFound)
Performs a pattern match operation.
ObjectExNihilo(ChunkedList< KeyValuePair< string, ScriptNode > > Members, bool HasWildcards, int Start, int Length, Expression Expression)
Creates an object from nothing.
static IElement Encapsulate(Array Elements, bool CanEncapsulateAsMatrix, ScriptNode Node)
Encapsulates the elements of a vector.
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:21
object AssociatedObjectValue
Associated object value.
Definition: IElement.cs:34
delegate bool ScriptNodeEventHandler(ScriptNode Node, out ScriptNode NewNode, object State)
Delegate for ScriptNode callback methods.
PatternMatchResult
Status result of a pattern matching operation.
Definition: ScriptNode.cs:17
SearchMethod
Method to traverse the expression structure
Definition: ScriptNode.cs:38