private object EvaluateBinaryExpression(ScriptBinaryExpression expression, ScriptDate left, ScriptDate right) { switch (expression.Operator) { case ScriptBinaryOperator.Substract: return(new ScriptTimeSpan(left.value - right.value)); case ScriptBinaryOperator.CompareEqual: return(left.value == right.value); case ScriptBinaryOperator.CompareNotEqual: return(left.value != right.value); case ScriptBinaryOperator.CompareLess: return(left.value < right.value); case ScriptBinaryOperator.CompareLessOrEqual: return(left.value <= right.value); case ScriptBinaryOperator.CompareGreater: return(left.value > right.value); case ScriptBinaryOperator.CompareGreaterOrEqual: return(left.value >= right.value); } throw new ScriptRuntimeException(expression.Span, $"Operator [{expression.Operator}] is not supported for timespan"); }
public override object Evaluate(TemplateContext context) { var increment = this.Operator == ScriptUnaryOperator.Increment ? 1 : -1; var value = Evaluate(context, this.Right.Span, ScriptUnaryOperator.Plus, context.Evaluate(this.Right)); var incrementedValue = ScriptBinaryExpression.Evaluate(context, this.Right.Span, ScriptBinaryOperator.Add, value, increment); context.SetValue(Right, incrementedValue); return(Post ? value : incrementedValue); }
private object EvaluateBinaryExpression(ScriptBinaryExpression expression, ScriptDate left, ScriptTimeSpan right) { switch (expression.Operator) { case ScriptBinaryOperator.Add: return(new ScriptDate((DateTime)left + right)); } throw new ScriptRuntimeException(expression.Span, $"Operator [{expression.Operator}] is not supported for between <date> and <timespan>"); }
object IScriptCustomType.EvaluateBinaryExpression(ScriptBinaryExpression expression, object left, object right) { if (left is ScriptDate && right is ScriptDate) { return(EvaluateBinaryExpression(expression, (ScriptDate)left, (ScriptDate)right)); } if (left is ScriptDate && right is ScriptTimeSpan) { return(EvaluateBinaryExpression(expression, (ScriptDate)left, (ScriptTimeSpan)right)); } throw new ScriptRuntimeException(expression.Span, $"Operator [{expression.Operator}] is not supported for between [{left?.GetType()}] and [{right?.GetType()}]"); }
public object Dot(object x, object y) { if (x is KalkVector vx) { if (y is KalkVector vy) { return(KalkVector.Dot(vx, vy)); } return(KalkVector.Dot(vx, vx.FromValue(Engine.ToObject(1, y, vx.ElementType)))); } else if (y is KalkVector vy) { return(KalkVector.Dot(vy.FromValue(Engine.ToObject(1, x, vy.ElementType)), vy)); } return(ScriptBinaryExpression.Evaluate(Engine, Engine.CurrentSpan, ScriptBinaryOperator.Multiply, x, y)); }
/// <summary> /// Divides the specified value by another value. If the divisor is an integer, the result will /// be floor to and converted back to an integer. /// </summary> /// <param name="context">The template context</param> /// <param name="span">The source span</param> /// <param name="value">The input value</param> /// <param name="divisor">The divisor value</param> /// <returns>The division of `value` by `divisor`.</returns> /// <remarks> /// ```scriban-html /// {{ 8.4 | math.divided_by 2.0 | math.round 1 }} /// {{ 8.4 | math.divided_by 2 }} /// ``` /// ```html /// 4.2 /// 4 /// ``` /// </remarks> public static object DividedBy(TemplateContext context, SourceSpan span, double value, object divisor) { var result = ScriptBinaryExpression.Evaluate(context, span, ScriptBinaryOperator.Divide, value, divisor); // If the divisor is an integer, return a an integer if (divisor is int) { if (result is double) { return((int)Math.Floor((double)result)); } if (result is float) { return((int)Math.Floor((float)result)); } } return(result); }
private void SquashPowers() { if (_powers == null) { return; } _powers.Sort(SortPowerPerSymbol); // Compress the powers: a^x * a^y = a^(x+y) KalkBinaryExpression previousPower = null; for (var i = 0; i < _powers.Count; i++) { var power = _powers[i]; if (previousPower != null && ReferenceEquals(power.Value, previousPower.Value)) { var powerResult = ScriptBinaryExpression.Evaluate(_context, _context.CurrentSpan, ScriptBinaryOperator.Add, power.Unit, previousPower.Unit); _powers[i - 1] = new KalkBinaryExpression(power.Value, ScriptBinaryOperator.Power, powerResult); _powers.RemoveAt(i); i--; continue; } previousPower = power; } // Remove any powers a^0.0 for (var i = 0; i < _powers.Count; i++) { var power = _powers[i]; var powerValue = _context.ToObject <double>(_context.CurrentSpan, power.Unit); if (Math.Abs(powerValue) < (float.Epsilon * 4)) { _powers.RemoveAt(i); i--; } } // Sort power per Power first and symbol after // From largest to smallest _powers.Sort(SortPowerPerPower); }
private ScriptStatement ParseLiquidIncDecStatement(bool isDec) { ScriptExpressionStatement incdecStatement = Open <ScriptExpressionStatement>(); NextToken(); // skip increment/decrement keyword ScriptBinaryExpression binaryExpression = Open <ScriptBinaryExpression>(); binaryExpression.Left = ExpectAndParseVariable(incdecStatement); binaryExpression.Right = new ScriptLiteral() { Span = binaryExpression.Span, Value = 1 }; binaryExpression.Operator = isDec ? ScriptBinaryOperator.Substract : ScriptBinaryOperator.Add; ExpectEndOfStatement(incdecStatement); incdecStatement.Expression = binaryExpression; Close(binaryExpression); return(Close(incdecStatement)); }
public bool TryEvaluate(TemplateContext context, SourceSpan span, ScriptBinaryOperator op, SourceSpan leftSpan, object leftValue, SourceSpan rightSpan, object rightValue, out object result) { result = null; if (leftValue is KalkHalf leftHalf && rightValue is KalkHalf rightHalf) { result = (KalkHalf)(float)ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, (float)leftHalf, rightSpan, (float)rightHalf); return(true); } if (leftValue is KalkHalf leftHalf1) { result = (KalkHalf)(float)ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, (float)leftHalf1, rightSpan, rightValue); return(true); } if (rightValue is KalkHalf rightHalf1) { result = (KalkHalf)(float)ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValue, rightSpan, rightHalf1); return(true); } return(false); }
public bool TryEvaluate(TemplateContext context, SourceSpan span, ScriptBinaryOperator op, SourceSpan leftSpan, object leftValue, SourceSpan rightSpan, object rightValue, out object result) { var leftExpr = leftValue as KalkExpression; if (leftExpr is null && !KalkValue.IsNumber(leftValue)) { throw new ScriptRuntimeException(leftSpan, "Expecting a number, vector or matrix"); } var rightExpr = rightValue as KalkExpression; if (rightExpr is null && !KalkValue.IsNumber(rightValue)) { throw new ScriptRuntimeException(rightSpan, "Expecting a number, vector or matrix"); } result = null; switch (op) { case ScriptBinaryOperator.CompareEqual: case ScriptBinaryOperator.CompareNotEqual: case ScriptBinaryOperator.CompareLessOrEqual: case ScriptBinaryOperator.CompareGreaterOrEqual: case ScriptBinaryOperator.CompareLess: case ScriptBinaryOperator.CompareGreater: if (leftExpr != null && rightExpr != null) { var leftSimplifier = new KalkExpressionSimplifier(context); var(leftValueMultiplier, newLeftExpr) = leftSimplifier.Canonical(leftExpr); var rightSimplifier = new KalkExpressionSimplifier(context); var(rightValueMultiplier, newRightExpr) = rightSimplifier.Canonical(rightExpr); var exprEquals = Equals(context, newLeftExpr, newRightExpr); if (exprEquals) { var almostEqual = KalkValue.AlmostEqual(leftValueMultiplier, rightValueMultiplier); switch (op) { case ScriptBinaryOperator.CompareEqual: result = almostEqual; break; case ScriptBinaryOperator.CompareNotEqual: result = !almostEqual; break; case ScriptBinaryOperator.CompareLessOrEqual: result = almostEqual || ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValueMultiplier, rightSpan, rightValueMultiplier) is bool v1 && v1; break; case ScriptBinaryOperator.CompareGreaterOrEqual: result = almostEqual || ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValueMultiplier, rightSpan, rightValueMultiplier) is bool v2 && v2; break; case ScriptBinaryOperator.CompareLess: result = ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValueMultiplier, rightSpan, rightValueMultiplier) is bool v3 && v3; break; case ScriptBinaryOperator.CompareGreater: result = ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValueMultiplier, rightSpan, rightValueMultiplier) is bool v4 && v4; break; } } else { result = op == ScriptBinaryOperator.CompareNotEqual; } } else { if (op == ScriptBinaryOperator.CompareEqual || op == ScriptBinaryOperator.CompareNotEqual) { result = op == ScriptBinaryOperator.CompareNotEqual; } else { throw NotMatching(leftSpan, leftExpr, rightSpan, rightExpr); } } return(true); case ScriptBinaryOperator.Multiply: case ScriptBinaryOperator.Divide: case ScriptBinaryOperator.Power: { if (op != ScriptBinaryOperator.Power || rightExpr == null) { var simplifier = new KalkExpressionSimplifier(context); var(valueMul, valueExpr) = simplifier.Canonical(new KalkBinaryExpression(leftValue, op, rightValue)); var valueBinExpr = valueExpr as KalkBinaryExpression; result = KalkValue.AlmostEqual(valueMul, 1.0) && valueBinExpr == null ? valueExpr ?? (object)1.0 : valueExpr == null ? valueMul : (object)new KalkBinaryExpression(valueMul, ScriptBinaryOperator.Multiply, valueExpr) { OriginalExpression = new KalkBinaryExpression(leftValue, op, rightValue) }; return(true); } else { throw new ScriptRuntimeException(rightSpan, "Cannot use a unit as an exponent."); } } case ScriptBinaryOperator.Add: case ScriptBinaryOperator.Substract: if (leftExpr != null && rightExpr != null) { var leftSimplifier = new KalkExpressionSimplifier(context); var(leftValueMultiplier, newLeftExpr) = leftSimplifier.Canonical(leftExpr); var rightSimplifier = new KalkExpressionSimplifier(context); var(rightValueMultiplier, newRightExpr) = rightSimplifier.Canonical(rightExpr); if (!Equals(context, newLeftExpr, newRightExpr)) { throw new ScriptRuntimeException(span, $"Cannot {(op == ScriptBinaryOperator.Add ? "add" : "subtract")} the expression. Units are not matching. The left expression with unit `{newLeftExpr}` is not matching the right expression with unit `{newRightExpr}`."); } result = new KalkBinaryExpression(ScriptBinaryExpression.Evaluate(context, span, op, leftSpan, leftValueMultiplier, rightSpan, rightValueMultiplier), ScriptBinaryOperator.Multiply, newLeftExpr) { OriginalExpression = new KalkBinaryExpression(leftValue, op, rightValue) }; } else { throw NotMatching(leftSpan, leftExpr, rightSpan, rightExpr); } return(true); } return(false); }
/// <summary> /// Substracts from the input value the `with` value /// </summary> /// <param name="context">The template context</param> /// <param name="span">The source span</param> /// <param name="value">The input value</param> /// <param name="with">The with value to substract from `value`</param> /// <returns>The results of the substraction: `value` - `with`</returns> /// <remarks> /// ```scriban-html /// {{ 255 | math.minus 5}} /// ``` /// ```html /// 250 /// ``` /// </remarks> public static object Minus(TemplateContext context, SourceSpan span, object value, object with) { return(ScriptBinaryExpression.Evaluate(context, span, ScriptBinaryOperator.Substract, value, with)); }
/// <summary> /// Performs the multiplication of the input value with the `with` value /// </summary> /// <param name="context">The template context</param> /// <param name="span">The source span</param> /// <param name="value">The input value</param> /// <param name="with">The with value to multiply to`value`</param> /// <returns>The results of the multiplication: `value` * `with`</returns> /// <remarks> /// ```scriban-html /// {{ 2 | math.times 3}} /// ``` /// ```html /// 6 /// ``` /// </remarks> public static object Times(TemplateContext context, SourceSpan span, object value, object with) { return(ScriptBinaryExpression.Evaluate(context, span, ScriptBinaryOperator.Multiply, value, with)); }
private ScriptExpression ParseExpression(ScriptNode parentNode, ref bool hasAnonymousFunction, ScriptExpression parentExpression = null, int precedence = 0, ParseExpressionMode mode = ParseExpressionMode.Default) { int expressionCount = 0; _expressionLevel++; int expressionDepthBeforeEntering = _expressionDepth; EnterExpression(); try { ScriptFunctionCall functionCall = null; parseExpression: expressionCount++; ScriptExpression leftOperand = null; switch (Current.Type) { case TokenType.Identifier: case TokenType.IdentifierSpecial: leftOperand = ParseVariable(); // In case of liquid template, we accept the syntax colon after a tag if (_isLiquid && parentNode is ScriptPipeCall && Current.Type == TokenType.Colon) { NextToken(); } // Special handle of the $$ block delegate variable if (ScriptVariable.BlockDelegate.Equals(leftOperand)) { if (expressionCount != 1 || _expressionLevel > 1) { LogError(RS.DelegateBlockInNestedExpr); } if (!(parentNode is ScriptExpressionStatement)) { LogError(parentNode, RS.DelegateBlockOutsideExpr); } return(leftOperand); } break; case TokenType.Integer: leftOperand = ParseInteger(); break; case TokenType.Float: leftOperand = ParseFloat(); break; case TokenType.String: leftOperand = ParseString(); break; case TokenType.ImplicitString: leftOperand = ParseImplicitString(); break; case TokenType.VerbatimString: leftOperand = ParseVerbatimString(); break; case TokenType.OpenParent: leftOperand = ParseParenthesis(ref hasAnonymousFunction); break; case TokenType.OpenBrace: leftOperand = ParseObjectInitializer(); break; case TokenType.OpenBracket: leftOperand = ParseArrayInitializer(); break; case TokenType.Not: case TokenType.Minus: case TokenType.Arroba: case TokenType.Plus: case TokenType.Caret: leftOperand = ParseUnaryExpression(ref hasAnonymousFunction); break; } // Should not happen but in case if (leftOperand == null) { if (functionCall != null) { LogError(string.Format(RS.UnexpectedTokenInFunc, GetAsText(Current), functionCall)); } else { LogError(string.Format(RS.UnexpectedTokenInExpr, GetAsText(Current))); } return(null); } if (leftOperand is ScriptAnonymousFunction) { hasAnonymousFunction = true; } while (!hasAnonymousFunction) { if (_isLiquid && Current.Type == TokenType.Comma && functionCall != null) { NextToken(); // Skip the comma for arguments in a function call } // Parse Member expression are expected to be followed only by an identifier if (Current.Type == TokenType.Dot) { Token nextToken = PeekToken(); if (nextToken.Type == TokenType.Identifier) { NextToken(); if (GetAsText(Current) == "empty" && PeekToken().Type == TokenType.Question) { ScriptIsEmptyExpression memberExpression = Open <ScriptIsEmptyExpression>(); NextToken(); // skip empty NextToken(); // skip ? memberExpression.Target = leftOperand; leftOperand = Close(memberExpression); } else { ScriptMemberExpression memberExpression = Open <ScriptMemberExpression>(); memberExpression.Target = leftOperand; ScriptExpression member = ParseVariable(); if (!(member is ScriptVariable)) { LogError(string.Format(RS.UnexpectedLiteralMember, member)); return(null); } memberExpression.Member = (ScriptVariable)member; leftOperand = Close(memberExpression); } } else { LogError(nextToken, string.Format(RS.InvalidTokenAfterDot, nextToken.Type)); return(null); } continue; } // If we have a bracket but left operand is a (variable || member || indexer), then we consider next as an indexer // unit test: 130-indexer-accessor-accept1.txt if (Current.Type == TokenType.OpenBracket && leftOperand is IScriptVariablePath && !IsPreviousCharWhitespace()) { NextToken(); ScriptIndexerExpression indexerExpression = Open <ScriptIndexerExpression>(); indexerExpression.Target = leftOperand; // unit test: 130-indexer-accessor-error5.txt indexerExpression.Index = ExpectAndParseExpression(indexerExpression, ref hasAnonymousFunction, functionCall, 0, string.Format(RS.ExpectToken, "index_expression", Current.Type)); if (Current.Type != TokenType.CloseBracket) { LogError(string.Format(RS.ExpectToken, "]", Current.Type)); } else { NextToken(); } leftOperand = Close(indexerExpression); continue; } if (mode == ParseExpressionMode.BasicExpression) { break; } if (Current.Type == TokenType.Equal) { ScriptAssignExpression assignExpression = Open <ScriptAssignExpression>(); if (_expressionLevel > 1) { // unit test: 101-assign-complex-error1.txt LogError(assignExpression, RS.ExprForTopLevelAssignmentOnly); } NextToken(); assignExpression.Target = TransformKeyword(leftOperand); // unit test: 105-assign-error3.txt assignExpression.Value = ExpectAndParseExpression(assignExpression, ref hasAnonymousFunction, parentExpression); leftOperand = Close(assignExpression); continue; } // Handle binary operators here ScriptBinaryOperator binaryOperatorType; if (BinaryOperators.TryGetValue(Current.Type, out binaryOperatorType) || (_isLiquid && TryLiquidBinaryOperator(out binaryOperatorType))) { int newPrecedence = GetOperatorPrecedence(binaryOperatorType); // Check precedence to see if we should "take" this operator here (Thanks TimJones for the tip code! ;) if (newPrecedence < precedence) { break; } // We fake entering an expression here to limit the number of expression EnterExpression(); ScriptBinaryExpression binaryExpression = Open <ScriptBinaryExpression>(); binaryExpression.Left = leftOperand; binaryExpression.Operator = binaryOperatorType; NextToken(); // skip the operator // unit test: 110-binary-simple-error1.txt binaryExpression.Right = ExpectAndParseExpression(binaryExpression, ref hasAnonymousFunction, functionCall ?? parentExpression, newPrecedence, string.Format(RS.ExpectTokenInRightOperator, "expression", Current.Type)); leftOperand = Close(binaryExpression); continue; } if (precedence > 0) { break; } if (StartAsExpression()) { // If we can parse a statement, we have a method call if (parentExpression != null) { break; } // Parse named parameters var paramContainer = parentNode as IScriptNamedArgumentContainer; if (Current.Type == TokenType.Identifier && (parentNode is IScriptNamedArgumentContainer || !_isLiquid && PeekToken().Type == TokenType.Colon)) { if (paramContainer == null) { if (functionCall == null) { functionCall = Open <ScriptFunctionCall>(); functionCall.Target = leftOperand; functionCall.Span.Start = leftOperand.Span.Start; } else { functionCall.Arguments.Add(leftOperand); } Close(leftOperand); } while (true) { if (Current.Type != TokenType.Identifier) { break; } ScriptNamedArgument parameter = Open <ScriptNamedArgument>(); string parameterName = GetAsText(Current); parameter.Name = parameterName; // Skip argument name NextToken(); if (paramContainer != null) { paramContainer.AddParameter(Close(parameter)); } else { functionCall.Arguments.Add(parameter); } // If we have a colon, we have a value // otherwise it is a boolean argument name if (Current.Type == TokenType.Colon) { NextToken(); parameter.Value = ExpectAndParseExpression(parentNode, mode: ParseExpressionMode.BasicExpression); parameter.Span.End = parameter.Value.Span.End; } if (functionCall != null) { functionCall.Span.End = parameter.Span.End; } } // As we have handled leftOperand here, we don't let the function out of this while to pick up the leftOperand if (functionCall != null) { leftOperand = functionCall; functionCall = null; } // We don't allow anything after named parameters break; } if (functionCall == null) { functionCall = Open <ScriptFunctionCall>(); functionCall.Target = leftOperand; // If we need to convert liquid to textscript functions: if (_isLiquid && Options.ConvertLiquidFunctions) { TransformFromLiquidFunctionCall(functionCall); } functionCall.Span.Start = leftOperand.Span.Start; } else { functionCall.Arguments.Add(leftOperand); } goto parseExpression; } if (Current.Type == TokenType.Pipe) { if (functionCall != null) { functionCall.Arguments.Add(leftOperand); leftOperand = functionCall; } ScriptPipeCall pipeCall = Open <ScriptPipeCall>(); pipeCall.From = leftOperand; NextToken(); // skip | // unit test: 310-func-pipe-error1.txt pipeCall.To = ExpectAndParseExpression(pipeCall, ref hasAnonymousFunction); return(Close(pipeCall)); } break; } if (functionCall != null) { functionCall.Arguments.Add(leftOperand); functionCall.Span.End = leftOperand.Span.End; return(functionCall); } return(Close(leftOperand)); } finally { LeaveExpression(); // Force to restore back to a level _expressionDepth = expressionDepthBeforeEntering; _expressionLevel--; } }
private void Collect(object value) { if (value == null) { return; } if (value is KalkUnit symbol) { if (symbol.Value != null) { Collect(symbol.Value); } else { if (_powers == null) { _powers = new List <KalkBinaryExpression>(); } _powers.Add(new KalkBinaryExpression(symbol, ScriptBinaryOperator.Power, 1)); } } else if (value is KalkBinaryExpression binary) { if (binary.Operator == ScriptBinaryOperator.Multiply) { var leftSimplifier = new KalkExpressionSimplifier(_context); leftSimplifier.Collect(binary.Value); Collect(leftSimplifier); var rightSimplifier = new KalkExpressionSimplifier(_context); rightSimplifier.Collect(binary.Unit); Collect(rightSimplifier); } else if (binary.Operator == ScriptBinaryOperator.Divide) { Collect(binary.Value); if (binary.Unit is KalkExpression) { Collect(new KalkBinaryExpression(binary.Unit, ScriptBinaryOperator.Power, -1)); } else { var result = ScriptBinaryExpression.Evaluate(_context, _context.CurrentSpan, ScriptBinaryOperator.Divide, 1, binary.Unit); SquashValue(result); } } else { Debug.Assert(binary.Operator == ScriptBinaryOperator.Power); if (_powers == null) { _powers = new List <KalkBinaryExpression>(); } // (a * b^2) ^ 5 // a ^ 5 * b ^ 10 var subSimplifier = new KalkExpressionSimplifier(_context); subSimplifier.Collect(binary.Value); var subValue = _context.ToObject <double>(_context.CurrentSpan, subSimplifier._value); if (!KalkValue.AlmostEqual(subValue, 1.0)) { var result = ScriptBinaryExpression.Evaluate(_context, _context.CurrentSpan, ScriptBinaryOperator.Power, subSimplifier._value, binary.Unit); SquashValue(result); } if (subSimplifier._powers != null) { foreach (var powerExpression in subSimplifier._powers) { var powerResult = ScriptBinaryExpression.Evaluate(_context, _context.CurrentSpan, ScriptBinaryOperator.Multiply, powerExpression.Unit, binary.Unit); var newPower = new KalkBinaryExpression(powerExpression.Value, ScriptBinaryOperator.Power, powerResult); _powers.Add(newPower); } } } } else { SquashValue(value); } }
public ScriptExpression ReplaceCondition(ScriptExpression condition, object replaceValue) { if (condition is ScriptVariableLocal localVar) { if (localVar.Name == string.Empty) { return(new ScriptLiteral(replaceValue)); } else { return(localVar); } } else if (condition is ScriptMemberExpression objExpr) { return(new ScriptMemberExpression() { Member = objExpr.Member, Trivias = objExpr.Trivias, Target = ReplaceCondition(objExpr.Target, replaceValue) }); } else if (condition is ScriptNestedExpression nestedExpr) { return(new ScriptNestedExpression() { Expression = ReplaceCondition(nestedExpr.Expression, replaceValue), Trivias = nestedExpr.Trivias }); } else if (condition is ScriptFunctionCall funcCall) { ScriptFunctionCall funcResult = new ScriptFunctionCall() { Target = funcCall.Target, Trivias = funcCall.Trivias }; foreach (ScriptExpression expr in funcCall.Arguments) { funcResult.Arguments.Add(ReplaceCondition(expr, replaceValue)); } return(funcResult); } else if (condition is ScriptPipeCall pipeCall) { ScriptPipeCall pipeResult = new ScriptPipeCall() { From = ReplaceCondition(pipeCall.From, replaceValue), To = ReplaceCondition(pipeCall.To, replaceValue), Trivias = pipeCall.Trivias }; return(pipeResult); } else if (condition is ScriptBinaryExpression binCondition) { ScriptBinaryExpression binExprResult = new ScriptBinaryExpression() { Left = ReplaceCondition(binCondition.Left, replaceValue), Right = ReplaceCondition(binCondition.Right, replaceValue), Operator = binCondition.Operator, Trivias = binCondition.Trivias }; return(binExprResult); } else { return(condition); } }
private void SquashValue(object value) { _value = ScriptBinaryExpression.Evaluate(_context, _context.CurrentSpan, ScriptBinaryOperator.Multiply, _value, value); }
public object Normalize(object x) { return(ScriptBinaryExpression.Evaluate(Engine, Engine.CurrentSpan, ScriptBinaryOperator.Divide, x, Length(x))); }