protected override IExpression ConvertAssign(IAssignExpression iae) { // set index variables on the converted target, using the unconverted lhs indices // this code is copied from ModelAnalysisTransform IAssignExpression ae = (IAssignExpression)base.ConvertAssign(iae); IParameterDeclaration ipd = null; IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ae.Target); if (ivd == null) { ipd = Recognizer.GetParameterDeclaration(ae.Target); if (ipd == null) { return(ae); } } if (iae.Target is IArrayIndexerExpression) { // Gather index variables from the left-hand side of the assignment object decl = (ipd == null) ? (object)ivd : ipd; VariableInformation vi = VariableInformation.GetVariableInformation(context, decl); try { List <IVariableDeclaration[]> indVars = new List <IVariableDeclaration[]>(); Recognizer.AddIndexers(context, indVars, iae.Target); // Sets the size of this variable at this array depth int depth = Recognizer.GetIndexingDepth(iae.Target); // if this statement is actually a constraint, then we don't need to enforce matching of index variables bool isConstraint = context.InputAttributes.Has <Models.Constraint>(context.FindAncestor <IStatement>()); for (int i = 0; i < depth; i++) { vi.SetIndexVariablesAtDepth(i, indVars[i], allowMismatch: isConstraint); } } catch (Exception ex) { Error(ex.Message, ex); } if (!context.InputAttributes.Has <VariableInformation>(decl)) { context.InputAttributes.Set(decl, vi); } } return(ae); }
protected override IExpression ConvertAssign(IAssignExpression iae) { IParameterDeclaration ipd = null; IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iae.Target); object decl = ivd; if (ivd == null) { ipd = Recognizer.GetParameterDeclaration(iae.Target); if (ipd == null) { return(base.ConvertAssign(iae)); } decl = ipd; } if (iae.Target is IArrayIndexerExpression) { // Gather index variables from the left-hand side of the assignment VariableInformation vi = VariableInformation.GetVariableInformation(context, decl); try { List <IVariableDeclaration[]> indVars = new List <IVariableDeclaration[]>(); Recognizer.AddIndexers(context, indVars, iae.Target); int depth = Recognizer.GetIndexingDepth(iae.Target); // if this statement is actually a constraint, then we don't need to enforce matching of index variables bool isConstraint = context.InputAttributes.Has <Models.Constraint>(context.FindAncestor <IStatement>()); for (int i = 0; i < depth; i++) { vi.SetIndexVariablesAtDepth(i, indVars[i], allowMismatch: isConstraint); } } catch (Exception ex) { Error(ex.Message, ex); } } IAssignExpression ae = (IAssignExpression)base.ConvertAssign(iae); if (ipd == null) { // assignment to a local variable if (ae.Expression is IMethodInvokeExpression) { IMethodInvokeExpression imie = (IMethodInvokeExpression)ae.Expression; // this unfortunately duplicates some of the work done by SetStoch and IsStoch. FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, imie); if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd)) { context.InputAttributes.Set(ivd, new DerivedVariable()); } } if (ae.Expression is ILiteralExpression) { bool isLoopInitializer = (Recognizer.GetAncestorIndexOfLoopBeingInitialized(context) != -1); if (!isLoopInitializer) { Type valueType = ae.Expression.GetExpressionType(); if (Quoter.ShouldInlineType(valueType)) { // inline all future occurrences of this variable with the rhs expression conditionContext.Add(new ConditionBinding(ae.Target, ae.Expression)); } } } } else { // assignment to a method parameter IStatement ist = context.FindAncestor <IStatement>(); if (!context.InputAttributes.Has <Models.Constraint>(ist)) { // mark this statement as a constraint context.OutputAttributes.Set(ist, new Models.Constraint()); } } // a FactorAlgorithm attribute on a variable turns into an Algorithm attribute on its right hand side. var attr = context.InputAttributes.Get <FactorAlgorithm>(decl); if (attr != null) { context.OutputAttributes.Set(ae.Expression, new Algorithm(attr.algorithm)); } context.InputAttributes.CopyObjectAttributesTo <GivePriorityTo>(decl, context.OutputAttributes, ae.Expression); return(ae); }