/// <summary> /// A private helper method to evaluate the type of a set of IExpressionNodes. /// </summary> /// <returns>The evaluation.</returns> /// <param name="expressions">Expressions.</param> private IProperty getEvaluation(params IExpressionNode[] expressions) { IExpressionNode expression = expressions [0]; // first evaluate the first of the expressions to get its type IProperty evaluatedType = expression.Accept(this).asProperty(); if (evaluatedType.GetTokenType() == TokenType.ERROR) { expression.EvaluationType = TokenType.ERROR; return(new ErrorProperty()); } expression.EvaluationType = evaluatedType.GetTokenType(); // go through the rest of the expressions and compare them to the first evaluation for (int i = 1; i < expressions.Length; i++) { expression = expressions [i]; IProperty retVal = expression.Accept(this).asProperty(); if (retVal.GetTokenType() != evaluatedType.GetTokenType()) { // if it didn't match the original one, it's an error expression.EvaluationType = TokenType.ERROR; return(new ErrorProperty()); } expression.EvaluationType = retVal.GetTokenType(); } return(evaluatedType); }
/// <summary> /// Checks the static semantic constraints of a ForLoopNode. /// </summary> /// <returns>An ISemanticCheckValue.</returns> /// <param name="node">Node.</param> public ISemanticCheckValue VisitForLoopNode(ForLoopNode node) { // check that the id property is ok IProperty property = getVariableProperty(node); if (property == voidProperty) { return(voidProperty); } VariableIdNode controlVariable = node.IDNode; // check that the control variable is declared checkPropertyDeclared(node, property, true); // check that the control variable's type is integer if (property.GetTokenType() != TokenType.INT_VAL) { analyzer.notifyError(new IllegalTypeError(controlVariable)); } // set the control variable as static so any attempts to assign new value // to it inside the loop reports an error analyzer.SymbolicTable [controlVariable.ID].Constant = true; IExpressionNode max = node.MaxValue; // check that the expression that defines the maximum value of the control variable // exists and evaluates to an integer if (max == null) { analyzer.notifyError(new NullPointerError(node)); } else { IProperty maxProperty = max.Accept(this.typeChecker).asProperty(); if (!checkPropertyType(maxProperty, TokenType.INT_VAL)) { analyzer.notifyError(new IllegalTypeError(max)); } } // check that the assingment that sets the control variables initial value // evaluates to an integer IProperty rangeFromProperty = node.RangeFrom.Accept(this.typeChecker).asProperty(); if (!checkPropertyType(rangeFromProperty, TokenType.INT_VAL)) { analyzer.notifyError(new IllegalTypeError(node.RangeFrom)); } // check the statements of this for loop node.Statements.Accept(this); // the control variable needs not to ba constant any more analyzer.SymbolicTable [controlVariable.ID].Constant = false; return(voidProperty); }
private bool HasGetErrorsMethod(IExpressionNode node) { _hasGetErrors = false; _errorPathNames.Clear(); node.Accept(this); return(_hasGetErrors); }
public Action <IDataContext> Handle(ref IExpressionNode expression, bool isPrimaryExpression, IDataContext context) { if (expression != null) { _lastContext = context; expression = expression.Accept(this); _lastContext = null; } return(null); }
public Action <IDataContext> Handle(ref IExpressionNode expression, bool isPrimaryExpression, IDataContext context) { if (expression == null) { return(null); } expression = expression.Accept(MacrosExpressionVisitor.Instance).Accept(NullConditionalOperatorVisitor.Instance); if (!isPrimaryExpression) { return(null); } lock (_errorPathNames) { if (!HasGetErrorsMethod(ref expression)) { return(null); } var pairs = _errorPathNames.ToArrayEx(); return(dataContext => UpdateBindingContext(dataContext, pairs)); } }
/// <summary> /// Prepares an <see cref="IExpressionNode" /> for the binding. /// </summary> /// <param name="expression">The specified binding expression.</param> /// <param name="isPrimaryExpression">If <c>true</c> it's main binding expression; otherwise parameter expression.</param> /// <param name="context">The specified context.</param> /// <returns>An instance of delegate to update binding.</returns> public Action <IDataContext> Handle(ref IExpressionNode expression, bool isPrimaryExpression, IDataContext context) { if (expression == null) { return(null); } //Updating relative sources. expression = expression.Accept(RelativeSourcePathMergerVisitor.Instance); if (!isPrimaryExpression) { return(null); } lock (_errorPathNames) { if (!HasGetErrorsMethod(expression)) { return(null); } var strings = _errorPathNames.Count == 0 ? null : _errorPathNames.ToArrayEx(); return(dataContext => UpdateBindingContext(dataContext, strings)); } }
private Action<IDataContext> GetBindingValueSetterMain(IExpressionNode node, Action<IDataContext, object> setSimpleValue, Action<IDataContext, Func<IDataContext, object>> setComplexValue, bool useBindingForMember) { var constantNode = node as IConstantExpressionNode; if (constantNode != null) { object value = constantNode.Value; return context => setSimpleValue(context, value); } try { node = node.Accept(_memberVisitor); if (_memberVisitor.IsMulti) { var members = _memberVisitor.Members.ToArrayEx(); var bindingSource = members.Length == 0 ? Empty.Array<Func<IDataContext, IObserver>>() : new Func<IDataContext, IObserver>[members.Length]; for (int i = 0; i < members.Length; i++) bindingSource[i] = GetBindingSourceDelegate(members[i].Value); var invoker = CreateExpressionInvoker(node, members, members.Length == 0); return context => { var sources = bindingSource.Length == 0 ? Empty.Array<IObserver>() : new IObserver[bindingSource.Length]; for (int i = 0; i < bindingSource.Length; i++) sources[i] = bindingSource[i].Invoke(context); setComplexValue(context, dataContext => { object[] args; if (sources.Length == 0) args = Empty.Array<object>(); else { args = new object[sources.Length]; for (int i = 0; i < sources.Length; i++) args[i] = sources[i].GetCurrentValue(); } try { return invoker.Invoke(dataContext, args); } catch (Exception e) { Tracer.Error(e.Message); return null; } }); }; } else { if (_memberVisitor.Members.Count == 0) { var value = ((IConstantExpressionNode)node).Value; return context => setSimpleValue(context, value); } var memberExp = _memberVisitor.Members[0].Value; if (!useBindingForMember && !memberExp.IsRelativeSource && !memberExp.IsDynamic) { var path = memberExp.Path; return context => setSimpleValue(context, path); } var srcFunc = GetBindingSourceDelegate(memberExp); return context => { var src = srcFunc(context); setComplexValue(context, dataContext => src.GetCurrentValue()); }; } } finally { _memberVisitor.Clear(); } }
/// <summary> /// Gets the evaluation of an expression. /// </summary> /// <returns>The evaluation.</returns> /// <param name="expressions">Expressions.</param> private IProperty getEvaluation(IExpressionNode expression) { IProperty evaluatedType = expression.Accept(this).asProperty(); return(evaluatedType); }
public int GetCount([NotNull] IExpressionNode node) { _count = 0; node.Accept(this); return(_count); }
private bool HasGetErrorsMethod(ref IExpressionNode node) { _errorPathNames.Clear(); node = node.Accept(this); return _errorPathNames.Count != 0; }
public Action<IDataContext> Handle(ref IExpressionNode expression, bool isPrimaryExpression, IDataContext context) { if (expression == null) return null; expression = expression.Accept(MacrosExpressionVisitor.Instance).Accept(NullConditionalOperatorVisitor.Instance); if (!isPrimaryExpression) return null; lock (_errorPathNames) { if (!HasGetErrorsMethod(ref expression)) return null; var pairs = _errorPathNames.ToArrayEx(); return dataContext => UpdateBindingContext(dataContext, pairs); } }
private bool HasGetErrorsMethod(ref IExpressionNode node) { _errorPathNames.Clear(); node = node.Accept(this); return(_errorPathNames.Count != 0); }