Neuron®
The Neuron® is the basis for the creation of open and secure federated networks for smart societies.
Loading...
Searching...
No Matches
FunctionTwoScalarVariables.cs
1using System.Collections.Generic;
2using System.Numerics;
3using System.Threading.Tasks;
8
9namespace Waher.Script.Model
10{
15 {
26 {
27 }
28
37 {
38 if (Argument1.IsScalar)
39 {
40 if (Argument2.IsScalar)
41 {
42 ISet Set1 = Argument1.AssociatedSet;
43 ISet Set2 = Argument2.AssociatedSet;
44
45 if (Set1 != Set2)
46 {
47 if (!Expression.UpgradeField(ref Argument1, ref Set1, ref Argument2, ref Set2))
48 return this.EvaluateScalar(Argument1, Argument2, Variables);
49 }
50
51 object x = Argument1.AssociatedObjectValue;
52 object y = Argument2.AssociatedObjectValue;
53
54 if (x is double xd && y is double yd)
55 return this.EvaluateScalar(xd, yd, Variables);
56
57 if (x is Complex xz && y is Complex yz)
58 return this.EvaluateScalar(xz, yz, Variables);
59
60 if (x is bool xb && y is bool yb)
61 return this.EvaluateScalar(xb, yb, Variables);
62
63 if (x is string xs && y is string ys)
64 return this.EvaluateScalar(xs, ys, Variables);
65
66 double arg1, arg2;
67
68 if (x is double xd2)
69 arg1 = xd2;
70 else
71 {
72 if (x is IPhysicalQuantity Q1)
73 arg1 = Q1.ToPhysicalQuantity().Magnitude;
74 else
75 return this.EvaluateScalar(Argument1, Argument2, Variables);
76 }
77
78 if (y is double yd2)
79 arg2 = yd2;
80 else
81 {
82 if (y is IPhysicalQuantity Q2)
83 arg2 = Q2.ToPhysicalQuantity().Magnitude;
84 else
85 return this.EvaluateScalar(Argument1, Argument2, Variables);
86 }
87
88 return this.EvaluateScalar(arg1, arg2, Variables);
89 }
90 else
91 {
92 LinkedList<IElement> Elements = new LinkedList<IElement>();
93
94 foreach (IElement E in Argument2.ChildElements)
95 Elements.AddLast(this.Evaluate(Argument1, E, Variables));
96
97 return Argument2.Encapsulate(Elements, this);
98 }
99 }
100 else
101 {
102 if (Argument2.IsScalar)
103 {
104 LinkedList<IElement> Elements = new LinkedList<IElement>();
105
106 foreach (IElement E in Argument1.ChildElements)
107 Elements.AddLast(this.Evaluate(E, Argument2, Variables));
108
109 return Argument1.Encapsulate(Elements, this);
110 }
111 else
112 {
113 ICollection<IElement> Argument1Children = Argument1.ChildElements;
114 ICollection<IElement> Argument2Children = Argument2.ChildElements;
115
116 if (Argument1Children.Count == Argument2Children.Count)
117 {
118 LinkedList<IElement> Elements = new LinkedList<IElement>();
119 IEnumerator<IElement> eArgument1 = Argument1Children.GetEnumerator();
120 IEnumerator<IElement> eArgument2 = Argument2Children.GetEnumerator();
121
122 try
123 {
124 while (eArgument1.MoveNext() && eArgument2.MoveNext())
125 Elements.AddLast(this.Evaluate(eArgument1.Current, eArgument2.Current, Variables));
126 }
127 finally
128 {
129 eArgument1.Dispose();
130 eArgument2.Dispose();
131 }
132
133 return Argument1.Encapsulate(Elements, this);
134 }
135 else
136 {
137 LinkedList<IElement> Argument1Result = new LinkedList<IElement>();
138
139 foreach (IElement Argument1Child in Argument1Children)
140 {
141 LinkedList<IElement> Argument2Result = new LinkedList<IElement>();
142
143 foreach (IElement Argument2Child in Argument2Children)
144 Argument2Result.AddLast(this.Evaluate(Argument1Child, Argument2Child, Variables));
145
146 Argument1Result.AddLast(Argument2.Encapsulate(Argument2Result, this));
147 }
148
149 return Argument1.Encapsulate(Argument1Result, this);
150 }
151 }
152 }
153 }
154
163 {
164 object v1 = Argument1.AssociatedObjectValue;
165 object v2 = Argument2.AssociatedObjectValue;
166
167 if (Expression.TryConvert(v1, out string s1) && Expression.TryConvert(v2, out string s2))
168 return this.EvaluateScalar(s1, s2, Variables);
169 else if (Expression.TryConvert(v1, out double d1) && Expression.TryConvert(v2, out double d2))
170 return this.EvaluateScalar(d1, d2, Variables);
171 else if (Expression.TryConvert(v1, out bool b1) && Expression.TryConvert(v2, out bool b2))
172 return this.EvaluateScalar(b1, b2, Variables);
173 else if (Expression.TryConvert(v1, out Complex z1) && Expression.TryConvert(v2, out Complex z2))
174 return this.EvaluateScalar(z1, z2, Variables);
175 else if (Expression.TryConvert(v1, out Integer i1) && Expression.TryConvert(v2, out Integer i2))
176 return this.EvaluateScalar((double)i1.Value, (double)i2.Value, Variables);
177 else if (Expression.TryConvert(v1, out RationalNumber q1) && Expression.TryConvert(v2, out RationalNumber q2))
178 return this.EvaluateScalar(q1.ToDouble(), q2.ToDouble(), Variables);
179 else
180 throw new ScriptRuntimeException("Type of scalar not supported.", this);
181 }
182
191 {
192 throw new ScriptRuntimeException("Double-valued arguments not supported.", this);
193 }
194
203 {
204 throw new ScriptRuntimeException("Complex-valued arguments not supported.", this);
205 }
206
215 {
216 throw new ScriptRuntimeException("Boolean-valued arguments not supported.", this);
217 }
218
227 {
228 throw new ScriptRuntimeException("String-valued arguments not supported.", this);
229 }
230
238 public override async Task<IElement> EvaluateAsync(IElement Argument1, IElement Argument2, Variables Variables)
239 {
240 if (Argument1.IsScalar)
241 {
242 if (Argument2.IsScalar)
243 {
244 ISet Set1 = Argument1.AssociatedSet;
245 ISet Set2 = Argument2.AssociatedSet;
246
247 if (Set1 != Set2)
248 {
249 if (!Expression.UpgradeField(ref Argument1, ref Set1, ref Argument2, ref Set2))
250 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
251 }
252
253 object x = Argument1.AssociatedObjectValue;
254 object y = Argument2.AssociatedObjectValue;
255
256 if (x is double xd && y is double yd)
257 return await this.EvaluateScalarAsync(xd, yd, Variables);
258
259 if (x is Complex xz && y is Complex yz)
260 return await this.EvaluateScalarAsync(xz, yz, Variables);
261
262 if (x is bool xb && y is bool yb)
263 return await this.EvaluateScalarAsync(xb, yb, Variables);
264
265 if (x is string xs && y is string ys)
266 return await this.EvaluateScalarAsync(xs, ys, Variables);
267
268 double arg1, arg2;
269
270 if (x is double xd2)
271 arg1 = xd2;
272 else
273 {
274 if (x is IPhysicalQuantity Q1)
275 arg1 = Q1.ToPhysicalQuantity().Magnitude;
276 else
277 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
278 }
279
280 if (y is double yd2)
281 arg2 = yd2;
282 else
283 {
284 if (y is IPhysicalQuantity Q2)
285 arg2 = Q2.ToPhysicalQuantity().Magnitude;
286 else
287 return await this.EvaluateScalarAsync(Argument1, Argument2, Variables);
288 }
289
290 return await this.EvaluateScalarAsync(arg1, arg2, Variables);
291 }
292 else
293 {
294 LinkedList<IElement> Elements = new LinkedList<IElement>();
295
296 foreach (IElement E in Argument2.ChildElements)
297 Elements.AddLast(await this.EvaluateAsync(Argument1, E, Variables));
298
299 return Argument2.Encapsulate(Elements, this);
300 }
301 }
302 else
303 {
304 if (Argument2.IsScalar)
305 {
306 LinkedList<IElement> Elements = new LinkedList<IElement>();
307
308 foreach (IElement E in Argument1.ChildElements)
309 Elements.AddLast(await this.EvaluateAsync(E, Argument2, Variables));
310
311 return Argument1.Encapsulate(Elements, this);
312 }
313 else
314 {
315 ICollection<IElement> Argument1Children = Argument1.ChildElements;
316 ICollection<IElement> Argument2Children = Argument2.ChildElements;
317
318 if (Argument1Children.Count == Argument2Children.Count)
319 {
320 LinkedList<IElement> Elements = new LinkedList<IElement>();
321 IEnumerator<IElement> eArgument1 = Argument1Children.GetEnumerator();
322 IEnumerator<IElement> eArgument2 = Argument2Children.GetEnumerator();
323
324 try
325 {
326 while (eArgument1.MoveNext() && eArgument2.MoveNext())
327 Elements.AddLast(await this.EvaluateAsync(eArgument1.Current, eArgument2.Current, Variables));
328 }
329 finally
330 {
331 eArgument1.Dispose();
332 eArgument2.Dispose();
333 }
334
335 return Argument1.Encapsulate(Elements, this);
336 }
337 else
338 {
339 LinkedList<IElement> Argument1Result = new LinkedList<IElement>();
340
341 foreach (IElement Argument1Child in Argument1Children)
342 {
343 LinkedList<IElement> Argument2Result = new LinkedList<IElement>();
344
345 foreach (IElement Argument2Child in Argument2Children)
346 Argument2Result.AddLast(await this.EvaluateAsync(Argument1Child, Argument2Child, Variables));
347
348 Argument1Result.AddLast(Argument2.Encapsulate(Argument2Result, this));
349 }
350
351 return Argument1.Encapsulate(Argument1Result, this);
352 }
353 }
354 }
355 }
356
365 {
366 object v1 = Argument1.AssociatedObjectValue;
367 object v2 = Argument2.AssociatedObjectValue;
368
369 if (Expression.TryConvert(v1, out string s1) && Expression.TryConvert(v2, out string s2))
370 return this.EvaluateScalarAsync(s1, s2, Variables);
371 else if (Expression.TryConvert(v1, out double d1) && Expression.TryConvert(v2, out double d2))
372 return this.EvaluateScalarAsync(d1, d2, Variables);
373 else if (Expression.TryConvert(v1, out bool b1) && Expression.TryConvert(v2, out bool b2))
374 return this.EvaluateScalarAsync(b1, b2, Variables);
375 else if (Expression.TryConvert(v1, out Complex z1) && Expression.TryConvert(v2, out Complex z2))
376 return this.EvaluateScalarAsync(z1, z2, Variables);
377 else if (Expression.TryConvert(v1, out Integer i1) && Expression.TryConvert(v2, out Integer i2))
378 return this.EvaluateScalarAsync((double)i1.Value, (double)i2.Value, Variables);
379 else if (Expression.TryConvert(v1, out RationalNumber q1) && Expression.TryConvert(v2, out RationalNumber q2))
380 return this.EvaluateScalarAsync(q1.ToDouble(), q2.ToDouble(), Variables);
381 else
382 throw new ScriptRuntimeException("Type of scalar not supported.", this);
383 }
384
392 public virtual Task<IElement> EvaluateScalarAsync(double Argument1, double Argument2, Variables Variables)
393 {
394 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
395 }
396
404 public virtual Task<IElement> EvaluateScalarAsync(Complex Argument1, Complex Argument2, Variables Variables)
405 {
406 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
407 }
408
416 public virtual Task<IElement> EvaluateScalarAsync(bool Argument1, bool Argument2, Variables Variables)
417 {
418 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
419 }
420
428 public virtual Task<IElement> EvaluateScalarAsync(string Argument1, string Argument2, Variables Variables)
429 {
430 return Task.FromResult(this.EvaluateScalar(Argument1, Argument2, Variables));
431 }
432
433 }
434}
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
static bool TryConvert(object Value, Type DesiredType, out object Result)
Tries to convert an object Value to an object of type DesiredType .
Definition: Expression.cs:5268
Base class for funcions of two scalar variables.
virtual Task< IElement > EvaluateScalarAsync(double Argument1, double Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(double Argument1, double Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(Complex Argument1, Complex Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(string Argument1, string Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(bool Argument1, bool Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual Task< IElement > EvaluateScalarAsync(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
override async Task< IElement > EvaluateAsync(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function.
override IElement Evaluate(IElement Argument1, IElement Argument2, Variables Variables)
Evaluates the function.
virtual IElement EvaluateScalar(bool Argument1, bool Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
virtual IElement EvaluateScalar(string Argument1, string Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
FunctionTwoScalarVariables(ScriptNode Argument1, ScriptNode Argument2, int Start, int Length, Expression Expression)
Base class for funcions of one scalar variable.
virtual Task< IElement > EvaluateScalarAsync(Complex Argument1, Complex Argument2, Variables Variables)
Evaluates the function on two scalar arguments.
Base class for funcions of one variable.
ScriptNode Argument2
Function argument 2.
ScriptNode Argument1
Function argument 1.
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
Integer-valued number.
Definition: Integer.cs:13
Collection of variables.
Definition: Variables.cs:25
Basic interface for all types of elements.
Definition: IElement.cs:20
Basic interface for all types of sets.
Definition: ISet.cs:10
Interface for objects that can be represented as a physical quantity.