/// <summary> /// Perform additional checks based on the parameter types /// </summary> /// <param name="root">The element on which the errors should be reported</param> /// <param name="context">The evaluation context</param> /// <param name="actualParameters">The parameters applied to this function call</param> public override void additionalChecks(ModelElement root, Interpreter.InterpretationContext context, Dictionary <string, Interpreter.Expression> actualParameters) { CheckFunctionalParameter(root, context, actualParameters[First.Name], 2); CheckFunctionalParameter(root, context, actualParameters[Second.Name], 0); Function function1 = actualParameters[First.Name].GetExpressionType() as Function; Function function2 = actualParameters[Second.Name].GetExpressionType() as Function; if (function1 != null && function2 != null) { if (function1.FormalParameters.Count == 2 && function2.FormalParameters.Count == 0) { Parameter p1 = (Parameter)function1.FormalParameters[0]; Parameter p2 = (Parameter)function1.FormalParameters[1]; if (p1.Type != EFSSystem.DoubleType || p2.Type != EFSSystem.DoubleType) { root.AddError("The formal parameters for the first function are not double"); } } if (function1.ReturnType != function2.ReturnType && function1.ReturnType != EFSSystem.DoubleType && function2.ReturnType != EFSSystem.DoubleType) { root.AddError("The return values for the functions provided as parameter are not the same"); } } }
/// <summary> /// Checks that the change is valid /// </summary> /// <param name="element"></param> public virtual bool CheckChange(ModelElement element) { bool retVal = true; if (Variable == null) { element.AddError("Cannot determine variable to be updated"); retVal = false; } if (NewValue == null) { element.AddError(Variable.FullName + " <- <cannot evaluate value>"); retVal = false; } return(retVal); }
/// <summary> /// Ensures that all changes have a correct value /// </summary> /// <param name="element"></param> public void CheckChanges(ModelElement element) { foreach (Change change in Changes) { if (change.NewValue == null) { element.AddError(change.Variable.FullName + " <- <cannot evaluate value>"); } } }
/// <summary> /// Checks that the change is valid /// </summary> /// <param name="element"></param> public override bool CheckChange(ModelElement element) { bool retVal = true; if (Variable == null) { element.AddError("Cannot determine variable to be updated"); retVal = false; } return(retVal); }
/// <summary> /// Ensures that the parameter provided corresponds to a function double->double /// </summary> /// <param name="root">Element on which the errors shall be attached</param> /// <param name="context">The context used to evaluate the expression</param> /// <param name="expression">The expression which references the function</param> /// <param name="count">the expected number of parameters</param> protected virtual void CheckFunctionalParameter(ModelElement root, InterpretationContext context, Expression expression, int count) { Type type = expression.GetExpressionType(); Function function = type as Function; if (function != null) { if (function.FormalParameters.Count == count) { foreach (Parameter parameter in function.FormalParameters) { if (!parameter.Type.IsDouble()) { root.AddError(expression.ToString() + " does not takes a double for parameter " + parameter.Name); } } } else { root.AddError(expression.ToString() + " does not take " + count + "parameter(s) as input"); } if (!function.ReturnType.IsDouble()) { root.AddError(expression.ToString() + " does not return a double"); } } else { if (!type.IsDouble()) { root.AddError(expression.ToString() + " type is not double"); } } }
/// <summary> /// Provides the parse tree according to the expression provided /// </summary> /// <param name="root">the element for which this expression should be parsed</param> /// <param name="expression"></param> /// <returns></returns> public Expression Expression(ModelElement root, string expression) { Expression retVal = null; try { Generated.ControllersManager.NamableController.DesactivateNotification(); Root = root; Buffer = expression.ToCharArray(); retVal = Expression(0); skipWhiteSpaces(); if (Index != Buffer.Length) { retVal = null; if (Index < Buffer.Length) { Root.AddError("End of expression expected, but found " + Buffer[Index]); } else { Root.AddError("End of expression expected, but found EOF"); } } if (retVal != null) { retVal.SemanticAnalysis(Filter.IsVariableOrValue); } } finally { Generated.ControllersManager.NamableController.ActivateNotification(); } return(retVal); }
/// <summary> /// Sets the value of a given association /// </summary> /// <param name="structureElement"></param> /// <param name="log">The element on which errors should be logged</param> /// <returns>the newly created field</returns> public Field CreateField(StructureElement structureElement, ModelElement log) { Field retVal = null; if (structureElement != null) { retVal = new Field(this, structureElement); Val[retVal.Name] = retVal; } else { log.AddError("Cannot find structure element"); } return(retVal); }
/// <summary> /// Sets the value of a given association /// </summary> /// <param name="enclosing"></param> /// <param name="name"></param> /// <param name="log">The element on which errors should be logged</param> /// <returns>the newly created field</returns> public Field CreateField(object enclosing, string name, ModelElement log) { Field retVal = null; StructureElement structureElement = Structure.FindStructureElement(name); if (structureElement != null) { retVal = CreateField(structureElement, log); } else { log.AddError("Cannot find structure element " + name); } return(retVal); }
/// <summary> /// Perform additional checks based on the parameter types /// </summary> /// <param name="root">The element on which the errors should be reported</param> /// <param name="context">The evaluation context</param> /// <param name="actualParameters">The parameters applied to this function call</param> public override void additionalChecks(ModelElement root, Interpreter.InterpretationContext context, Dictionary <string, Interpreter.Expression> actualParameters) { CheckFunctionalParameter(root, context, actualParameters[Targets1.Name], 1); CheckFunctionalParameter(root, context, actualParameters[Targets2.Name], 1); CheckFunctionalParameter(root, context, actualParameters[Targets3.Name], 1); Function function1 = actualParameters[Targets1.Name].GetExpressionType() as Function; Function function2 = actualParameters[Targets2.Name].GetExpressionType() as Function; Function function3 = actualParameters[Targets3.Name].GetExpressionType() as Function; if (function1 != null && function2 != null && function3 != null) { if (function1.ReturnType != function2.ReturnType || function2.ReturnType != function3.ReturnType) { root.AddError("The types of functions provided are not the same"); } } }
/// <summary> /// Provides the Term at position Index of the Buffer. /// </summary> /// <param name="root">The root element for which this term is built</param> /// <returns></returns> private Statement.Statement Statement(ModelElement root) { Statement.Statement retVal = null; Root = root; if (LookAhead("APPLY")) { Match("APPLY"); Call callExpression = Expression(0) as Call; if (callExpression != null) { Statement.ProcedureCallStatement call = new Statement.ProcedureCallStatement(root, callExpression); Match("ON"); Expression listExpression = Expression(0); Expression condition = null; if (LookAhead("|")) { Match("|"); condition = Expression(0); } retVal = new Statement.ApplyStatement(root, call, listExpression, condition); } else { Root.AddError("Cannot parse call expression"); } } else if (LookAhead("INSERT")) { Match("INSERT"); Expression value = Expression(0); if (value != null) { Match("IN"); Expression list = Expression(0); Expression replaceElement = null; if (LookAhead("WHEN")) { Match("WHEN"); Match("FULL"); Match("REPLACE"); replaceElement = Expression(0); } retVal = new Statement.InsertStatement(root, value, list, replaceElement); } } else if (LookAhead("REMOVE")) { Match("REMOVE"); Statement.RemoveStatement.PositionEnum position = Interpreter.Statement.RemoveStatement.PositionEnum.First; if (LookAhead("FIRST")) { Match("FIRST"); } else if (LookAhead("LAST")) { Match("LAST"); position = Interpreter.Statement.RemoveStatement.PositionEnum.Last; } else if (LookAhead("ALL")) { Match("ALL"); position = Interpreter.Statement.RemoveStatement.PositionEnum.All; } Expression condition = null; if (!LookAhead("IN")) { condition = Expression(0); } Match("IN"); Expression list = Expression(0); retVal = new Statement.RemoveStatement(root, condition, position, list); } else if (LookAhead("REPLACE")) { Match("REPLACE"); Expression condition = Expression(0); Match("IN"); Expression list = Expression(0); Match("BY"); Expression value = Expression(0); retVal = new Statement.ReplaceStatement(root, value, list, condition); } else { Expression expression = Expression(0); if (expression != null) { if (LookAhead("<-")) { // This is a variable update Match("<-"); if (LookAhead("%")) { Match("%"); } Expression expression2 = Expression(0); if (expression2 != null) { retVal = new Statement.VariableUpdateStatement(root, expression, expression2); } else { Root.AddError("Invalid <- right side"); } expression.Enclosing = retVal; } else { // This is a procedure call Call call = expression as Call; if (call != null) { retVal = new Statement.ProcedureCallStatement(root, call); } else { Root.AddError("Cannot parse call expression"); } } } else { Root.AddError("Cannot parse expression"); } } return(retVal); }
/// <summary> /// Perform additional checks based on the parameter types /// </summary> /// <param name="root">The element on which the errors should be reported</param> /// <param name="context">The evaluation context</param> /// <param name="actualParameters">The parameters applied to this function call</param> public override void additionalChecks(ModelElement root, Interpreter.InterpretationContext context, Dictionary<string, Interpreter.Expression> actualParameters) { CheckFunctionalParameter(root, context, actualParameters[First.Name], 1); CheckFunctionalParameter(root, context, actualParameters[Second.Name], 1); Function function1 = actualParameters[First.Name].GetExpressionType() as Function; Function function2 = actualParameters[Second.Name].GetExpressionType() as Function; if (function1 != null && function2 != null) { if (function1.FormalParameters.Count == 1 && function2.FormalParameters.Count == 1) { Parameter p1 = (Parameter)function1.FormalParameters[0]; Parameter p2 = (Parameter)function2.FormalParameters[0]; if (p1.Type != p2.Type && p1.Type != EFSSystem.DoubleType && p2.Type != EFSSystem.DoubleType) { root.AddError("The formal parameters for the functions provided as parameter are not the same"); } } if (function1.ReturnType != function2.ReturnType && function1.ReturnType != EFSSystem.DoubleType && function2.ReturnType != EFSSystem.DoubleType) { root.AddError("The return values for the functions provided as parameter are not the same"); } } }
/// <summary> /// Checks that the change is valid /// </summary> /// <param name="element"></param> public override bool CheckChange(ModelElement element) { bool retVal = true; if (Variable == null) { element.AddError("Cannot determine variable to be updated"); retVal = false; } return retVal; }
/// <summary> /// Evaluates the rules associated to a single variable /// </summary> /// <param name="priority">The priority in which this variable is evaluated</param> /// <param name="activations">The activation list result of this evaluation</param> /// <param name="variable">The variable to evaluate</param> /// <param name="explanation">The explanation part to be filled</param> private void EvaluateVariable(acceptor.RulePriority priority, HashSet <Activation> activations, IVariable variable, ExplanationPart explanation) { if (variable != null && variable.Value != EfsSystem.Instance.EmptyValue) { if (variable.Type != null && variable.Type.ApplicableRule(priority)) { if (variable.Type is Structure) { Structure structure = variable.Type as Structure; foreach (Rules.Rule rule in structure.Rules) { rule.Evaluate(this, priority, variable, activations, explanation); } StructureValue value = variable.Value as StructureValue; if (value != null) { foreach (IVariable subVariable in value.SubVariables.Values) { EvaluateVariable(priority, activations, subVariable, explanation); } } } else if (variable.Type is StateMachine) { EvaluateStateMachine(activations, priority, variable, explanation); } else if (variable.Type is Collection) { Collection collectionType = variable.Type as Collection; if (variable.Value != EfsSystem.Instance.EmptyValue) { ListValue val = variable.Value as ListValue; if (val != null) { foreach (IValue subVal in val.Val) { Variables.Variable tmp = new Variables.Variable { Name = "list_entry", Type = collectionType.Type, Value = subVal }; EvaluateVariable(priority, activations, tmp, explanation); } } else { ModelElement element = variable as ModelElement; if (element != null) { element.AddError("Variable " + variable.Name + " does not hold a collection but " + variable.Value); } else { throw new Exception("Variable " + variable.Name + " does not hold a collection but " + variable.Value); } } } } } } }
/// <summary> /// Provides the Term at position Index of the Buffer. /// </summary> /// <param name="root">The root element for which this term is built</param> /// <returns></returns> private Statement.Statement Statement(ModelElement root) { Statement.Statement retVal = null; Root = root; if (LookAhead("APPLY")) { Match("APPLY"); Call callExpression = Expression(0) as Call; if (callExpression != null) { Statement.ProcedureCallStatement call = new Statement.ProcedureCallStatement(root, callExpression); Match("ON"); Expression listExpression = Expression(0); Expression condition = null; if (LookAhead("|")) { Match("|"); condition = Expression(0); } retVal = new Statement.ApplyStatement(root, call, listExpression, condition); } else { Root.AddError("Cannot parse call expression"); } } else if (LookAhead("INSERT")) { Match("INSERT"); Expression value = Expression(0); if (value != null) { Match("IN"); Expression list = Expression(0); Expression replaceElement = null; if (LookAhead("WHEN")) { Match("WHEN"); Match("FULL"); Match("REPLACE"); replaceElement = Expression(0); } retVal = new Statement.InsertStatement(root, value, list, replaceElement); } } else if (LookAhead("REMOVE")) { Match("REMOVE"); Statement.RemoveStatement.PositionEnum position = Interpreter.Statement.RemoveStatement.PositionEnum.First; if (LookAhead("FIRST")) { Match("FIRST"); } else if (LookAhead("LAST")) { Match("LAST"); position = Interpreter.Statement.RemoveStatement.PositionEnum.Last; } else if (LookAhead("ALL")) { Match("ALL"); position = Interpreter.Statement.RemoveStatement.PositionEnum.All; } Expression condition = null; if (!LookAhead("IN")) { condition = Expression(0); } Match("IN"); Expression list = Expression(0); retVal = new Statement.RemoveStatement(root, condition, position, list); } else if (LookAhead("REPLACE")) { Match("REPLACE"); Expression condition = Expression(0); Match("IN"); Expression list = Expression(0); Match("BY"); Expression value = Expression(0); retVal = new Statement.ReplaceStatement(root, value, list, condition); } else { Expression expression = Expression(0); if (expression != null) { if (LookAhead("<-")) { // This is a variable update Match("<-"); if (LookAhead("%")) { Match("%"); } Expression expression2 = Expression(0); if (expression2 != null) { retVal = new Statement.VariableUpdateStatement(root, expression, expression2); } else { Root.AddError("Invalid <- right side"); } expression.Enclosing = retVal; } else { // This is a procedure call Call call = expression as Call; if (call != null) { retVal = new Statement.ProcedureCallStatement(root, call); } else { Root.AddError("Cannot parse call expression"); } } } else { Root.AddError("Cannot parse expression"); } } return retVal; }
/// <summary> /// Ensures that the parameter provided corresponds to a function double->double /// </summary> /// <param name="root">Element on which the errors shall be attached</param> /// <param name="context">The context used to evaluate the expression</param> /// <param name="expression">The expression which references the function</param> /// <param name="count">the expected number of parameters</param> protected virtual void CheckFunctionalParameter(ModelElement root, Interpreter.InterpretationContext context, Interpreter.Expression expression, int count) { Types.Type type = expression.GetExpressionType(); Function function = type as Function; if (function != null) { if (function.FormalParameters.Count == count) { foreach (Parameter parameter in function.FormalParameters) { if (!parameter.Type.IsDouble()) { root.AddError(expression.ToString() + " does not takes a double for parameter " + parameter.Name); } } } else { root.AddError(expression.ToString() + " does not take " + count + "parameter(s) as input"); } if (!function.ReturnType.IsDouble()) { root.AddError(expression.ToString() + " does not return a double"); } } else { if (!type.IsDouble()) { root.AddError(expression.ToString() + " type is not double"); } } }
/// <summary> /// Provides the parse tree according to the expression provided /// </summary> /// <param name="root">the element for which this expression should be parsed</param> /// <param name="expression"></param> /// <returns></returns> public Expression Expression(ModelElement root, string expression) { Expression retVal = null; try { Generated.ControllersManager.NamableController.DesactivateNotification(); Root = root; Buffer = expression.ToCharArray(); retVal = Expression(0); skipWhiteSpaces(); if (Index != Buffer.Length) { retVal = null; if (Index < Buffer.Length) { Root.AddError("End of expression expected, but found " + Buffer[Index]); } else { Root.AddError("End of expression expected, but found EOF"); } } if (retVal != null) { retVal.SemanticAnalysis(Filter.IsVariableOrValue); } } finally { Generated.ControllersManager.NamableController.ActivateNotification(); } return retVal; }
/// <summary> /// Provides the parse tree according to the expression provided /// </summary> /// <param name="root">the element for which this expression should be parsed</param> /// <param name="expression">the expression to parse</param> /// <param name="filter">The filter to apply when performing the semantic analysis</param> /// <param name="doSemanticalAnalysis">true indicates that the semantical analysis should be performed</param> /// <param name="log">the element on which errors should be raised. By default, this is root</param> /// <param name="silent">Indicates whether errors should be reported (silent = false) or not</param> /// <returns></returns> public Expression Expression(ModelElement root, string expression, BaseFilter filter = null, bool doSemanticalAnalysis = true, ModelElement log = null, bool silent = false) { Expression retVal = null; NoReentrance.WaitOne(); ModelElement.DontRaiseError(silent, () => { try { // Setup context Root = root; RootLog = log; if (RootLog == null) { RootLog = Root; } Buffer = expression.ToCharArray(); retVal = Expression(0); SkipWhiteSpaces(); if (Index != Buffer.Length) { retVal = null; if (Index < Buffer.Length) { RootLog.AddError("End of expression expected, but found " + Buffer[Index]); } else { RootLog.AddError("End of expression expected, but found EOF"); } } if (retVal != null && doSemanticalAnalysis) { if (filter == null) { retVal.SemanticAnalysis(IsVariableOrValue.INSTANCE); } else { retVal.SemanticAnalysis(filter); } } } catch (Exception e) { root.AddException(e); } finally { NoReentrance.ReleaseMutex(); } }); return retVal; }
/// <summary> /// Perform additional checks based on the parameter types /// </summary> /// <param name="root">The element on which the errors should be reported</param> /// <param name="context">The evaluation context</param> /// <param name="actualParameters">The parameters applied to this function call</param> public override void additionalChecks(ModelElement root, Interpreter.InterpretationContext context, Dictionary<string, Interpreter.Expression> actualParameters) { CheckFunctionalParameter(root, context, actualParameters[Targets1.Name], 1); CheckFunctionalParameter(root, context, actualParameters[Targets2.Name], 1); CheckFunctionalParameter(root, context, actualParameters[Targets3.Name], 1); Function function1 = actualParameters[Targets1.Name].GetExpressionType() as Function; Function function2 = actualParameters[Targets2.Name].GetExpressionType() as Function; Function function3 = actualParameters[Targets3.Name].GetExpressionType() as Function; if (function1 != null && function2 != null && function3 != null) { if (function1.ReturnType != function2.ReturnType || function2.ReturnType != function3.ReturnType) { root.AddError("The types of functions provided are not the same"); } } }