/// <summary> /// Visits a Binary expression /// </summary> /// <param name="binaryExpression"></param> protected virtual void VisitBinaryExpression(BinaryExpression binaryExpression) { if (binaryExpression.Left != null) { VisitExpression(binaryExpression.Left); } if (binaryExpression.Right != null) { VisitExpression(binaryExpression.Right); } }
/// <summary> /// Visits a Binary expression /// </summary> /// <param name="binaryExpression"></param> protected virtual void VisitBinaryExpression(BinaryExpression binaryExpression) { if (binaryExpression.Left != null) { VisitInterpreterTreeNode(binaryExpression.Left); } if (binaryExpression.Right != null) { VisitInterpreterTreeNode(binaryExpression.Right); } }
/// <summary> /// Combines two types to create a new one /// </summary> /// <param name="right"></param> /// <returns></returns> public override Type CombineType(Type right, BinaryExpression.Operator Operator) { Type retVal = null; if (Operator == BinaryExpression.Operator.Mult) { Range range = right as Range; if (range != null) { if (range.getPrecision() == acceptor.PrecisionEnum.aIntegerPrecision) { retVal = this; } } } return retVal; }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="Operation"></param> /// <param name="right"></param> /// <returns></returns> public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.OPERATOR Operation, IValue right) { IntValue retVal = null; int int1 = getValue(left); int int2 = getValue(right); switch (Operation) { case BinaryExpression.OPERATOR.EXP: retVal = new IntValue(EFSSystem.IntegerType, (Decimal) Math.Pow((double) int1, (double) int2)); break; case BinaryExpression.OPERATOR.MULT: retVal = new IntValue(EFSSystem.IntegerType, (int1*int2)); break; case BinaryExpression.OPERATOR.DIV: if (int2 == 0) throw new Exception("Division by zero"); else retVal = new IntValue(EFSSystem.IntegerType, (int1/int2)); break; case BinaryExpression.OPERATOR.ADD: retVal = new IntValue(EFSSystem.IntegerType, (int1 + int2)); break; case BinaryExpression.OPERATOR.SUB: retVal = new IntValue(EFSSystem.IntegerType, (int1 - int2)); break; } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="otherType"></param> /// <returns></returns> public override bool ValidBinaryOperation(BinaryExpression.OPERATOR operation, Type otherType) { bool retVal = base.ValidBinaryOperation(operation, otherType); if (!retVal) { if (operation == BinaryExpression.OPERATOR.ADD || operation == BinaryExpression.OPERATOR.DIV || operation == BinaryExpression.OPERATOR.MULT || operation == BinaryExpression.OPERATOR.SUB) { // Allow implicit conversions IntegerType integerType = otherType as IntegerType; if (integerType != null) { retVal = true; } else { DoubleType doubleType = otherType as DoubleType; retVal = (doubleType != null); } } } return retVal; }
/// <summary> /// Combines two types to create a new one /// </summary> /// <param name="right"></param> /// <returns></returns> public override Type CombineType(Type right, BinaryExpression.OPERATOR Operator) { Type retVal = null; if (Operator == BinaryExpression.OPERATOR.MULT) { if (FullName.CompareTo("Default.BaseTypes.Speed") == 0 && right.FullName.CompareTo("Default.BaseTypes.Time") == 0) { NameSpace nameSpace = EnclosingNameSpaceFinder.find(this); retVal = nameSpace.findTypeByName("Distance"); } } else { if (IsDouble()) { if (right == EFSSystem.DoubleType) { retVal = this; } } else { if (right == EFSSystem.IntegerType) { retVal = this; } } } return retVal; }
/// <summary> /// Indicates whether the expression is based on a placeholder value, ommiting the parameter provided /// </summary> /// <param name="context">The current interpretation context</param> /// <param name="expression">The expression to evaluate</param> /// <returns></returns> private bool ExpressionBasedOnPlaceHolder(InterpretationContext context, BinaryExpression expression) { bool retVal = false; if (expression != null) { foreach (ITypedElement element in expression.GetRightSides()) { Parameter parameter = element as Parameter; if (parameter != null) { IVariable variable = context.FindOnStack(parameter); if (variable != null) { PlaceHolder placeHolder = variable.Value as PlaceHolder; if (placeHolder != null) { retVal = true; break; } } } } } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="otherType"></param> /// <returns></returns> public override bool ValidBinaryOperation(BinaryExpression.OPERATOR operation, Type otherType) { bool retVal; if (operation == BinaryExpression.OPERATOR.LESS || operation == BinaryExpression.OPERATOR.LESS_OR_EQUAL || operation == BinaryExpression.OPERATOR.GREATER || operation == BinaryExpression.OPERATOR.GREATER_OR_EQUAL) { retVal = false; } else { retVal = base.ValidBinaryOperation(operation, otherType); } return retVal; }
public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator operation, IValue right) { ListValue retVal = null; switch (operation) { case BinaryExpression.Operator.Add: Collection leftType = left.Type as Collection; Collection rightType = right.Type as Collection; Collection returnType; if (leftType != null && rightType != null) { if (leftType is GenericCollection) { if (rightType is GenericCollection) { returnType = new GenericCollection(EFSSystem); } else { returnType = rightType; } } else { if (leftType == rightType || rightType is GenericCollection) { returnType = leftType; } else if (leftType.Type == rightType.Type) { returnType = leftType; } else { throw new Exception("Cannot determine the collection type for expression"); } } ListValue leftValue = left as ListValue; ListValue rightValue = right as ListValue; if (leftValue != null && rightValue != null) { retVal = new ListValue(returnType, new List<IValue>()); foreach (IValue val in leftValue.Val) { if (!(val is EmptyValue)) { retVal.Val.Add(val.RightSide(null, true, true)); } } foreach (IValue val in rightValue.Val) { if (!(val is EmptyValue)) { retVal.Val.Add(val.RightSide(null, true, true)); } } } else { throw new Exception("Cannot add a collection to a single element"); } } break; } return retVal; }
/// <summary> /// Implements the following grammar rules /// Expression_iCont -> {op_i+1} Expression_i+1 Expression_iCont /// Expression_iCont -> Epsilon /// </summary> /// <param name="expressionLevel">the current level of the expression</param> /// <param name="expressionLeft">the left part of the current expression</param> /// <returns></returns> private Expression ExpressionContinuation(int expressionLevel, Expression expressionLeft) { Expression retVal = expressionLeft; string[] operators = BinaryExpression.Images(BinaryExpression.OperatorsByLevel[expressionLevel]); string op = LookAhead(operators); if (op != null && "<".Equals(op)) { // Avoid <- to be confused with < -1 if (Index < Buffer.Length - 1 && Buffer[Index + 1] == '-') { op = null; } } if (op != null) // Expression_iCont -> {op_i+1} Expression_i+1 Expression_iCont { Match(op); BinaryExpression.Operator oper = BinaryExpression.FindOperatorByName(op); Expression expressionRight = Expression(expressionLevel + 1); if (expressionRight != null) { retVal = new BinaryExpression(Root, RootLog, expressionLeft, oper, expressionRight, expressionLeft.Start, expressionRight.End); // {op_i+1} Expression_i+1 retVal = ExpressionContinuation(expressionLevel, retVal); // Expression_iCont } } return retVal; }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="Operation"></param> /// <param name="right"></param> /// <returns></returns> public virtual Values.IValue PerformArithmericOperation(Interpreter.InterpretationContext context, Values.IValue left, BinaryExpression.OPERATOR Operation, Values.IValue right) { Values.IValue retVal = null; Functions.Function leftFunction = left as Functions.Function; Functions.Function rigthFunction = right as Functions.Function; if (rigthFunction == null) { if (leftFunction.Graph != null) { Functions.Graph graph = Functions.Graph.createGraph(Functions.Function.getDoubleValue(right)); rigthFunction = graph.Function; } else { Functions.Surface surface = Functions.Surface.createSurface(Functions.Function.getDoubleValue(right), leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); rigthFunction = surface.Function; } } if (leftFunction.Graph != null) { Functions.Graph tmp = null; switch (Operation) { case BinaryExpression.OPERATOR.ADD: tmp = leftFunction.Graph.AddGraph(rigthFunction.Graph); break; case BinaryExpression.OPERATOR.SUB: tmp = leftFunction.Graph.SubstractGraph(rigthFunction.Graph); break; case BinaryExpression.OPERATOR.MULT: tmp = leftFunction.Graph.MultGraph(rigthFunction.Graph); break; case BinaryExpression.OPERATOR.DIV: tmp = leftFunction.Graph.DivGraph(rigthFunction.Graph); break; } retVal = tmp.Function; } else { Functions.Surface rightSurface = rigthFunction.getSurface(leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); Functions.Surface tmp = null; switch (Operation) { case BinaryExpression.OPERATOR.ADD: tmp = leftFunction.Surface.AddSurface(rightSurface); break; case BinaryExpression.OPERATOR.SUB: tmp = leftFunction.Surface.SubstractSurface(rightSurface); break; case BinaryExpression.OPERATOR.MULT: tmp = leftFunction.Surface.MultiplySurface(rightSurface); break; case BinaryExpression.OPERATOR.DIV: tmp = leftFunction.Surface.DivideSurface(rightSurface); break; } retVal = tmp.Function; } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="operation"></param> /// <param name="otherType"></param> /// <returns></returns> public override bool ValidBinaryOperation(BinaryExpression.Operator operation, Type otherType) { bool retVal; if (operation == BinaryExpression.Operator.Less || operation == BinaryExpression.Operator.LessOrEqual || operation == BinaryExpression.Operator.Greater || operation == BinaryExpression.Operator.GreaterOrEqual) { retVal = false; } else { retVal = base.ValidBinaryOperation(operation, otherType); } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="otherType"></param> /// <returns></returns> public virtual bool ValidBinaryOperation(BinaryExpression.OPERATOR operation, Type otherType) { bool retVal; if (operation == BinaryExpression.OPERATOR.IN || operation == BinaryExpression.OPERATOR.NOT_IN) { Collection collectionType = otherType as Collection; if (collectionType != null) { retVal = Match(collectionType.Type); } else { retVal = Match(otherType); } } else { retVal = Match(otherType); } return retVal; }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="operation"></param> /// <param name="right"></param> /// <returns></returns> public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator operation, IValue right) { DoubleValue retVal = null; double double1 = getValue(left); double double2 = getValue(right); switch (operation) { case BinaryExpression.Operator.Exp: retVal = new DoubleValue(this, Math.Pow(double1, double2)); break; case BinaryExpression.Operator.Mult: retVal = new DoubleValue(this, (double1*double2)); break; case BinaryExpression.Operator.Div: if (double2 == 0) throw new Exception("Division by zero"); else retVal = new DoubleValue(this, (double1/double2)); break; case BinaryExpression.Operator.Add: retVal = new DoubleValue(this, (double1 + double2)); break; case BinaryExpression.Operator.Sub: retVal = new DoubleValue(this, (double1 - double2)); break; } return retVal; }
public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator Operation, IValue right) { throw new Exception("Cannot perform arithmetic operation between " + left.LiteralName + " and " + right.LiteralName); }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="operation"></param> /// <param name="right"></param> /// <returns></returns> public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator operation, IValue right) { IntValue retVal = null; Decimal int1 = getValue(left); Decimal int2 = getValue(right); switch (operation) { case BinaryExpression.Operator.Exp: retVal = new IntValue(EFSSystem.IntegerType, (Decimal) Math.Pow((double) int1, (double) int2)); break; case BinaryExpression.Operator.Mult: retVal = new IntValue(EFSSystem.IntegerType, (int1*int2)); break; case BinaryExpression.Operator.Div: if (int2 == 0) throw new Exception("Division by zero"); else retVal = new IntValue(EFSSystem.IntegerType, Math.Floor(int1/int2)); break; case BinaryExpression.Operator.Add: retVal = new IntValue(EFSSystem.IntegerType, (int1 + int2)); break; case BinaryExpression.Operator.Sub: retVal = new IntValue(EFSSystem.IntegerType, (int1 - int2)); break; } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="otherType"></param> /// <returns></returns> public override bool ValidBinaryOperation(BinaryExpression.Operator operation, Type otherType) { bool retVal = base.ValidBinaryOperation(operation, otherType); if (!retVal) { if (operation == BinaryExpression.Operator.Add || operation == BinaryExpression.Operator.Div || operation == BinaryExpression.Operator.Mult || operation == BinaryExpression.Operator.Sub) { // Allow implicit conversions IntegerType integerType = otherType as IntegerType; if (integerType != null) { retVal = true; } else { DoubleType doubleType = otherType as DoubleType; retVal = (doubleType != null); } } } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="operation"></param> /// <param name="otherType"></param> /// <returns></returns> public override bool ValidBinaryOperation(BinaryExpression.Operator operation, Type otherType) { bool retVal = false; if (ReturnType != null) { Function otherFunction = otherType as Function; if (otherFunction != null) { if (otherFunction.ReturnType != null) { retVal = ReturnType.ValidBinaryOperation(operation, otherFunction.ReturnType); } } else if (ReturnType != this) { retVal = ReturnType.ValidBinaryOperation(operation, otherType); } else { retVal = true; } } return retVal; }
/// <summary> /// Combines two types to create a new one /// </summary> /// <param name="right"></param> /// <returns></returns> public virtual Type CombineType(Type right, BinaryExpression.Operator Operator) { return null; }
/// <summary> /// Combines two types to create a new one /// </summary> /// <param name="right"></param> /// <param name="Operator"></param> /// <returns></returns> public override Type CombineType(Type right, BinaryExpression.Operator Operator) { Type retVal = null; Function function = right as Function; if (function != null) { if (ReturnType == function.ReturnType) { if (FormalParameters.Count >= function.FormalParameters.Count) { retVal = this; } else { retVal = function; } } else { AddError("Cannot combine types " + ReturnType.Name + " and " + function.ReturnType.Name); } } else if (right.IsDouble()) { retVal = this; } else { AddError("Cannot combine types " + ReturnType.Name + " and " + right.Name); } return retVal; }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="operation"></param> /// <param name="right"></param> /// <returns></returns> public virtual IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.Operator operation, IValue right) { IValue retVal = null; Function leftFunction = left as Function; Function rigthFunction = right as Function; if (leftFunction != null) { if (rigthFunction == null) { if (leftFunction.Graph != null) { Graph graph = Graph.createGraph(Function.GetDoubleValue(right)); rigthFunction = graph.Function; } else { Surface surface = Surface.createSurface(Function.GetDoubleValue(right), leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); rigthFunction = surface.Function; } } if (leftFunction.Graph != null) { IGraph tmp = null; switch (operation) { case BinaryExpression.Operator.Add: tmp = leftFunction.Graph.AddGraph(rigthFunction.Graph); break; case BinaryExpression.Operator.Sub: tmp = leftFunction.Graph.SubstractGraph(rigthFunction.Graph); break; case BinaryExpression.Operator.Mult: tmp = leftFunction.Graph.MultGraph(rigthFunction.Graph); break; case BinaryExpression.Operator.Div: tmp = leftFunction.Graph.DivGraph(rigthFunction.Graph); break; } Graph tmpGraph = tmp as Graph; if (tmpGraph != null) { retVal = tmpGraph.Function; } } else { Surface rightSurface = rigthFunction.GetSurface(leftFunction.Surface.XParameter, leftFunction.Surface.YParameter); Surface tmp = null; switch (operation) { case BinaryExpression.Operator.Add: tmp = leftFunction.Surface.AddSurface(rightSurface); break; case BinaryExpression.Operator.Sub: tmp = leftFunction.Surface.SubstractSurface(rightSurface); break; case BinaryExpression.Operator.Mult: tmp = leftFunction.Surface.MultiplySurface(rightSurface); break; case BinaryExpression.Operator.Div: tmp = leftFunction.Surface.DivideSurface(rightSurface); break; } retVal = tmp.Function; } } return retVal; }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="Operation"></param> /// <param name="right"></param> /// <returns></returns> public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.OPERATOR Operation, IValue right) { IValue retVal = null; left = derefEnumForArithmeticOperation(left); right = derefEnumForArithmeticOperation(right); IntValue int1 = left as IntValue; IntValue int2 = right as IntValue; if (int1 == null || int2 == null) { retVal = EFSSystem.DoubleType.PerformArithmericOperation(context, left, Operation, right); } else { retVal = EFSSystem.IntegerType.PerformArithmericOperation(context, left, Operation, right); } return retVal; }
/// <summary> /// Indicates that binary operation is valid for this type and the other type /// </summary> /// <param name="otherType"></param> /// <returns></returns> public virtual bool ValidBinaryOperation(BinaryExpression.Operator operation, Type otherType) { bool retVal; if (operation == BinaryExpression.Operator.In || operation == BinaryExpression.Operator.NotIn) { Collection collectionType = otherType as Collection; if (collectionType != null) { retVal = Match(collectionType.Type); } else { retVal = Match(otherType); } } else { retVal = Match(otherType); } return retVal; }
public override void visit(Generated.RuleCondition obj, bool subNodes) { Rules.RuleCondition ruleCondition = obj as Rules.RuleCondition; if (ruleCondition != null) { try { bool found = false; ruleCondition.Messages.Clear(); foreach (Rules.PreCondition preCondition in ruleCondition.PreConditions) { Interpreter.BinaryExpression expression = checkExpression(preCondition, preCondition.Expression) as Interpreter.BinaryExpression; if (expression != null) { if (expression.IsSimpleEquality()) { Types.ITypedElement variable = expression.Left.Ref as Types.ITypedElement; if (variable != null) { if (variable.Type != null) { // Check that when preconditions are based on a request, // the corresponding action affects the value Request.Disabled to the same variable if (variable.Type.Name.Equals("Request") && expression.Right != null && expression.Right is Interpreter.UnaryExpression) { Values.IValue val2 = expression.Right.Ref as Values.IValue; if (val2 != null && "Response".CompareTo(val2.Name) == 0) { if (ruleCondition != null) { found = false; foreach (Rules.Action action in ruleCondition.Actions) { Variables.IVariable var = OverallVariableFinder.INSTANCE.findByName(action, preCondition.findVariable()); Interpreter.Statement.VariableUpdateStatement update = action.Modifies(var); if (update != null) { Interpreter.UnaryExpression updateExpr = update.Expression as Interpreter.UnaryExpression; if (updateExpr != null) { Values.IValue val3 = updateExpr.Ref as Values.IValue; if (val3 != null && val3.Name.CompareTo("Disabled") == 0) { found = true; break; } } } } if (!found) { preCondition.AddError("Rules where the Pre conditions is based on a Request type variable must assign that variable the value 'Request.Disabled'"); } } } } } // Check that the outgoing variables are not read if (variable.Mode == Generated.acceptor.VariableModeEnumType.aOutgoing) { if (ruleCondition.Reads(variable)) { preCondition.AddError("An outgoing variable cannot be read"); } } // Check that the incoming variables are not modified if (variable.Mode == Generated.acceptor.VariableModeEnumType.aIncoming) { if (ruleCondition.Modifies(variable) != null) { preCondition.AddError("An incoming variable cannot be written"); } } } } } } } catch (Exception exception) { ruleCondition.AddException(exception); } } base.visit(obj, subNodes); }
// left +/-/*/div/exp right /// <summary> /// Performs the arithmetic operation based on the type of the result /// </summary> /// <param name="context">The context used to perform this operation</param> /// <param name="left"></param> /// <param name="Operation"></param> /// <param name="right"></param> /// <returns></returns> public override IValue PerformArithmericOperation(InterpretationContext context, IValue left, BinaryExpression.OPERATOR Operation, IValue right) { DoubleValue retVal = null; double double1 = getValue(left); double double2 = getValue(right); switch (Operation) { case BinaryExpression.OPERATOR.EXP: retVal = new DoubleValue(this, Math.Pow(double1, double2)); break; case BinaryExpression.OPERATOR.MULT: retVal = new DoubleValue(this, (double1*double2)); break; case BinaryExpression.OPERATOR.DIV: if (double2 == 0) throw new Exception("Division by zero"); else retVal = new DoubleValue(this, (double1/double2)); break; case BinaryExpression.OPERATOR.ADD: retVal = new DoubleValue(this, (double1 + double2)); break; case BinaryExpression.OPERATOR.SUB: retVal = new DoubleValue(this, (double1 - double2)); break; } return retVal; }