/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { // --- Test for operand errors var addrValue = StartAddress.Evaluate(evalContext); if (addrValue.Type == ExpressionValueType.Error) { EvaluationError = StartAddress.EvaluationError; return(ExpressionValue.Error); } var length = EndAddress == null ? new ExpressionValue(1) : EndAddress.Evaluate(evalContext); if (length.Type == ExpressionValueType.Error) { EvaluationError = EndAddress?.EvaluationError; return(ExpressionValue.Error); } if (checkOnly) { return(ExpressionValue.NonEvaluated); } if (addrValue.Type == ExpressionValueType.ByteArray || length.Type == ExpressionValueType.ByteArray) { EvaluationError = "Memory address operator cannot be applied on a byte array"; return(ExpressionValue.Error); } var addr = addrValue.AsNumber(); return(new ExpressionValue(evalContext.GetMemorySection((ushort)addr, (ushort)(addr + length.AsNumber() - 1)))); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext) { var operand = Operand.Evaluate(evalContext); SuggestTypeOf(Operand); return(new ExpressionValue(~operand)); }
private static void EvaluateSingleTagDirective( [NotNull] TextWriter writer, [NotNull] IExpressionEvaluationContext context, [NotNull] Directive directive, [NotNull] IReadOnlyList <object> components) { /* Pre-evaluate the tag's components, as these */ var tagEvaluatedComponents = EvaluateTag(context, components); /* Evaluate tag. */ object state = null; var flowDecision = Directive.FlowDecision.Evaluate; while (flowDecision != Directive.FlowDecision.Terminate) { /* Check for cancellation. */ context.CancellationToken.ThrowIfCancellationRequested(); flowDecision = directive.Execute(0, tagEvaluatedComponents, ref state, context, out string directiveText); /* Check for cancellation. */ context.CancellationToken.ThrowIfCancellationRequested(); if (directiveText != null) { writer.Write(directiveText); } } }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext) { var address = Address.Evaluate(evalContext); if (!address.IsValid) { return(ExpressionValue.Error); } switch (WidthSpecifier) { case "W": SuggestType(ExpressionValueType.Word); return(new ExpressionValue(evalContext.GetMemoryIndirectValue(address).Value + (evalContext.GetMemoryIndirectValue(new ExpressionValue(address.Value + 1)).Value << 8))); case "DW": SuggestType(ExpressionValueType.DWord); return(new ExpressionValue(evalContext.GetMemoryIndirectValue(address).Value + (evalContext.GetMemoryIndirectValue(new ExpressionValue(address.Value + 1)).Value << 8) + (evalContext.GetMemoryIndirectValue(new ExpressionValue(address.Value + 2)).Value << 16) + (evalContext.GetMemoryIndirectValue(new ExpressionValue(address.Value + 3)).Value << 24))); default: SuggestType(ExpressionValueType.Byte); return(evalContext.GetMemoryIndirectValue(address)); } }
/// <summary> /// Executes the current directive. /// <remarks> /// The directive sets a new variable (as specified by the identifier) with the value of the given expression. The directive then /// evaluates the contents of its body. The variable will be useable within the evaluated body. /// </remarks> /// </summary> /// <param name="tagIndex">The index of the tag that triggered the execution.</param> /// <param name="components">The tag components as provided by the lexical analyzer.</param> /// <param name="state">A general-purpose state object. Initially set to <c>null</c>.</param> /// <param name="context">The evaluation context.</param> /// <param name="text">An optional text generated by the directive.</param> /// <returns> /// A value indicating the next step for the evaluation environment. /// </returns> protected internal override FlowDecision Execute( int tagIndex, object[] components, ref object state, IExpressionEvaluationContext context, out string text) { Debug.Assert(tagIndex >= 0 && tagIndex <= 1, "tagIndex must be between 0 and 1."); Debug.Assert(components != null, "components cannot be null."); Debug.Assert(components.Length == Tags[tagIndex].ComponentCount, "component length must match tag component length."); Debug.Assert(context != null, "context cannot be null."); text = null; var identifier = components[_identifierComponentIndex] as string; Debug.Assert(identifier != null, "variable name expected to be set."); if (state == null) { /* Starting up. */ Debug.Assert(tagIndex == 0, "tagIndex expected to be 0."); /* Add the new variable to the context. */ var value = components[_expressionComponentIndex]; context.SetProperty(identifier, value); /* Set the state to something. Not required for this particular directive, but to keep the flow intact. */ state = identifier; return(FlowDecision.Evaluate); } Debug.Assert(tagIndex == 1, "tagIndex expected to be 1."); return(FlowDecision.Terminate); }
/// <summary> /// Calculates the result of the binary operation. /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Result of the operation</returns> public override ExpressionValue Calculate(IExpressionEvaluationContext evalContext) { // --- Check operands for errors var leftValue = LeftOperand.Evaluate(evalContext); if (leftValue.Type == ExpressionValueType.Error) { EvaluationError = LeftOperand.EvaluationError; return(ExpressionValue.Error); } var rightValue = RightOperand.Evaluate(evalContext); if (rightValue.Type == ExpressionValueType.Error) { EvaluationError = RightOperand.EvaluationError; return(ExpressionValue.Error); } // --- Test for incompatible types if (leftValue.Type == ExpressionValueType.ByteArray || rightValue.Type == ExpressionValueType.ByteArray) { EvaluationError = "'>>' operator cannot be applied on a byte array"; return(ExpressionValue.Error); } // --- Numeric operands return(new ExpressionValue(leftValue.AsNumber() >> (ushort)rightValue.AsNumber())); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext) { var operand = Operand.Evaluate(evalContext); SuggestType(ExpressionValueType.Bool); return(new ExpressionValue((uint)(operand.Value == 0 ? 0 : 1))); }
protected override bool TryReduce(IExpressionEvaluationContext reduceContext, out object reducedValue) { Debug.Assert(reduceContext != null, "reduceContext cannot be null."); if (_groupChildrenNodes.Count == 1) { if (_groupChildrenNodes[0].Reduce(reduceContext)) { reducedValue = _groupChildrenNodes[0].ReducedValue; return(true); } } else if (_groupChildrenNodes.Count > 1) { var allReduced = true; foreach (var child in _groupChildrenNodes) { allReduced &= child.Reduce(reduceContext); } if (allReduced) { reducedValue = _groupChildrenNodes.Select(s => s.ReducedValue).ToArray(); return(true); } } reducedValue = null; return(false); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext) { var result = evalContext.GetZ80RegisterValue(Register, out var is8Bit); SuggestType(is8Bit ? ExpressionValueType.Byte : ExpressionValueType.Word); return(result); }
public virtual bool EvaluateLhs([NotNull] IExpressionEvaluationContext context, [CanBeNull] object left, out object result) { Expect.NotNull(nameof(context), context); result = null; return(false); }
protected override bool TryReduce(IExpressionEvaluationContext reduceContext, out object value) { Debug.Assert(reduceContext != null, "reduceContext cannot be null."); value = Literal; return true; }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { // --- Check operand error var operandValue = Operand.Evaluate(evalContext); if (operandValue.Type == ExpressionValueType.Error) { EvaluationError = Operand.EvaluationError; return(ExpressionValue.Error); } if (checkOnly) { return(ExpressionValue.NonEvaluated); } // --- Carry out operation switch (operandValue.Type) { case ExpressionValueType.ByteArray: EvaluationError = "Unary logical NOT operator cannot be applied on a byte array"; return(ExpressionValue.Error); case ExpressionValueType.Bool: case ExpressionValueType.Number: return(new ExpressionValue(!operandValue.AsBool())); default: return(ExpressionValue.Error); } }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { // --- Test for operand errors var addrValue = StartAddress.Evaluate(evalContext); if (addrValue.Type == ExpressionValueType.Error) { EvaluationError = StartAddress.EvaluationError; return(ExpressionValue.Error); } var endValue = EndAddress == null ? new ExpressionValue(1) : EndAddress.Evaluate(evalContext); if (endValue.Type == ExpressionValueType.Error) { EvaluationError = EndAddress?.EvaluationError; return(ExpressionValue.Error); } if (checkOnly) { return(ExpressionValue.NonEvaluated); } if (addrValue.Type == ExpressionValueType.ByteArray || endValue.Type == ExpressionValueType.ByteArray) { EvaluationError = "Memory address operator cannot be applied on a byte array"; return(ExpressionValue.Error); } return(new ExpressionValue(evalContext.GetMachineContext().GetMemorySection(addrValue.AsWord(), endValue.AsWord()))); }
protected virtual bool TryReduce(IExpressionEvaluationContext reduceContext, out object reducedValue) { Debug.Assert(reduceContext != null, "reduceContext cannot be null."); reducedValue = null; return(false); }
/// <summary> /// Executes the current directive. /// </summary> /// <param name="tagIndex">The index of the tag that triggered the execution.</param> /// <param name="components">The tag components as provided by the lexical analyzer.</param> /// <param name="state">A general-purpose state object. Initially set to <c>null</c>.</param> /// <param name="context">The evaluation context.</param> /// <param name="text">Always <c>null</c>.</param> /// <returns> /// A value indicating the next step for the evaluation environment. /// </returns> /// <remarks> /// If the expression evaluates to <c>true</c>, the contents between the first and the middle tag are evaluated, other wise the constants between the middle /// and the end tag are evaluated. /// </remarks> protected internal override FlowDecision Execute( int tagIndex, object[] components, ref object state, IExpressionEvaluationContext context, out string text) { Debug.Assert(tagIndex >= 0 && tagIndex <= 2, "tagIndex must be between 0 and 2."); Debug.Assert(components != null, "components cannot be null."); Debug.Assert(components.Length == Tags[tagIndex].ComponentCount, "component length must match tag component length."); Debug.Assert(context != null, "context cannot be null."); text = null; switch (tagIndex) { case 0: var conditionIsTrue = TypeConverter.ConvertToBoolean(components[_conditionalExpressionComponentIndex]); state = conditionIsTrue; return(conditionIsTrue ? FlowDecision.Evaluate : FlowDecision.Skip); case 1: Debug.Assert(state is bool, "state object expected to be a boolean."); var conditionWasTrue = (bool)state; if (!conditionWasTrue) { return(FlowDecision.Evaluate); } break; } return(FlowDecision.Terminate); }
/// <summary> /// Tries to evaluate the result only using the left-hand-side operand. /// <remarks>This method is used by operators that support left-hand-side short-circuit logic. The current implementation always return <c>false</c>.</remarks> /// </summary> /// <param name="context">The evaluation context.</param> /// <param name="left">The left operand.</param> /// <param name="result">The result of the evaluation if the return value is <c>true</c>.</param> /// <returns> /// <c>true</c> if the operation is supported; <c>false</c> otherwise. /// </returns> public override bool EvaluateLhs(IExpressionEvaluationContext context, object left, out object result) { Expect.NotNull(nameof(context), context); result = true; return(TypeConverter.TypeOf(left) == PrimitiveType.Boolean && TypeConverter.ConvertToBoolean(left)); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { // --- Check operand error var operandValue = Operand.Evaluate(evalContext); if (operandValue.Type == ExpressionValueType.Error) { EvaluationError = Operand.EvaluationError; return(ExpressionValue.Error); } if (checkOnly) { return(ExpressionValue.NonEvaluated); } // --- Carry out operation if (operandValue.Type != ExpressionValueType.ByteArray) { return(operandValue); } EvaluationError = "Unary plus operator cannot be applied on a byte array"; return(ExpressionValue.Error); }
/// <summary> /// Processes all un-parsed text blocks read from the original template. The method current implementation /// trims all white-spaces and new line characters and replaces them with a single white-space character (emulates how HTML trimming works). /// A preformatted directive is available to allow disabling this default behavior and preserving all original formatting. /// </summary> /// <param name="context">The <see cref="IExpressionEvaluationContext" /> instance containing the current evaluation state.</param> /// <param name="unParsedText">The text block being processed.</param> /// <returns> /// The processed text value. /// </returns> /// <exception cref="ArgumentNullException">Argument <paramref name="context" /> is <c>null</c>.</exception> public override string DecorateUnParsedText(IExpressionEvaluationContext context, string unParsedText) { Expect.NotNull(nameof(context), context); return (context.ContainsStateObject(PreformattedStateObject) ? unParsedText : base.DecorateUnParsedText(context, unParsedText)); }
/// <summary> /// Evaluates the result of integer sequence operation for <paramref name="left" /> and <paramref name="right" /> operands. /// </summary> /// <param name="context">The evaluation context.</param> /// <param name="left">The left operand.</param> /// <param name="right">The right operand.</param> /// <returns> /// The generated sequence or integers, or <c>null</c> if the operation would result in an invalid sequence. /// </returns> /// <exception cref="ArgumentNullException">Argument <paramref name="context" /> is <c>null</c>.</exception> public override object Evaluate(IExpressionEvaluationContext context, object left, object right) { Expect.NotNull(nameof(context), context); var min = TypeConverter.ConvertToInteger(left); var max = TypeConverter.ConvertToInteger(right); return(min <= max?Enumerable.Range(min, max - min + 1) : null); }
/// <summary> /// Calculates the result of the binary operation. /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Result of the operation</returns> public override ExpressionValue Calculate(IExpressionEvaluationContext evalContext) { var left = LeftOperand.Evaluate(evalContext); var right = RightOperand.Evaluate(evalContext); SuggestWiderType(); return(left.IsValid && right.IsValid ? new ExpressionValue(left.Value >> (int)right.Value) : ExpressionValue.Error); }
/// <summary> /// Calculates the result of the binary operation. /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Result of the operation</returns> public override ExpressionValue Calculate(IExpressionEvaluationContext evalContext) { var left = LeftOperand.Evaluate(evalContext); var right = RightOperand.Evaluate(evalContext); SuggestType(ExpressionValueType.Bool); return(left.IsValid && right.IsValid ? new ExpressionValue(left.Value >= right.Value ? 1u : 0u) : ExpressionValue.Error); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { if (checkOnly) { return(ExpressionValue.NonEvaluated); } var flagValue = evalContext.GetFlagValue(FlagName); return(new ExpressionValue(flagValue)); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <param name="checkOnly"></param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext, bool checkOnly = false) { if (checkOnly) { return(ExpressionValue.NonEvaluated); } var regValue = evalContext.GetMachineContext().GetRegisterValue(RegisterName); return(new ExpressionValue(regValue)); }
public object Evaluate([NotNull] IExpressionEvaluationContext context) { Expect.NotNull(nameof(context), context); if (!Constructed) { ExceptionHelper.CannotEvaluateUnConstructedExpression(); } Debug.Assert(_evaluationFunction != null); return(_evaluationFunction(context)); }
/// <summary> /// Retrieves the value of the expression /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Evaluated expression value</returns> public override ExpressionValue Evaluate(IExpressionEvaluationContext evalContext) { var idExpr = evalContext.GetSymbolValue(SymbolName); if (idExpr != ExpressionValue.Error) { SuggestType(ExpressionValueType.Word); return(idExpr); } EvaluationError = $"Symbol '{SymbolName}' cannot be found"; return(ExpressionValue.Error); }
protected override bool TryReduce(IExpressionEvaluationContext reduceContext, out object value) { Debug.Assert(reduceContext != null, "reduceContext cannot be null."); if (RightNode.Reduce(reduceContext)) { value = Operator.Evaluate(reduceContext, RightNode.ReducedValue); return(true); } value = null; return(false); }
public ExpressionEvaluator(IExpressionEvaluationContext context, Type functionsDefinition) { myContext = context; if (functionsDefinition != null) { myFunctions = functionsDefinition.GetMethods(BindingFlags.Public | BindingFlags.Static); } else { myFunctions = Enumerable.Empty <MethodInfo>(); } }
/// <summary> /// Executes the current directive. /// <remarks> /// If the expression is evaluated to <c>null</c>, the directive does not evaluate. It evaluates once for non-sequences and once for each element if the /// expression is a sequence. On each cycle the identifier is set to the value of the enumerated object. /// </remarks> /// </summary> /// <param name="tagIndex">The index of the tag that triggered the execution.</param> /// <param name="components">The tag components as provided by the lexical analyzer.</param> /// <param name="state">A general-purpose state object. Initially set to <c>null</c>.</param> /// <param name="context">The evaluation context.</param> /// <param name="text">An optional text generated by the directive.</param> /// <returns> /// A value indicating the next step for the evaluation environment. /// </returns> protected internal override FlowDecision Execute( int tagIndex, object[] components, ref object state, IExpressionEvaluationContext context, out string text) { Debug.Assert(tagIndex >= 0 && tagIndex <= 1, "tagIndex must be between 0 and 1."); Debug.Assert(components != null, "components cannot be null."); Debug.Assert(components.Length == Tags[tagIndex].ComponentCount, "component length must match tag component length."); Debug.Assert(context != null, "context cannot be null."); text = null; IEnumerator <object> enumerator; if (state == null) { /* Starting up. */ Debug.Assert(tagIndex == 0, "tagIndex expected to be 0."); var sequence = TypeConverter.ConvertToSequence(components[_expressionComponentIndex]); if (sequence == null) { return(FlowDecision.Terminate); } enumerator = sequence.GetEnumerator(); state = enumerator; } else if (tagIndex == 0) { enumerator = state as IEnumerator <object>; Debug.Assert(enumerator != null, "state object expected to be an enumerator."); } else { return(FlowDecision.Restart); } if (!enumerator.MoveNext()) { return(FlowDecision.Terminate); } var propertyName = components[_identifierComponentIndex] as string; Debug.Assert(propertyName != null, "variable name expected to be set."); context.SetProperty(propertyName, enumerator.Current); return(FlowDecision.Evaluate); }
/// <summary> /// Calculates the result of the binary operation. /// </summary> /// <param name="evalContext">Evaluation context</param> /// <returns>Result of the operation</returns> public override ExpressionValue Calculate(IExpressionEvaluationContext evalContext) { // --- Check operands for errors var leftValue = LeftOperand.Evaluate(evalContext); if (leftValue.Type == ExpressionValueType.Error) { EvaluationError = LeftOperand.EvaluationError; return(ExpressionValue.Error); } var rightValue = RightOperand.Evaluate(evalContext); if (rightValue.Type == ExpressionValueType.Error) { EvaluationError = RightOperand.EvaluationError; return(ExpressionValue.Error); } // --- Test if both operands are byte arrays if (leftValue.Type == ExpressionValueType.ByteArray) { if (rightValue.Type != ExpressionValueType.ByteArray) { EvaluationError = "Cannot apply bitwise XOR on a numeric value and a byte array"; return(ExpressionValue.Error); } // --- Bitwise XOR each array elements (shortest) var leftArray = leftValue.AsByteArray(); var rightArray = rightValue.AsByteArray(); var shortest = leftArray.Length > rightArray.Length ? leftArray.Length : rightArray.Length; var resultArray = new byte[shortest]; for (var i = 0; i < shortest; i++) { resultArray[i] = (byte)(leftArray[i] ^ rightArray[i]); } return(new ExpressionValue(resultArray)); } // --- Test incompatible types if (rightValue.Type == ExpressionValueType.ByteArray) { EvaluationError = "Cannot apply bitwise XOR on a byte array and a numeric value"; return(ExpressionValue.Error); } // --- Numeric operands return(new ExpressionValue(leftValue.AsNumber() ^ rightValue.AsNumber())); }
/// <summary> /// Evaluates the specified expression /// </summary> /// <param name="expr">Expression to evaluate</param> /// <param name="context">Evaluation context</param> /// <returns></returns> private ExpressionValue EvaluateExpression(ExpressionNode expr, IExpressionEvaluationContext context) { var value = expr.Evaluate(context); if (value == ExpressionValue.NonEvaluated) { throw new TestExecutionException("Expression cannot be evaluated."); } if (value == ExpressionValue.Error) { throw new TestExecutionException($"Expression evaluated with error: {expr.EvaluationError}"); } return(value); }