/// <summary> /// Visits a Call expression /// </summary> /// <param name="call"></param> protected virtual void VisitCall(Call call) { if (call.Called != null) { VisitExpression(call.Called); } foreach (Expression expression in call.ActualParameters) { if (expression != null) { VisitExpression(expression); } } foreach (KeyValuePair<Designator, Expression> pair in call.NamedActualParameters) { if (pair.Key != null) { VisitDesignator(pair.Key); } if (pair.Value != null) { VisitExpression(pair.Value); } } }
/// <summary> /// Gets the reference of the call if it covers the position given /// </summary> /// <param name="call"></param> protected override void VisitCall(Call call) { if (ShouldCheck(call)) { bool stopLooking = false; // Provides the return type when we are at the end of the call if (Position == call.End) { ICallable callable = call.Called.GetExpressionType() as ICallable; if (callable != null) { stopLooking = true; Context = callable.ReturnType; } } else { // Perform the analysis on the expressions providing the actual parameters for the call foreach (Expression expression in call.ActualParameters) { if (expression != null && ShouldCheck(expression)) { stopLooking = true; VisitExpression(expression); break; } } foreach (KeyValuePair<Designator, Expression> pair in call.NamedActualParameters) { if (pair.Value != null && ShouldCheck(pair.Value)) { stopLooking = true; VisitExpression(pair.Value); break; } } } // In all other cases, provide the function that is currently being called if (!stopLooking) { Context = call.Called.GetExpressionType(); } } }
/// <summary> /// Evaluates a function call, when the left part (function identification) has been parsed /// </summary> /// <param name="left">The left part of the function call expression</param> /// <returns></returns> private Expression EvaluateFunctionCallExpression(Expression left) { Call retVal = null; SkipWhiteSpaces(); if (LookAhead("(")) { retVal = new Call(Root, RootLog, left, left.Start, -1); Match("("); bool cont = true; while (cont) { SkipWhiteSpaces(); if (LookAhead(")")) { Match(")"); cont = false; } else { // Handle named parameters int current2 = Index; string id = Identifier(); Designator parameter = null; if (id != null) { string assignOp = LookAhead(AssignOps); if (assignOp != null) { Match(assignOp); parameter = new Designator(Root, RootLog, id, current2, current2 + id.Length); } else { Index = current2; } } Expression arg = Expression(0); if (arg != null) { retVal.AddActualParameter(parameter, arg); if (LookAhead(",")) { Match(","); } else if (LookAhead(")")) { Match(")"); cont = false; } } else { throw new ParseErrorException("Syntax error", Index, Buffer); } } } retVal.End = Index; } return retVal; }
/// <summary> /// Evaluates a function call, when the left part (function identification) has been parsed /// </summary> /// <param name="left">The left part of the function call expression</param> /// <returns></returns> private Expression EvaluateFunctionCallExpression(Expression left) { Call retVal = null; int current = Index; skipWhiteSpaces(); if (LookAhead("(")) { retVal = new Call(Root, left); Match("("); bool cont = true; while (cont) { skipWhiteSpaces(); if (LookAhead(")")) { Match(")"); cont = false; } else { // Handle named parameters int current2 = Index; string id = Identifier(); if (id != null) { if (LookAhead("=>")) { Match("=>"); } else { id = null; Index = current2; } } Expression arg = Expression(0); if (arg != null) { retVal.AddActualParameter(id, arg); if (LookAhead(",")) { Match(","); } else if (LookAhead(")")) { Match(")"); cont = false; } } else { throw new ParseErrorException("Syntax error"); } } } } return retVal; }
/// <summary> /// Checks that the call, if related to Graph or Surfaces, is valid /// </summary> /// <param name="call"></param> /// <param name="distance">The distance parameter</param> /// <param name="speed"></param> private void CheckCall(Call call, Parameter distance, Parameter speed) { DecelerationProfile decelerationFunction = EfsSystem.Instance.DecelerationProfilePredefinedFunction; FullDecelerationForTarget fullDecelerationForTargetFunction = EfsSystem.Instance.FullDecelerationForTargetPredefinedFunction; if (call.Called.Ref == decelerationFunction) { GraphCheck.CheckCall(call, decelerationFunction.SpeedRestrictions, distance); SurfaceCheck.CheckCall(call, decelerationFunction.DecelerationFactor, distance, speed); } else if (call.Called.Ref == fullDecelerationForTargetFunction) { SurfaceCheck.CheckCall(call, fullDecelerationForTargetFunction.DecelerationFactor, distance, speed); } }