/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (ListExpression != null) { if (ListExpression.Ref is Parameter) { Root.AddError("Cannot change the list value which is a parameter (" + ListExpression + ")"); } Collection targetListType = ListExpression.GetExpressionType() as Collection; if (targetListType != null) { if (Condition != null) { Condition.CheckExpression(); BoolType conditionType = Condition.GetExpressionType() as BoolType; if (conditionType == null) { Root.AddError("Condition does not evaluates to boolean"); } } } else { Root.AddError("Cannot determine type of " + ListExpression); } } else { Root.AddError("List should be specified"); } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (ListExpression != null) { ListExpression.CheckExpression(); Collection listExpressionType = ListExpression.GetExpressionType() as Collection; if (listExpressionType == null) { Root.AddError("Target does not references a list"); } } else { Root.AddError("List should be specified"); } if (ConditionExpression != null) { ConditionExpression.CheckExpression(); } if (AppliedStatement != null) { AppliedStatement.CheckStatement(); } else { Root.AddError("Procedure should be specified in the APPLY statement"); } }
/// <summary> /// Adds an error message to the root element /// </summary> /// <param name="message"></param> public void AddError(string message) { if (Root != null) { Root.AddError(message); } }
/// <summary> /// Checks the expression and appends errors to the root tree node when inconsistencies are found /// </summary> public override void CheckExpression() { Structure structureType = Structure.GetExpressionType() as Structure; if (structureType != null) { if (structureType.IsAbstract) { AddError("Instantiation of abstract types is forbidden", RuleChecksEnum.SyntaxError); } foreach (KeyValuePair <Designator, Expression> pair in Associations) { Designator name = pair.Key; Expression expression = pair.Value; List <INamable> targets = new List <INamable>(); structureType.Find(name.Image, targets); if (targets.Count > 0) { expression.CheckExpression(); Type type = expression.GetExpressionType(); if (type != null) { if (type.IsAbstract) { AddError("Instantiation of abstract types is forbidden", RuleChecksEnum.SyntaxError); } else { foreach (INamable namable in targets) { ITypedElement element = namable as ITypedElement; if (element != null && element.Type != null) { if (!element.Type.Match(type)) { AddError("Expression " + expression + " type (" + type.FullName + ") does not match the target element " + element.Name + " type (" + element.Type.FullName + ")", RuleChecksEnum.SyntaxError); } } } } } else { AddError("Expression " + expression + " type cannot be found", RuleChecksEnum.SyntaxError); } } else { Root.AddError("Cannot find " + name + " in structure " + Structure); } } } else { AddError("Cannot find structure type " + Structure, RuleChecksEnum.SyntaxError); } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { Value.checkExpression(); Types.Collection targetListType = ListExpression.GetExpressionType() as Types.Collection; if (targetListType != null) { Types.Type elementType = Value.GetExpressionType(); if (elementType != targetListType.Type) { Root.AddError("Inserted element type does not corresponds to list type"); } Condition.checkExpression(); Types.BoolType conditionType = Condition.GetExpressionType() as Types.BoolType; if (conditionType == null) { Root.AddError("Condition does not evaluates to boolean"); } } else { Root.AddError("Cannot determine collection type of " + ListExpression); } }
/// <summary> /// Creates the graph associated to this expression, when the given parameter ranges over the X axis /// </summary> /// <param name="context">The interpretation context</param> /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param> /// <returns></returns> public override Functions.Graph createGraph(InterpretationContext context, Parameter parameter) { Functions.Graph retVal = base.createGraph(context, parameter); Functions.PredefinedFunctions.Cast cast = Called.Ref as Functions.PredefinedFunctions.Cast; if (cast != null) { // In case of cast, just take the graph of the enclosed expression Parameter param = (Parameter)cast.FormalParameters[0]; retVal = cast.createGraphForParameter(context, param); } Function calledFunction = Called.Ref as Function; Dictionary <Parameter, Expression> parameterAssociation = null; if (calledFunction == null) { calledFunction = Called.GetValue(context) as Function; parameterAssociation = createParameterAssociation(calledFunction); } else { parameterAssociation = ParameterAssociation; } Parameter Xaxis = null; foreach (KeyValuePair <Parameter, Expression> pair in parameterAssociation) { if (pair.Value.Ref == parameter) { if (Xaxis == null) { Xaxis = pair.Key; } else { Root.AddError("Cannot evaluate graph for function call " + ToString() + " which has more than 1 parameter used as X axis"); Xaxis = null; break; } } } int token = context.LocalScope.PushContext(); calledFunction.AssignParameters(context, AssignParameterValues(context, calledFunction, false)); if (Xaxis != null) { retVal = calledFunction.createGraphForParameter(context, Xaxis); } else { retVal = Function.createGraphForValue(GetValue(context)); } context.LocalScope.PopContext(token); return(retVal); }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply) { Variables.IVariable variable = ListExpression.GetVariable(context); if (variable != null) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue; variable.Value = listValue; if (listValue != null) { Values.ListValue newListValue = new Values.ListValue(listValue); int i = 0; foreach (Values.IValue current in newListValue.Val) { IteratorVariable.Value = current; if (conditionSatisfied(context)) { break; } i += 1; } if (i < newListValue.Val.Count) { Values.IValue value = Value.GetValue(context); if (value != null) { newListValue.Val[i] = value; Rules.Change change = new Rules.Change(variable, variable.Value, newListValue); changes.Add(change, apply); explanation.SubExplanations.Add(new ExplanationPart(Root, change)); } else { Root.AddError("Cannot find value for " + Value.ToString()); } } else { Root.AddError("Cannot find value in " + ListExpression.ToString() + " which satisfies " + Condition.ToString()); } } else { Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value"); } } else { Root.AddError("Cannot find variable for " + ListExpression.ToString()); } }
public void Add(string name, DTDElementDeclaration decl) { if (Contains(name)) { Root.AddError(new XmlSchemaException(String.Format( "Element declaration for {0} was already added.", name), null)); return; } decl.SetRoot(Root); BaseAdd(name, decl); }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { InterpretationContext context = new InterpretationContext(Root); Types.Collection listExpressionType = ListExpression.GetExpressionType() as Types.Collection; if (listExpressionType == null) { Root.AddError("Target does not references a list variable"); } context.LocalScope.setVariable(IteratorVariable); Call.CheckStatement(context); }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (ListExpression != null) { if (ListExpression.Ref is Parameter) { Root.AddError("Cannot change the list value which is a parameter (" + ListExpression + ")"); } Collection targetListType = ListExpression.GetExpressionType() as Collection; if (targetListType != null) { Type elementType = Value.GetExpressionType(); if (elementType != targetListType.Type) { Root.AddError("Inserted element type does not corresponds to list type"); } if (Condition != null) { Condition.CheckExpression(); BoolType conditionType = Condition.GetExpressionType() as BoolType; if (conditionType == null) { Root.AddError("Condition does not evaluates to boolean"); } } else { Root.AddError("Condition should be provided"); } } else { Root.AddError("Cannot determine collection type of " + ListExpression); } } else { Root.AddError("List should be specified"); } if (Value != null) { Value.CheckExpression(); } else { Root.AddError("Value should be specified"); } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { Types.Type targetType = VariableIdentification.GetExpressionType(); if (targetType == null) { Root.AddError("Cannot determine type of target " + VariableIdentification.ToString()); } else if (Expression != null) { Expression.checkExpression(); Types.Type type = Expression.GetExpressionType(); if (type != null) { if (targetType != null) { if (!targetType.Match(type)) { UnaryExpression unaryExpression = Expression as UnaryExpression; if (unaryExpression != null && unaryExpression.Term.LiteralValue != null) { if (targetType.getValue(unaryExpression.ToString()) == null) { Root.AddError("Expression " + Expression.ToString() + " does not fit in variable " + VariableIdentification.ToString()); } } else { Root.AddError("Expression [" + Expression.ToString() + "] type (" + type.FullName + ") does not match variable [" + VariableIdentification.ToString() + "] type (" + targetType.FullName + ")"); } } } else { Root.AddError("Cannot determine variable type"); } } else { Root.AddError("Cannot determine expression type (3) for " + Expression.ToString()); } } else { Root.AddError("Invalid expression in assignment"); } }
/// <summary> /// Performs the semantic analysis of the expression /// </summary> /// <param name="instance">the reference instance on which this element should analysed</param> /// <param name="expectation">Indicates the kind of element we are looking for</param> /// <returns>True if semantic analysis should be continued</returns> public override bool SemanticAnalysis(INamable instance, BaseFilter expectation) { bool retVal = base.SemanticAnalysis(instance, expectation); if (retVal) { // InitialValue if (InitialValue != null) { InitialValue.SemanticAnalysis(instance, IsRightSide.INSTANCE); StaticUsage.AddUsages(InitialValue.StaticUsage, Usage.ModeEnum.Read); LastIteration.Type = InitialValue.GetExpressionType(); CurrentIteration.Type = InitialValue.GetExpressionType(); StaticUsage.AddUsage(InitialValue.GetExpressionType(), Root, Usage.ModeEnum.Type); } else { AddError("Initial value not provided", RuleChecksEnum.SemanticAnalysisError); } // Expression if (Expression != null) { Expression.SemanticAnalysis(instance, AllMatches.INSTANCE); StaticUsage.AddUsages(Expression.StaticUsage, Usage.ModeEnum.Read); } else { Root.AddError("Accumulator expression value not provided"); } // Condition if (Condition != null) { Condition.SemanticAnalysis(instance, AllMatches.INSTANCE); StaticUsage.AddUsages(Condition.StaticUsage, Usage.ModeEnum.Read); } else { Root.AddError("Stop condition not provided"); } } return(retVal); }
/// <summary> /// Checks the expression and appends errors to the root tree node when inconsistencies are found /// </summary> public override void CheckExpression() { if (Ref is StructureElement) { if (!IsInstance()) { Root.AddError("Invalid expression (" + Ref.FullName + "): structure should not be used to reference an instance"); } } foreach (Expression subExpression in Arguments) { subExpression.CheckExpression(); } base.CheckExpression(); }
/// <summary> /// Checks the expression and appends errors to the root tree node when inconsistencies are found /// </summary> public override void checkExpression() { Types.Structure structureType = Structure.GetExpressionType() as Types.Structure; if (structureType != null) { foreach (KeyValuePair <string, Expression> pair in Associations) { string name = pair.Key; Expression expression = pair.Value; List <Utils.INamable> targets = new List <Utils.INamable>(); structureType.Find(name, targets); if (targets.Count > 0) { expression.checkExpression(); Types.Type type = expression.GetExpressionType(); if (type != null) { foreach (Utils.INamable namable in targets) { Types.ITypedElement element = namable as Types.ITypedElement; if (element != null && element.Type != null) { if (!element.Type.Match(type)) { AddError("Expression " + expression.ToString() + " type (" + type.FullName + ") does not match the target element " + element.Name + " type (" + element.Type.FullName + ")"); } } } } else { AddError("Expression " + expression.ToString() + " type cannot be found"); } } else { Root.AddError("Cannot find " + name + " in structure " + Structure.ToString()); } } } else { AddError("Cannot find structure type " + Structure.ToString()); } }
/// <summary> /// Selects the X and Y axis of the surface to be created according to the function for which the surface need be /// created and the parameters on which the surface is created /// </summary> /// <param name="xParam">The X parameter for which the surface need be created</param> /// <param name="yParam">The Y parameter for which the surface need be created</param> /// <param name="function">The function creating the surface</param> /// <param name="xAxis">The resulting X axis</param> /// <param name="yAxis">The resulting Y axis</param> /// <returns>true if the axis could be selected</returns> private void SelectXandYAxis(Parameter xParam, Parameter yParam, Function function, out Parameter xAxis, out Parameter yAxis) { xAxis = null; yAxis = null; Dictionary <Parameter, Expression> association = GetParameterAssociation(function); if (association != null) { foreach (KeyValuePair <Parameter, Expression> pair in association) { if (pair.Value.Ref == xParam) { if (xAxis == null) { xAxis = pair.Key; } else { Root.AddError("Cannot evaluate surface for function call " + ToString() + " which has more than 1 X axis parameter"); xAxis = null; break; } } if (pair.Value.Ref == yParam) { if (yAxis == null) { yAxis = pair.Key; } else { Root.AddError("Cannot evaluate surface for function call " + ToString() + " which has more than 1 Y axis parameter"); yAxis = null; break; } } } } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public void CheckStatement(InterpretationContext context) { Call.checkExpression(); if (Call != null) { Functions.Procedure procedure = Call.getProcedure(context); if (procedure != null) { } else { Root.AddError("Cannot determine called procedure (2)"); } } else { Root.AddError("Cannot determine called procedure (1)"); } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (Call != null) { Call.CheckExpression(); Procedure procedure = Call.Called.Ref as Procedure; if (procedure == null) { if (Call.Called.Ref is Function) { Root.AddError("Invalid call : Function " + Call.Called + " called as a procedure"); } else { Root.AddError("Cannot determine called procedure " + Call.Called); } } else { if (procedure.Enclosing is Structure) { DerefExpression deref = Call.Called as DerefExpression; if (deref != null) { int count = deref.Arguments.Count; Expression baseExpression = deref.Arguments[count - 2]; INamable referenced = baseExpression.Ref; if ((referenced is NameSpace) || (referenced is Structure && !(baseExpression is Call))) { Root.AddError( "Invalid procedure call : context should be the instance on which the call is performed"); } } } } } else { Root.AddError("Cannot parse called procedure for " + ToString()); } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { Types.Collection targetListType = ListExpression.GetExpressionType() as Types.Collection; if (targetListType == null) { Root.AddError("Cannot determine type of " + ListExpression); } else { if (Condition != null) { Condition.checkExpression(); Types.BoolType conditionType = Condition.GetExpressionType() as Types.BoolType; if (conditionType == null) { Root.AddError("Condition does not evaluates to boolean"); } } } }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { Value.checkExpression(); Types.Collection targetListType = ListExpression.GetExpressionType() as Types.Collection; if (targetListType != null) { Types.Type elementType = Value.GetExpressionType(); if (elementType != targetListType.Type) { Root.AddError("Inserted element type does not corresponds to list type"); } } else { Root.AddError("Cannot determine collection type of " + ListExpression); } if (ReplaceElement != null) { Types.Type replaceElementType = ReplaceElement.GetExpressionType(); if (replaceElementType != null) { if (targetListType.Type != null) { if (replaceElementType != targetListType.Type) { Root.AddError("The replace element type (" + replaceElementType.FullName + ") does not correspond to the list type (" + targetListType.Type.FullName + ")"); } } else { Root.AddError("Cannot determine list element's type for " + targetListType.FullName); } } else { Root.AddError("Cannot determine replacement element type"); } } }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply) { Variables.IVariable variable = ListExpression.GetVariable(context); if (variable != null) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue; variable.Value = listValue; if (listValue != null) { int token = context.LocalScope.PushContext(); context.LocalScope.setVariable(IteratorVariable); foreach (Values.IValue value in listValue.Val) { if (value != EFSSystem.EmptyValue) { IteratorVariable.Value = value; if (conditionSatisfied(context)) { Call.GetChanges(context, changes, explanation, apply); } } } context.LocalScope.PopContext(token); } else { Root.AddError("List expression does not evaluate to a list value"); } } else { Root.AddError("Cannot find variable for " + ListExpression.ToString()); } }
// It returns whether the entity contains references to external entities. public void ScanEntityValue(ArrayList refs) { // To modify this code, beware nesting between this and EntityValue. string value = EntityValue; if (this.SystemId != null) { hasExternalReference = true; } if (recursed) { throw NotWFError("Entity recursion was found."); } recursed = true; if (scanned) { foreach (string referenced in refs) { if (this.ReferencingEntities.Contains(referenced)) { throw NotWFError(String.Format( "Nested entity was found between {0} and {1}", referenced, Name)); } } recursed = false; return; } int len = value.Length; int start = 0; for (int i = 0; i < len; i++) { switch (value [i]) { case '&': start = i + 1; break; case ';': if (start == 0) { break; } string name = value.Substring(start, i - start); if (name.Length == 0) { throw NotWFError("Entity reference name is missing."); } if (name [0] == '#') { break; // character reference } if (XmlChar.GetPredefinedEntity(name) >= 0) { break; // predefined reference } this.ReferencingEntities.Add(name); DTDEntityDeclaration decl = Root.EntityDecls [name]; if (decl != null) { if (decl.SystemId != null) { hasExternalReference = true; } refs.Add(Name); decl.ScanEntityValue(refs); foreach (string str in decl.ReferencingEntities) { ReferencingEntities.Add(str); } refs.Remove(Name); value = value.Remove(start - 1, name.Length + 2); value = value.Insert(start - 1, decl.EntityValue); i -= name.Length + 1; // not +2, because of immediate i++ . len = value.Length; } start = 0; break; } } if (start != 0) #if NET_2_1 { Root.AddError(new XmlSchemaException(this, this.BaseURI, "Invalid reference character '&' is specified.")); } #else { Root.AddError(new XmlSchemaException("Invalid reference character '&' is specified.", this.LineNumber, this.LinePosition, null, this.BaseURI, null)); } #endif scanned = true; recursed = false; }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { VariableIdentification.CheckExpression(); if (VariableIdentification.Ref is Parameter) { Root.AddError("Cannot assign a value to a parameter (" + VariableIdentification + ")"); } if (VariableIdentification.Ref == null) { Root.AddError("Cannot assign a value to " + VariableIdentification); } Type targetType = VariableIdentification.GetExpressionType(); if (targetType == null) { Root.AddError("Cannot determine type of target " + VariableIdentification); } else if (Expression != null) { Expression.CheckExpression(); Type type = Expression.GetExpressionType(); if (type != null) { if (!targetType.Match(type)) { UnaryExpression unaryExpression = Expression as UnaryExpression; if (unaryExpression != null && unaryExpression.Term.LiteralValue != null) { Root.AddError("Expression " + Expression + " does not fit in variable " + VariableIdentification); } else { Root.AddError("Expression [" + Expression + "] type (" + type.FullName + ") does not match variable [" + VariableIdentification + "] type (" + targetType.FullName + ")"); } } else { Range rangeType = targetType as Range; if (rangeType != null) { IValue value = Expression.Ref as IValue; if (value != null) { if (rangeType.convert(value) == null) { Root.AddError("Cannot set " + value.LiteralName + " in variable of type " + rangeType.Name); } } } } if (Expression.Ref == EfsSystem.Instance.EmptyValue) { if (targetType is Collection) { Root.AddError("Assignation of " + Expression.Ref.Name + " cannot be performed on variables of type collection. Use [] instead."); } } } else { Root.AddError("Cannot determine expression type (3) for " + Expression); } } else { Root.AddError("Invalid expression in assignment"); } // Check that the incoming variables are not modified if (EnclosingFinder <DataDictionary.Types.NameSpace> .find(Root, true) != null) { IVariable variable = VariableIdentification.Ref as IVariable; if (variable != null && variable.Mode == acceptor.VariableModeEnumType.aIncoming) { Root.AddError("An incoming variable cannot be written"); } } }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> /// <param name="runner"></param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply, Runner runner) { // Explain what happens in this statement explanation = ExplanationPart.CreateSubExplanation(explanation, this); IVariable variable = ListExpression.GetVariable(context); if (variable != null) { if (variable.Value != EfsSystem.Instance.EmptyValue) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue; variable.Value = listValue; ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue); if (listValue != null) { int token = context.LocalScope.PushContext(); context.LocalScope.SetVariable(IteratorVariable); bool elementFound = false; bool matchingElementFound = false; foreach (IValue value in listValue.Val) { if (value != EfsSystem.Instance.EmptyValue) { // All elements should always be != from EmptyValue elementFound = true; IteratorVariable.Value = value; if (ConditionSatisfied(context, explanation)) { matchingElementFound = true; AppliedStatement.GetChanges(context, changes, explanation, apply, runner); } } } if (!elementFound) { ExplanationPart.CreateSubExplanation(explanation, "Empty collection"); } else if (!matchingElementFound) { ExplanationPart.CreateSubExplanation(explanation, "No matching element found"); } context.LocalScope.PopContext(token); } else { Root.AddError("List expression does not evaluate to a list value"); } } } else { Root.AddError("Cannot find variable for " + ListExpression); } }
/// <summary> /// Creates the graph associated to this expression, when the given parameter ranges over the X axis /// </summary> /// <param name="context">The interpretation context</param> /// <param name="parameter">The parameters of *the enclosing function* for which the graph should be created</param> /// <param name="explain"></param> /// <returns></returns> public override Graph CreateGraph(InterpretationContext context, Parameter parameter, ExplanationPart explain) { Graph retVal = base.CreateGraph(context, parameter, explain); Cast cast = Called.Ref as Cast; if (cast != null) { // In case of cast, just take the graph of the enclosed expression Parameter param = (Parameter)cast.FormalParameters[0]; retVal = cast.CreateGraphForParameter(context, param, explain); } else { Function calledFunction = Called.Ref as Function; Dictionary <Parameter, Expression> parameterAssociation; if (calledFunction == null) { calledFunction = Called.GetValue(context, explain) as Function; parameterAssociation = CreateParameterAssociation(calledFunction); } else { parameterAssociation = ParameterAssociation; } if (calledFunction != null) { Parameter xAxis = null; foreach (KeyValuePair <Parameter, Expression> pair in parameterAssociation) { if (pair.Value.Ref == parameter) { if (xAxis == null) { xAxis = pair.Key; } else { Root.AddError("Cannot evaluate graph for function call " + ToString() + " which has more than 1 parameter used as X axis"); xAxis = null; break; } } } int token = context.LocalScope.PushContext(); calledFunction.AssignParameters(context, AssignParameterValues(context, calledFunction, false, explain)); if (xAxis != null) { retVal = calledFunction.CreateGraphForParameter(context, xAxis, explain); } else { retVal = Function.CreateGraphForValue(GetValue(context, explain)); } context.LocalScope.PopContext(token); } else { AddError("Cannot determine called function", RuleChecksEnum.SemanticAnalysisError); } } return(retVal); }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> /// <param name="runner"></param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply, Runner runner) { // Explain what happens in this statement explanation = ExplanationPart.CreateSubExplanation(explanation, this); int index = context.LocalScope.PushContext(); context.LocalScope.SetVariable(IteratorVariable); IVariable variable = ListExpression.GetVariable(context); if (variable != null) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue; variable.Value = listValue; if (listValue != null) { // Provide the state of the list before removing elements from it ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue); ListValue newListValue = new ListValue(listValue); int i = 0; foreach (IValue current in newListValue.Val) { IteratorVariable.Value = current; if (ConditionSatisfied(context, explanation)) { break; } i += 1; } if (i < newListValue.Val.Count) { IValue value = Value.GetExpressionValue(context, explanation); if (value != null) { newListValue.Val[i] = value; Change change = new Change(variable, variable.Value, newListValue); changes.Add(change, apply, runner); ExplanationPart.CreateSubExplanation(explanation, Root, change); } else { Root.AddError("Cannot find value for " + Value); } } else { Root.AddError("Cannot find value in " + ListExpression + " which satisfies " + Condition); } } else { Root.AddError("Variable " + ListExpression + " does not contain a list value"); } } else { Root.AddError("Cannot find variable for " + ListExpression); } context.LocalScope.PopContext(index); }
/// <summary> /// Provides the changes performed by this statement /// </summary> /// <param name="context">The context on which the changes should be computed</param> /// <param name="changes">The list to fill with the changes</param> /// <param name="explanation">The explanatino to fill, if any</param> /// <param name="apply">Indicates that the changes should be applied immediately</param> public override void GetChanges(InterpretationContext context, ChangeList changes, ExplanationPart explanation, bool apply) { Variables.IVariable variable = ListExpression.GetVariable(context); if (variable != null) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation Values.ListValue listValue = variable.Value.RightSide(variable, false) as Values.ListValue; variable.Value = listValue; if (listValue != null) { Values.IValue value = Value.GetValue(context); if (value != null) { Values.ListValue newListValue = new Values.ListValue(listValue); int index = newListValue.Val.IndexOf(EFSSystem.EmptyValue); if (index >= 0) { newListValue.Val[index] = value; } else { // List is full, try to remove an element before inserting the new element if (ReplaceElement != null) { Values.IValue removeValue = ReplaceElement.GetValue(context); index = newListValue.Val.IndexOf(removeValue); if (index >= 0) { newListValue.Val[index] = value; } else { Root.AddError("Cannot remove replacing element " + removeValue.Name); } } else { Root.AddError("Cannot add new element in list value : list is full"); } } Rules.Change change = new Rules.Change(variable, variable.Value, newListValue); changes.Add(change, apply); explanation.SubExplanations.Add(new ExplanationPart(Root, change)); } else { Root.AddError("Cannot find value for " + Value.ToString()); } } else { Root.AddError("Variable " + ListExpression.ToString() + " does not contain a list value"); } } else { Root.AddError("Cannot find variable for " + ListExpression.ToString()); } }
/// <summary> /// Evaluates the current input as a list /// </summary> /// <param name="root">the root element for which this list is built</param> /// <returns></returns> public ListExpression EvaluateList() { ListExpression retVal = null; int backup = Index; if (LookAhead("[")) { Match("["); List <Expression> list = new List <Expression>(); Types.Type elementType = null; if (LookAhead("]")) { Match("]"); retVal = new ListExpression(Root, list); } else { bool cont = true; while (cont) { Expression expression = Expression(0); if (expression != null) { list.Add(expression); if (LookAhead(",")) { Match(","); continue; } else if (LookAhead("]")) { Match("]"); retVal = new ListExpression(Root, list); break; } else { Root.AddError("] expected"); break; } } else { Root.AddError("Cannot parse expression"); break; } } } } if (retVal == null) { Index = backup; } return(retVal); }
/// <summary> /// Provides the change for this insert statement /// </summary> /// <param name="context"></param> /// <param name="variable"></param> /// <param name="explanation"></param> /// <param name="apply"></param> /// <param name="runner"></param> /// <returns></returns> public Change GetChange(InterpretationContext context, IVariable variable, ExplanationPart explanation, bool apply, Runner runner) { Change retVal = null; // Explain what happens in this statement explanation = ExplanationPart.CreateSubExplanation(explanation, this); if (variable != null) { // HacK : ensure that the value is a correct rigth side // and keep the result of the right side operation ListValue listValue = variable.Value.RightSide(variable, false, false) as ListValue; variable.Value = listValue; if (listValue != null) { ExplanationPart.CreateSubExplanation(explanation, "Input data = ", listValue); IValue value = Value.GetExpressionValue(context, explanation); if (value != null) { if (!listValue.Val.Contains(value)) { ListValue newListValue = new ListValue(listValue); if (newListValue.Val.Count < newListValue.CollectionType.getMaxSize()) { ExplanationPart.CreateSubExplanation(explanation, "Inserting", value); newListValue.Val.Add(value.RightSide(variable, true, true)); } else { // List is full, try to remove an element before inserting the new element if (ReplaceElement != null) { IValue removeValue = ReplaceElement.GetExpressionValue(context, explanation); ExplanationPart.CreateSubExplanation(explanation, "Replaced element", removeValue); int index = newListValue.Val.IndexOf(removeValue); if (index >= 0) { ExplanationPart.CreateSubExplanation(explanation, "Replacing", value); newListValue.Val[index] = value.RightSide(variable, true, true); } else { Root.AddError("Cannot remove replacing element " + removeValue.Name); } } else { Root.AddError("Cannot add new element in list value : list is full"); } } retVal = new Change(variable, variable.Value, newListValue); ExplanationPart.CreateSubExplanation(explanation, Root, retVal); } else { ExplanationPart.CreateSubExplanation(explanation, "NOT added : Already present in collection", value); } } else { Root.AddError("Cannot find value for " + Value); } } else { Root.AddError("Variable " + ListExpression + " does not contain a list value"); } } else { Root.AddError("Cannot find variable for " + ListExpression); } return(retVal); }
/// <summary> /// Evaluates the current input as a structure /// </summary> /// <returns></returns> public Expression EvaluateStructure() { StructExpression retVal = null; int backup = Index; Expression structureId = DerefExpression(); if (structureId != null) { if (LookAhead("{")) { Match("{"); Dictionary <string, Expression> associations = new Dictionary <string, Interpreter.Expression>(); if (LookAhead("}")) { Match("}"); retVal = new StructExpression(Root, structureId, associations); } else { while (true) { string id = Identifier(); if (id != null) { Match("=>"); Expression expression = Expression(0); if (expression != null) { associations[id] = expression; } else { Root.AddError("Cannot parse expression after " + id + " => "); break; } } else { if (Index < Buffer.Length) { Root.AddError("Identifier expected, but found " + Buffer[Index]); } else { Root.AddError("Identifier expected, but EOF found "); } break; } if (LookAhead(",")) { Match(","); continue; } else if (LookAhead("}")) { Match("}"); retVal = new StructExpression(Root, structureId, associations); break; } else { if (Index < Buffer.Length) { Root.AddError(", or } expected, but found " + Buffer[Index]); } else { Root.AddError(", or } expected, but EOF found "); } break; } } } } } if (retVal == null) { Index = backup; } return(retVal); }
/// <summary> /// Checks the statement for semantical errors /// </summary> public override void CheckStatement() { if (ListExpression != null) { ListExpression.CheckExpression(); if (ListExpression.Ref is Parameter) { Root.AddError("Cannot change the list value which is a parameter (" + ListExpression + ")"); } Collection targetListType = ListExpression.GetExpressionType() as Collection; if (targetListType != null) { if (Value != null) { Type elementType = Value.GetExpressionType(); if (elementType != targetListType.Type) { Root.AddError("Inserted element type does not corresponds to list type"); } } if (ReplaceElement != null) { ReplaceElement.CheckExpression(); Type replaceElementType = ReplaceElement.GetExpressionType(); if (replaceElementType != null) { if (targetListType.Type != null) { if (replaceElementType != targetListType.Type) { Root.AddError("The replace element type (" + replaceElementType.FullName + ") does not correspond to the list type (" + targetListType.Type.FullName + ")"); } } else { Root.AddError("Cannot determine list element's type for " + targetListType.FullName); } } else { Root.AddError("Cannot determine replacement element type"); } } } else { Root.AddError("Cannot determine collection type of " + ListExpression); } } else { Root.AddError("List should be specified"); } if (Value != null) { Value.CheckExpression(); } else { Root.AddError("Value should be specified"); } }