Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
BinaryVectorOperator.cs
1using System;
2using System.Collections.Generic;
3using System.Threading.Tasks;
7
8namespace Waher.Script.Model
9{
13 public abstract class BinaryVectorOperator : BinaryOperator
14 {
24 : base(Left, Right, Start, Length, Expression)
25 {
26 }
27
34 {
35 IElement Left = this.left.Evaluate(Variables);
36 IElement Right = this.right.Evaluate(Variables);
37
38 return this.Evaluate(Left, Right, Variables);
39 }
40
46 public override async Task<IElement> EvaluateAsync(Variables Variables)
47 {
48 if (!this.isAsync)
49 return this.Evaluate(Variables);
50
51 IElement Left = await this.left.EvaluateAsync(Variables);
52 IElement Right = await this.right.EvaluateAsync(Variables);
53
54 return await this.EvaluateAsync(Left, Right, Variables);
55 }
56
65 {
66 if (Left is IVector VL)
67 {
68 if (Right is IVector VR)
69 {
70 ISet LeftSet = Left.AssociatedSet;
71 ISet RightSet = Right.AssociatedSet;
73
74 if (!LeftSet.Equals(RightSet) && (UpgradeBehaviour = this.ScalarUpgradeBehaviour) != UpgradeBehaviour.DifferentTypesOk)
75 {
76 if (!Expression.UpgradeField(ref Left, ref LeftSet, ref Right, ref RightSet))
77 {
78 if (UpgradeBehaviour == UpgradeBehaviour.SameTypeRequired)
79 throw new ScriptRuntimeException("Incompatible operands.", this);
80 }
81 }
82
83 return this.EvaluateVector(VL, VR, Variables);
84 }
85 else
86 {
87 LinkedList<IElement> Result = new LinkedList<IElement>();
88
89 foreach (IElement RightChild in Right.ChildElements)
90 Result.AddLast(this.Evaluate(Left, RightChild, Variables));
91
92 return Right.Encapsulate(Result, this);
93 }
94 }
95 else
96 {
97 if (Right is IVector)
98 {
99 LinkedList<IElement> Result = new LinkedList<IElement>();
100
101 foreach (IElement LeftChild in Left.ChildElements)
102 Result.AddLast(this.Evaluate(LeftChild, Right, Variables));
103
104 return Left.Encapsulate(Result, this);
105 }
106 else
107 {
108 ICollection<IElement> LeftChildren = Left.ChildElements;
109 ICollection<IElement> RightChildren = Right.ChildElements;
110
111 if (LeftChildren.Count == RightChildren.Count)
112 {
113 LinkedList<IElement> Result = new LinkedList<IElement>();
114 IEnumerator<IElement> eLeft = LeftChildren.GetEnumerator();
115 IEnumerator<IElement> eRight = RightChildren.GetEnumerator();
116
117 try
118 {
119 while (eLeft.MoveNext() && eRight.MoveNext())
120 Result.AddLast(this.Evaluate(eLeft.Current, eRight.Current, Variables));
121 }
122 finally
123 {
124 eLeft.Dispose();
125 eRight.Dispose();
126 }
127
128 return Left.Encapsulate(Result, this);
129 }
130 else
131 {
132 LinkedList<IElement> LeftResult = new LinkedList<IElement>();
133
134 foreach (IElement LeftChild in LeftChildren)
135 {
136 LinkedList<IElement> RightResult = new LinkedList<IElement>();
137
138 foreach (IElement RightChild in RightChildren)
139 RightResult.AddLast(this.Evaluate(LeftChild, RightChild, Variables));
140
141 LeftResult.AddLast(Right.Encapsulate(RightResult, this));
142 }
143
144 return Left.Encapsulate(LeftResult, this);
145 }
146 }
147 }
148 }
149
157 public virtual async Task<IElement> EvaluateAsync(IElement Left, IElement Right, Variables Variables)
158 {
159 if (Left is IVector VL)
160 {
161 if (Right is IVector VR)
162 {
163 ISet LeftSet = Left.AssociatedSet;
164 ISet RightSet = Right.AssociatedSet;
166
167 if (!LeftSet.Equals(RightSet) && (UpgradeBehaviour = this.ScalarUpgradeBehaviour) != UpgradeBehaviour.DifferentTypesOk)
168 {
169 if (!Expression.UpgradeField(ref Left, ref LeftSet, ref Right, ref RightSet))
170 {
171 if (UpgradeBehaviour == UpgradeBehaviour.SameTypeRequired)
172 throw new ScriptRuntimeException("Incompatible operands.", this);
173 }
174 }
175
176 return await this.EvaluateVectorAsync(VL, VR, Variables);
177 }
178 else
179 {
180 LinkedList<IElement> Result = new LinkedList<IElement>();
181
182 foreach (IElement RightChild in Right.ChildElements)
183 Result.AddLast(await this.EvaluateAsync(Left, RightChild, Variables));
184
185 return Right.Encapsulate(Result, this);
186 }
187 }
188 else
189 {
190 if (Right is IVector)
191 {
192 LinkedList<IElement> Result = new LinkedList<IElement>();
193
194 foreach (IElement LeftChild in Left.ChildElements)
195 Result.AddLast(await this.EvaluateAsync(LeftChild, Right, Variables));
196
197 return Left.Encapsulate(Result, this);
198 }
199 else
200 {
201 ICollection<IElement> LeftChildren = Left.ChildElements;
202 ICollection<IElement> RightChildren = Right.ChildElements;
203
204 if (LeftChildren.Count == RightChildren.Count)
205 {
206 LinkedList<IElement> Result = new LinkedList<IElement>();
207 IEnumerator<IElement> eLeft = LeftChildren.GetEnumerator();
208 IEnumerator<IElement> eRight = RightChildren.GetEnumerator();
209
210 try
211 {
212 while (eLeft.MoveNext() && eRight.MoveNext())
213 Result.AddLast(await this.EvaluateAsync(eLeft.Current, eRight.Current, Variables));
214 }
215 finally
216 {
217 eLeft.Dispose();
218 eRight.Dispose();
219 }
220
221 return Left.Encapsulate(Result, this);
222 }
223 else
224 {
225 LinkedList<IElement> LeftResult = new LinkedList<IElement>();
226
227 foreach (IElement LeftChild in LeftChildren)
228 {
229 LinkedList<IElement> RightResult = new LinkedList<IElement>();
230
231 foreach (IElement RightChild in RightChildren)
232 RightResult.AddLast(await this.EvaluateAsync(LeftChild, RightChild, Variables));
233
234 LeftResult.AddLast(Right.Encapsulate(RightResult, this));
235 }
236
237 return Left.Encapsulate(LeftResult, this);
238 }
239 }
240 }
241 }
242
251
259 public virtual Task<IElement> EvaluateVectorAsync(IVector Left, IVector Right, Variables Variables)
260 {
261 return Task.FromResult<IElement>(this.EvaluateVector(Left, Right, Variables));
262 }
263
267 public virtual UpgradeBehaviour ScalarUpgradeBehaviour => UpgradeBehaviour.SameTypeRequired;
268 }
269}
Class managing a script expression.
Definition: Expression.cs:39
static bool UpgradeField(ref IElement E1, ref ISet Set1, ref IElement E2, ref ISet Set2)
Upgrades elements if necessary, to a common field extension, trying to make them compatible.
Definition: Expression.cs:5070
Base class for all binary operators.
ScriptNode right
Right operand.
ScriptNode left
Left operand.
bool isAsync
If subtree is asynchroneous.
Base class for binary vector operators.
override IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
virtual UpgradeBehaviour ScalarUpgradeBehaviour
How scalar operands of different types are to be treated. By default, scalar operands are required to...
virtual Task< IElement > EvaluateVectorAsync(IVector Left, IVector Right, Variables Variables)
Evaluates the operator on vector operands.
override async Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection.
BinaryVectorOperator(ScriptNode Left, ScriptNode Right, int Start, int Length, Expression Expression)
Base class for binary vector operators.
virtual IElement Evaluate(IElement Left, IElement Right, Variables Variables)
Evaluates the operator.
abstract IElement EvaluateVector(IVector Left, IVector Right, Variables Variables)
Evaluates the operator on vector operands.
virtual async Task< IElement > EvaluateAsync(IElement Left, IElement Right, Variables Variables)
Evaluates the operator.
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
abstract IElement Evaluate(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
virtual Task< IElement > EvaluateAsync(Variables Variables)
Evaluates the node, using the variables provided in the Variables collection. This method should be ...
Definition: ScriptNode.cs:158
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:20
ICollection< IElement > ChildElements
An enumeration of child elements. If the element is a scalar, this property will return null.
Definition: IElement.cs:49
IElement Encapsulate(ICollection< IElement > Elements, ScriptNode Node)
Encapsulates a set of elements into a similar structure as that provided by the current element.
Basic interface for vectors.
Definition: IVector.cs:9
Basic interface for all types of sets.
Definition: ISet.cs:10
UpgradeBehaviour
How operands are to be handled if not of the same type.