protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { bool isDef = Recognizer.IsBeingMutated(context, ivre); RegisterDepth(ivre, isDef); return(ivre); }
private IExpression GetMessageExpression(IExpression expr, IDictionary <IVariableDeclaration, IVariableDeclaration> msgVars) { if (expr is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)expr; IVariableDeclaration ivd = ivre.Variable.Resolve(); IVariableDeclaration msgVar; if (msgVars.TryGetValue(ivd, out msgVar)) { return(Builder.VarRefExpr(msgVar)); } else { return(null); } } else if (expr is IArrayIndexerExpression) { IArrayIndexerExpression iaie = (IArrayIndexerExpression)expr; IExpression targetMsg = GetMessageExpression(iaie.Target, msgVars); if (targetMsg == null) { return(null); } else { return(Builder.ArrayIndex(targetMsg, iaie.Indices)); } } else { throw new ArgumentException("Unrecognized method argument expression"); } }
public static Set <IVariableDeclaration> GetConditionedLoopVariables(BasicTransformContext context) { Set <IVariableDeclaration> loopVars = new Set <IVariableDeclaration>(); foreach (IConditionStatement ics in context.FindAncestors <IConditionStatement>()) { ConditionBinding binding = new ConditionBinding(ics.Condition); if (binding.lhs is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.lhs; if (Recognizer.GetLoopForVariable(context, ivre) != null) { loopVars.Add(Recognizer.GetVariableDeclaration(ivre)); } } if (binding.rhs is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)binding.rhs; if (Recognizer.GetLoopForVariable(context, ivre) != null) { loopVars.Add(Recognizer.GetVariableDeclaration(ivre)); } } } return(loopVars); }
/// <summary> /// Converts a variable reference. /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { if (Recognizer.IsBeingMutated(context, ivre)) { return(ivre); } else if (Recognizer.IsBeingIndexed(context)) { return(ivre); } IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre); if (ivd == null) { return(ivre); } VariableToChannelInformation vtci; if (usesOfVariable.TryGetValue(ivd, out vtci)) { if (vtci.usageDepth != 0) { Error("wrong usageDepth (" + vtci.usageDepth + " instead of 0)"); } return(Builder.ArrayIndex(Builder.VarRefExpr(vtci.usesDecl), Builder.LiteralExpr(GetUseNumber(ivd, vtci)))); } return(ivre); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { foreach (ConditionBinding binding in iterationContext) { if (binding.lhs.Equals(ivre)) { return(binding.rhs); } } IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre); UnrolledVar v; if (unrolledVars.TryGetValue(ivd, out v)) { Set <ConditionBinding> bindings = new Set <ConditionBinding>(); foreach (ConditionBinding binding in iterationContext) { if (v.loopVars.Contains(binding.lhs)) { bindings.Add(binding); } } if (!v.clones.ContainsKey(bindings)) { Error(ivre + " not defined in context " + bindings); return(ivre); } IVariableDeclaration clone = v.clones[bindings]; return(Builder.VarRefExpr(clone)); } return(ivre); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { bool isPartOfLhs = Recognizer.IsBeingMutated(context, ivre); AddUsage(ivre, isPartOfLhs); return(base.ConvertVariableRefExpr(ivre)); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { bool isDef = Recognizer.IsBeingMutated(context, ivre); if (isDef) { return(ivre); } return(GetClone(ivre)); }
/// <summary> /// Modify the argument of Infer to be the marginal channel variable i.e. Infer(a) transforms to Infer(a_marginal). /// </summary> /// <param name="imie"></param> /// <returns></returns> protected IExpression ConvertInfer(IMethodInvokeExpression imie) { IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression; if (ivre == null) { //Error("Argument to Infer() must be a variable reference, was " + imie.Arguments[0] + "."); return(imie); } // Find expression for the marginal of interest IVariableDeclaration ivd = ivre.Variable.Resolve(); VariableToChannelInformation vtci = context.InputAttributes.Get <VariableToChannelInformation>(ivd); if (vtci == null) { return(imie); // The argument is constant } ExpressionEvaluator eval = new ExpressionEvaluator(); QueryType query = (QueryType)eval.Evaluate(imie.Arguments[2]); IVariableDeclaration inferDecl = null; if (query == QueryTypes.Marginal) { inferDecl = vtci.marginalChannel.decl; } else if (query == QueryTypes.Samples) { inferDecl = vtci.samplesChannel.decl; } else if (query == QueryTypes.Conditionals) { inferDecl = vtci.conditionalsChannel.decl; } else { return(imie); // Error("Unrecognized query '"+query+"'"); } IMethodInvokeExpression mie = Builder.MethodInvkExpr(); mie.Method = imie.Method; mie.Arguments.Add(Builder.VarRefExpr(inferDecl)); for (int i = 1; i < imie.Arguments.Count; i++) { mie.Arguments.Add(imie.Arguments[i]); } // move the IsInferred attribute to the inferred channel context.OutputAttributes.Remove <IsInferred>(ivd); if (!context.OutputAttributes.Has <IsInferred>(inferDecl)) { context.OutputAttributes.Set(inferDecl, new IsInferred()); context.OutputAttributes.Add(inferDecl, new QueryTypeCompilerAttribute(query)); } return(mie); }
/// <summary> /// Modify variable references that can be replaced by other variables. /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { // should not convert if on LHS IExpression copyExpr = GetCopyExpr(ivre); if (copyExpr != null) { return(copyExpr); } return(ivre); }
/// <summary> /// Modify variable references that can be replaced by other variables. /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { // should not convert if on LHS IExpression copyExpr = GetCopyExpr(ivre); if (copyExpr != null && CanBeReplacedBy(ivre, copyExpr.GetExpressionType())) { return(copyExpr); } else { return(ivre); } }
public override bool Equals(object obj) { if (this == obj) { return(true); } IVariableReferenceExpression expressionRef = obj as IVariableReferenceExpression; if (expressionRef == null) { return(false); } return(this.Variable.Equals(expressionRef.Variable.Resolve())); }
/// <summary> /// Register a use of a variable without indices /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { IExpression expr = base.ConvertVariableRefExpr(ivre); if (Recognizer.IsBeingIndexed(context) || Recognizer.IsBeingMutated(context, expr)) { return(expr); } IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(expr); if (usageInfo.TryGetValue(ivd, out UsageInfo info)) { info.indexingDepths.Add(0); RegisterUse(info, expr); } return(expr); }
public static IVariableDeclaration GetVariable(IExpression exp) { IVariableDeclarationExpression exp_var_decl = exp as IVariableDeclarationExpression; if (exp_var_decl != null) { return(exp_var_decl.Variable); } IVariableReferenceExpression exp_var_ref = exp as IVariableReferenceExpression; if (exp_var_ref != null) { return(exp_var_ref.Variable.Resolve()); } return(null); }
/// <summary> /// Converts references to variables which were declared inside loops, by adding indexing as appropriate. /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre); LoopVarInfo lvi; if (!loopVarInfos.TryGetValue(ivd, out lvi)) { return(ivre); } IExpression expr = Builder.VarRefExpr(lvi.arrayvd); for (int i = 0; i < lvi.indexVarRefs.Length; i++) { expr = Builder.ArrayIndex(expr, lvi.indexVarRefs[i]); } context.InputAttributes.CopyObjectAttributesTo(ivre, context.OutputAttributes, expr); return(expr); }
/// <summary> /// Converts a variable reference. /// </summary> /// <param name="ivre"></param> /// <returns></returns> protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { IVariableDeclaration ivd = ivre.Variable.Resolve(); VariableToChannelInformation vtci = Context.InputAttributes.Get <VariableToChannelInformation>(ivd); // If deterministic variable do nothing. if (vtci == null || vtci.usageChannel == null) { return(ivre); } else if (Recognizer.IsBeingIndexed(context)) { return(ivre); } else if (Recognizer.IsBeingMutated(context, ivre)) { return(ivre); } else { return(vtci.usageChannel.ReplaceWithUsesChannel(ivre, Builder.LiteralExpr(vtci.shareAllUses ? 0 : vtci.useCount++))); } }
/// <summary> /// Modify the argument of Infer to be the marginal channel variable i.e. Infer(a) transforms to Infer(a_marginal) /// </summary> /// <param name="imie"></param> /// /// <returns>The modified expression</returns> protected IExpression ConvertInfer(IMethodInvokeExpression imie) { IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression; if (ivre == null) { //Error("Argument to Infer() must be a variable reference, was " + imie.Arguments[0] + "."); return(imie); } // Find expression for the marginal of interest IVariableDeclaration ivd = ivre.Variable.Resolve(); IVariableDeclaration marginalDecl; ExpressionEvaluator eval = new ExpressionEvaluator(); QueryType query = (imie.Arguments.Count < 3) ? null : (QueryType)eval.Evaluate(imie.Arguments[2]); bool isOutput = (query == QueryTypes.MarginalDividedByPrior); Dictionary <IVariableDeclaration, IVariableDeclaration> dict = isOutput ? useOfVariable : marginalOfVariable; if (!dict.TryGetValue(ivd, out marginalDecl)) { return(imie); // The argument is constant } IMethodInvokeExpression mie = Builder.MethodInvkExpr(); mie.Method = imie.Method; mie.Arguments.Add(Builder.VarRefExpr(marginalDecl)); for (int i = 1; i < imie.Arguments.Count; i++) { mie.Arguments.Add(imie.Arguments[i]); } // move the IsInferred attribute to the marginal channel //context.OutputAttributes.Remove<IsInferred>(ivd); if (!context.OutputAttributes.Has <IsInferred>(marginalDecl)) { context.OutputAttributes.Set(marginalDecl, new IsInferred()); } return(mie); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { if (Recognizer.IsBeingMutated(context, ivre)) { return(ivre); } IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(ivre); if (ivd == null) { return(ivre); } if (!variablesAssigned.Contains(ivd)) { Error(ivd + " is used before it is assigned to"); } IVariableDeclaration useDecl; if (useOfVariable.TryGetValue(ivd, out useDecl)) { return(Builder.VarRefExpr(useDecl)); } return(ivre); }
// Shallow copy variable references for efficiency protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { return ConvertWithReplication(ivre); }
private void WriteVariableReferenceExpression(IVariableReferenceExpression expression, IFormatter formatter) { this.WriteVariableReference(expression.Variable, formatter); }
protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie) { IExpression converted = base.ConvertMethodInvoke(imie); if (converted is IMethodInvokeExpression mie) { if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, ICompilerAttribute, PlaceHolder>(Attrib.Var))) { IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression; IVariableDeclaration target = ivre.Variable.Resolve(); IExpression expr = imie.Arguments[1]; AddAttribute(target, expr); return(null); } else if (Recognizer.IsStaticMethod(imie, new Action <object, object>(Attrib.InitialiseTo))) { IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression; IVariableDeclaration target = ivre.Variable.Resolve(); context.OutputAttributes.Set(target, new InitialiseTo(imie.Arguments[1])); return(null); } else if (CodeRecognizer.IsInfer(imie)) { // the arguments must not be substituted for their values, so we don't call ConvertExpression IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(imie.Arguments[0]); if (ivd != null) { var vi = VariableInformation.GetVariableInformation(context, ivd); QueryType query = (imie.Arguments.Count < 3) ? null : (QueryType)evaluator.Evaluate(imie.Arguments[2]); vi.NeedsMarginalDividedByPrior = (query == QueryTypes.MarginalDividedByPrior); } return(imie); } bool anyArgumentIsLiteral = mie.Arguments.Any(arg => arg is ILiteralExpression); if (anyArgumentIsLiteral) { if (Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.And))) { if (mie.Arguments.Any(arg => arg is ILiteralExpression ile && ile.Value.Equals(false))) { return(Builder.LiteralExpr(false)); } // any remaining literals must be true, and therefore can be ignored. var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression)); if (reducedArguments.Count() == 1) { return(reducedArguments.First()); } else { return(Builder.LiteralExpr(true)); } } else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.Or))) { if (mie.Arguments.Any(arg => arg is ILiteralExpression ile && ile.Value.Equals(true))) { return(Builder.LiteralExpr(true)); } // any remaining literals must be false, and therefore can be ignored. var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression)); if (reducedArguments.Count() == 1) { return(reducedArguments.First()); } else { return(Builder.LiteralExpr(false)); } } else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool>(Factors.Factor.Not))) { bool allArgumentsAreLiteral = mie.Arguments.All(arg => arg is ILiteralExpression); if (allArgumentsAreLiteral) { return(Builder.LiteralExpr(evaluator.Evaluate(mie))); } } } } return(converted); }
public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression value) { this.VisitVariableReference(value.Variable); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { liveVariables.Add(ivre.Variable.Variable); return(base.ConvertVariableRefExpr(ivre)); }
//=========================================================== // Expression 分岐 //=========================================================== public virtual void WriteExpression(IExpression expression) { if (expression == null) { return; } mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, false); #if FALSE #pragma warning disable 612 IMemberInitializerExpression expression3 = expression as IMemberInitializerExpression; if (expression3 != null) { this.WriteMemberInitializerExpression(expression3); return; } IAddressOutExpression expression27 = expression as IAddressOutExpression; if (expression27 != null) { this.WriteAddressOutExpression(expression27); return; } IAddressReferenceExpression expression26 = expression as IAddressReferenceExpression; if (expression26 != null) { this.WriteAddressReferenceExpression(expression26); return; } IDelegateCreateExpression iDelegateCreateExpression = expression as IDelegateCreateExpression; if (iDelegateCreateExpression != null) { this.WriteDelegateCreateExpression(iDelegateCreateExpression); return; } IMethodInvokeExpression iMethodInvokeExpression = expression as IMethodInvokeExpression; if (iMethodInvokeExpression != null) { this.WriteMethodInvokeExpression(iMethodInvokeExpression); return; } IVariableDeclarationExpression expression15 = expression as IVariableDeclarationExpression; if (expression15 != null) { this.WriteVariableDeclaration(expression15.Variable); return; } ITypeOfExpression iTypeOfExpression = expression as ITypeOfExpression; if (iTypeOfExpression != null) { this.WriteTypeOfExpression(iTypeOfExpression); return; } ISnippetExpression iSnippetExpression = expression as ISnippetExpression; if (iSnippetExpression != null) { this.WriteSnippetExpression(iSnippetExpression); return; } IUnaryExpression iUnaryExpression = expression as IUnaryExpression; if (iUnaryExpression != null) { this.WriteUnaryExpression(iUnaryExpression); return; } IObjectCreateExpression iObjectCreateExpression = expression as IObjectCreateExpression; if (iObjectCreateExpression != null) { this.WriteObjectCreateExpression(iObjectCreateExpression); return; } IVariableReferenceExpression iVariableReferenceExpression = expression as IVariableReferenceExpression; if (iVariableReferenceExpression != null) { this.WriteVariableReferenceExpression(iVariableReferenceExpression); return; } IThisReferenceExpression expression12 = expression as IThisReferenceExpression; if (expression12 != null) { this.WriteThisReferenceExpression(expression12); return; } ITryCastExpression iTryCastExpression = expression as ITryCastExpression; if (iTryCastExpression != null) { this.WriteTryCastExpression(iTryCastExpression); return; } IConditionExpression expression9 = expression as IConditionExpression; if (expression9 != null) { this.WriteConditionExpression(expression9); return; } IFieldReferenceExpression iFieldReferenceExpression = expression as IFieldReferenceExpression; if (iFieldReferenceExpression != null) { this.WriteFieldReferenceExpression(iFieldReferenceExpression); return; } IPropertyIndexerExpression iPropertyIndexerExpression = expression as IPropertyIndexerExpression; if (iPropertyIndexerExpression != null) { this.WritePropertyIndexerExpression(iPropertyIndexerExpression); return; } ITypeReferenceExpression iTypeReferenceExpression = expression as ITypeReferenceExpression; if (iTypeReferenceExpression != null) { this.WriteTypeReferenceExpression(iTypeReferenceExpression); return; } IMethodReferenceExpression iMethodReferenceExpression = expression as IMethodReferenceExpression; if (iMethodReferenceExpression != null) { this.WriteMethodReferenceExpression(iMethodReferenceExpression); return; } IPropertyReferenceExpression iPropertyReferenceExpression = expression as IPropertyReferenceExpression; if (iPropertyReferenceExpression != null) { this.WritePropertyReferenceExpression(iPropertyReferenceExpression); return; } ICastExpression expression5 = expression as ICastExpression; if (expression5 != null) { this.WriteCastExpression(expression5); return; } ICanCastExpression iCanCastExpression = expression as ICanCastExpression; if (iCanCastExpression != null) { this.WriteCanCastExpression(iCanCastExpression); return; } ICastExpression iCastExpression = expression as ICastExpression; if (iCastExpression != null) { this.WriteCastExpression(iCastExpression); return; } ILiteralExpression literalExpression = expression as ILiteralExpression; if (literalExpression != null) { this.WriteLiteralExpression(literalExpression); return; } IBinaryExpression iBinaryExpression = expression as IBinaryExpression; if (iBinaryExpression != null) { mwg.Reflector.CppCli.ExpressionWriter.WriteExpression(this, expression, true); //this.WriteBinaryExpression(iBinaryExpression); return; } IArrayIndexerExpression expression30 = expression as IArrayIndexerExpression; if (expression30 != null) { this.WriteArrayIndexerExpression(expression30); return; } IAddressDereferenceExpression expression29 = expression as IAddressDereferenceExpression; if (expression29 != null) { this.WriteAddressDereferenceExpression(expression29); return; } IAddressOfExpression expression28 = expression as IAddressOfExpression; if (expression28 != null) { this.WriteAddressOfExpression(expression28); return; } IArgumentListExpression expression25 = expression as IArgumentListExpression; if (expression25 != null) { this.WriteArgumentListExpression(expression25); return; } IBaseReferenceExpression iBaseReferenceExpression = expression as IBaseReferenceExpression; if (iBaseReferenceExpression != null) { this.WriteBaseReferenceExpression(iBaseReferenceExpression); return; } IArgumentReferenceExpression expression13 = expression as IArgumentReferenceExpression; if (expression13 != null) { this.WriteArgumentReferenceExpression(expression13); return; } IArrayCreateExpression expression10 = expression as IArrayCreateExpression; if (expression10 != null) { this.WriteArrayCreateExpression(expression10); return; } IAssignExpression iAssignExpression = expression as IAssignExpression; if (iAssignExpression != null) { this.WriteAssignExpression(iAssignExpression); return; } IBlockExpression expression2 = expression as IBlockExpression; if (expression2 != null) { this.WriteBlockExpression(expression2); return; } #pragma warning restore 612 this.Write(expression.ToString()); #endif }
public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression value) { VisitVariableReference(value.Variable); }
protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie) { IExpression result = base.ConvertMethodInvoke(imie); if (result is IMethodInvokeExpression) { imie = (IMethodInvokeExpression)result; } else { return(result); } if (UseJaggedSubarray && Recognizer.IsStaticGenericMethod(imie, new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, IReadOnlyList <PlaceHolder> >(Collection.Subarray))) { // check for the form Subarray(arrayExpr, indices[i]) where arrayExpr does not depend on i IExpression arrayExpr = imie.Arguments[0]; IExpression arg1 = imie.Arguments[1]; if (arg1 is IArrayIndexerExpression) { IArrayIndexerExpression index = (IArrayIndexerExpression)arg1; if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression) { // index has the form indices[i] List <IStatement> targetLoops = Containers.GetLoopsNeededForExpression(context, arrayExpr, -1, false); List <IStatement> indexLoops = Containers.GetLoopsNeededForExpression(context, index.Target, -1, false); Set <IStatement> parentLoops = new Set <IStatement>(); parentLoops.AddRange(targetLoops); parentLoops.AddRange(indexLoops); IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0]; IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex); foreach (IStatement loop in parentLoops) { if (Containers.ContainersAreEqual(loop, innerLoop)) { // arrayExpr depends on i return(imie); } } IVariableDeclaration arrayVar = Recognizer.GetVariableDeclaration(arrayExpr); // If the variable is not stochastic, return if (arrayVar == null) { return(imie); } VariableInformation arrayInfo = VariableInformation.GetVariableInformation(context, arrayVar); if (!arrayInfo.IsStochastic) { return(imie); } object indexVar = Recognizer.GetDeclaration(index); VariableInformation indexInfo = VariableInformation.GetVariableInformation(context, indexVar); int depth = Recognizer.GetIndexingDepth(index); IExpression resultSize = indexInfo.sizes[depth][0]; var indices = Recognizer.GetIndices(index); int replaceCount = 0; resultSize = indexInfo.ReplaceIndexVars(context, resultSize, indices, null, ref replaceCount); indexInfo.DefineIndexVarsUpToDepth(context, depth + 1); IVariableDeclaration resultIndex = indexInfo.indexVars[depth][0]; Type arrayType = arrayExpr.GetExpressionType(); Type elementType = Util.GetElementType(arrayType); // create a new variable arrayExpr_indices = JaggedSubarray(arrayExpr, indices) string name = ToString(arrayExpr) + "_" + ToString(index.Target); var stmts = Builder.StmtCollection(); var arrayIndices = Recognizer.GetIndices(arrayExpr); var bracket = Builder.ExprCollection(); bracket.Add(Builder.ArrayIndex(index, Builder.VarRefExpr(resultIndex))); arrayIndices.Add(bracket); IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop); IVariableDeclaration temp = arrayInfo.DeriveArrayVariable(stmts, context, name, resultSize, resultIndex, arrayIndices); VariableInformation tempInfo = VariableInformation.GetVariableInformation(context, temp); stmts.Clear(); IVariableDeclaration newvd = tempInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex)); if (!context.InputAttributes.Has <DerivedVariable>(newvd)) { context.InputAttributes.Set(newvd, new DerivedVariable()); } IExpression rhs = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, int[][], PlaceHolder[][]>(Collection.JaggedSubarray), new Type[] { elementType }, arrayExpr, index.Target); context.InputAttributes.CopyObjectAttributesTo <Algorithm>(newvd, context.OutputAttributes, rhs); stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), rhs)); // Reduce memory consumption by declaring the clone outside of unnecessary loops. // This way, the item is cloned outside the loop and then replicated, instead of replicating the entire array and cloning the item. Containers containers = new Containers(context); containers = RemoveReferencesTo(containers, innerIndex); containers = Containers.RemoveUnusedLoops(containers, context, rhs); if (context.InputAttributes.Has <DoNotSendEvidence>(arrayVar)) { containers = Containers.RemoveStochasticConditionals(containers, context); } // To put the declaration in the desired containers, we find an ancestor which includes as many of the containers as possible, // then wrap the declaration with the remaining containers. int ancIndex = containers.GetMatchingAncestorIndex(context); Containers missing = containers.GetContainersNotInContext(context, ancIndex); stmts = Containers.WrapWithContainers(stmts, missing.outputs); context.AddStatementsBeforeAncestorIndex(ancIndex, stmts); context.InputAttributes.Set(newvd, containers); // convert into arrayExpr_indices[i] IExpression newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex); newExpr = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { newExpr.GetExpressionType() }, newExpr); return(newExpr); } } } return(imie); }
/// <summary> /// This method does all the work of converting literal indexing expressions. /// </summary> /// <param name="iaie"></param> /// <returns></returns> protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie) { IndexAnalysisTransform.IndexInfo info; if (!analysis.indexInfoOf.TryGetValue(iaie, out info)) { return(base.ConvertArrayIndexer(iaie)); } // Determine if this is a definition i.e. the variable is on the left hand side of an assignment // This must be done before base.ConvertArrayIndexer changes the expression! bool isDef = Recognizer.IsBeingMutated(context, iaie); if (info.clone != null) { if (isDef) { // check that extra literal indices in the target are zero. // for example, if iae is x[i][0] = (...) then it is safe to add x_uses[i] = Rep(x[i]) // if iae is x[i][1] = (...) then it is safe to add x_uses[i][1] = Rep(x[i][1]) // but not x_uses[i] = Rep(x[i]) since this will be a duplicate. bool extraLiteralsAreZero = true; int parentIndex = context.InputStack.Count - 2; object parent = context.GetAncestor(parentIndex); while (parent is IArrayIndexerExpression) { IArrayIndexerExpression parent_iaie = (IArrayIndexerExpression)parent; foreach (IExpression index in parent_iaie.Indices) { if (index is ILiteralExpression) { int value = (int)((ILiteralExpression)index).Value; if (value != 0) { extraLiteralsAreZero = false; break; } } } parentIndex--; parent = context.GetAncestor(parentIndex); } if (false && extraLiteralsAreZero) { // change: // array[0] = f() // into: // array_item0 = f() // array[0] = Copy(array_item0) IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy <PlaceHolder>), new Type[] { iaie.GetExpressionType() }, info.clone); IStatement copySt = Builder.AssignStmt(iaie, copy); context.AddStatementAfterCurrent(copySt); } } return(info.clone); } if (isDef) { // do not clone the lhs of an array create assignment. IAssignExpression assignExpr = context.FindAncestor <IAssignExpression>(); if (assignExpr.Expression is IArrayCreateExpression) { return(iaie); } } IVariableDeclaration originalBaseVar = Recognizer.GetVariableDeclaration(iaie); // If the variable is not stochastic, return if (!CodeRecognizer.IsStochastic(context, originalBaseVar)) { return(iaie); } IExpression newExpr = null; IVariableDeclaration baseVar = originalBaseVar; IVariableDeclaration newvd = null; IExpression rhsExpr = null; Containers containers = info.containers; Type tp = iaie.GetExpressionType(); if (tp == null) { Error("Could not determine type of expression: " + iaie); return(iaie); } var stmts = Builder.StmtCollection(); var stmtsAfter = Builder.StmtCollection(); // does the expression have the form array[indices[k]][indices2[k]][indices3[k]]? if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression && iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression) { IArrayIndexerExpression index3 = (IArrayIndexerExpression)iaie.Indices[0]; IArrayIndexerExpression iaie2 = (IArrayIndexerExpression)iaie.Target; if (index3.Indices.Count == 1 && index3.Indices[0] is IVariableReferenceExpression && iaie2.Target is IArrayIndexerExpression && iaie2.Indices.Count == 1 && iaie2.Indices[0] is IArrayIndexerExpression) { IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie2.Indices[0]; IArrayIndexerExpression iaie3 = (IArrayIndexerExpression)iaie2.Target; if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression && iaie3.Indices.Count == 1 && iaie3.Indices[0] is IArrayIndexerExpression) { IArrayIndexerExpression index = (IArrayIndexerExpression)iaie3.Indices[0]; IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0]; IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex); if (index.Indices.Count == 1 && index2.Indices[0].Equals(innerIndex) && index3.Indices[0].Equals(innerIndex) && innerLoop != null && AreLoopsDisjoint(innerLoop, iaie3.Target, index.Target)) { // expression has the form array[indices[k]][indices2[k]][indices3[k]] if (isDef) { Error("fancy indexing not allowed on left hand side"); return(iaie); } WarnIfLocal(index.Target, iaie3.Target, iaie); WarnIfLocal(index2.Target, iaie3.Target, iaie); WarnIfLocal(index3.Target, iaie3.Target, iaie); containers = RemoveReferencesTo(containers, innerIndex); IExpression loopSize = Recognizer.LoopSizeExpression(innerLoop); var indices = Recognizer.GetIndices(iaie); // Build name of replacement variable from index values StringBuilder sb = new StringBuilder("_item"); AppendIndexString(sb, iaie3); AppendIndexString(sb, iaie2); AppendIndexString(sb, iaie); string name = ToString(iaie3.Target) + sb.ToString(); VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar); newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSize, Recognizer.GetVariableDeclaration(innerIndex), indices); if (!context.InputAttributes.Has <DerivedVariable>(newvd)) { context.InputAttributes.Set(newvd, new DerivedVariable()); } IExpression getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <IReadOnlyList <PlaceHolder> > >, IReadOnlyList <int>, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromDeepJagged), new Type[] { tp }, iaie3.Target, index.Target, index2.Target, index3.Target); context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems); stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems)); newExpr = Builder.ArrayIndex(Builder.VarRefExpr(newvd), innerIndex); rhsExpr = getItems; } } } } // does the expression have the form array[indices[k]][indices2[k]]? if (newvd == null && UseGetItems && iaie.Target is IArrayIndexerExpression && iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression) { IArrayIndexerExpression index2 = (IArrayIndexerExpression)iaie.Indices[0]; IArrayIndexerExpression target = (IArrayIndexerExpression)iaie.Target; if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression && target.Indices.Count == 1 && target.Indices[0] is IArrayIndexerExpression) { IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index2.Indices[0]; IArrayIndexerExpression index = (IArrayIndexerExpression)target.Indices[0]; IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex); if (index.Indices.Count == 1 && index.Indices[0].Equals(innerIndex) && innerLoop != null && AreLoopsDisjoint(innerLoop, target.Target, index.Target)) { // expression has the form array[indices[k]][indices2[k]] if (isDef) { Error("fancy indexing not allowed on left hand side"); return(iaie); } var innerLoops = new List <IForStatement>(); innerLoops.Add(innerLoop); var indexTarget = index.Target; var index2Target = index2.Target; // check if the index array is jagged, i.e. array[indices[k][j]] while (indexTarget is IArrayIndexerExpression && index2Target is IArrayIndexerExpression) { IArrayIndexerExpression indexTargetExpr = (IArrayIndexerExpression)indexTarget; IArrayIndexerExpression index2TargetExpr = (IArrayIndexerExpression)index2Target; if (indexTargetExpr.Indices.Count == 1 && indexTargetExpr.Indices[0] is IVariableReferenceExpression && index2TargetExpr.Indices.Count == 1 && index2TargetExpr.Indices[0] is IVariableReferenceExpression) { IVariableReferenceExpression innerIndexTarget = (IVariableReferenceExpression)indexTargetExpr.Indices[0]; IVariableReferenceExpression innerIndex2Target = (IVariableReferenceExpression)index2TargetExpr.Indices[0]; IForStatement indexTargetLoop = Recognizer.GetLoopForVariable(context, innerIndexTarget); if (indexTargetLoop != null && AreLoopsDisjoint(indexTargetLoop, target.Target, indexTargetExpr.Target) && innerIndexTarget.Equals(innerIndex2Target)) { innerLoops.Add(indexTargetLoop); indexTarget = indexTargetExpr.Target; index2Target = index2TargetExpr.Target; } else { break; } } else { break; } } WarnIfLocal(indexTarget, target.Target, iaie); WarnIfLocal(index2Target, target.Target, iaie); innerLoops.Reverse(); var loopSizes = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) }); var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) }); // Build name of replacement variable from index values StringBuilder sb = new StringBuilder("_item"); AppendIndexString(sb, target); AppendIndexString(sb, iaie); string name = ToString(target.Target) + sb.ToString(); VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar); var indices = Recognizer.GetIndices(iaie); newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices); if (!context.InputAttributes.Has <DerivedVariable>(newvd)) { context.InputAttributes.Set(newvd, new DerivedVariable()); } IExpression getItems; if (innerLoops.Count == 1) { getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <int>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItemsFromJagged), new Type[] { tp }, target.Target, indexTarget, index2Target); } else if (innerLoops.Count == 2) { getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <IReadOnlyList <PlaceHolder> >, IReadOnlyList <IReadOnlyList <int> >, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItemsFromJagged), new Type[] { tp }, target.Target, indexTarget, index2Target); } else { throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}"); } context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems); stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems)); var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i]))); newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices); rhsExpr = getItems; } else if (HasAnyCommonLoops(index, index2)) { Warning($"This model will consume excess memory due to the indexing expression {iaie} since {index} and {index2} have larger depth than the compiler can handle."); } } } if (newvd == null) { IArrayIndexerExpression originalExpr = iaie; if (UseGetItems) { iaie = (IArrayIndexerExpression)base.ConvertArrayIndexer(iaie); } if (!object.ReferenceEquals(iaie.Target, originalExpr.Target) && false) { // TODO: determine if this warning is useful or not string warningText = "This model may consume excess memory due to the jagged indexing expression {0}"; Warning(string.Format(warningText, originalExpr)); } // get the baseVar of the new expression. baseVar = Recognizer.GetVariableDeclaration(iaie); VariableInformation varInfo = VariableInformation.GetVariableInformation(context, baseVar); var indices = Recognizer.GetIndices(iaie); // Build name of replacement variable from index values StringBuilder sb = new StringBuilder("_item"); AppendIndexString(sb, iaie); string name = ToString(iaie.Target) + sb.ToString(); // does the expression have the form array[indices[k]]? if (UseGetItems && iaie.Indices.Count == 1 && iaie.Indices[0] is IArrayIndexerExpression) { IArrayIndexerExpression index = (IArrayIndexerExpression)iaie.Indices[0]; if (index.Indices.Count == 1 && index.Indices[0] is IVariableReferenceExpression) { // expression has the form array[indices[k]] IVariableReferenceExpression innerIndex = (IVariableReferenceExpression)index.Indices[0]; IForStatement innerLoop = Recognizer.GetLoopForVariable(context, innerIndex); if (innerLoop != null && AreLoopsDisjoint(innerLoop, iaie.Target, index.Target)) { if (isDef) { Error("fancy indexing not allowed on left hand side"); return(iaie); } var innerLoops = new List <IForStatement>(); innerLoops.Add(innerLoop); var indexTarget = index.Target; // check if the index array is jagged, i.e. array[indices[k][j]] while (indexTarget is IArrayIndexerExpression) { IArrayIndexerExpression index2 = (IArrayIndexerExpression)indexTarget; if (index2.Indices.Count == 1 && index2.Indices[0] is IVariableReferenceExpression) { IVariableReferenceExpression innerIndex2 = (IVariableReferenceExpression)index2.Indices[0]; IForStatement innerLoop2 = Recognizer.GetLoopForVariable(context, innerIndex2); if (innerLoop2 != null && AreLoopsDisjoint(innerLoop2, iaie.Target, index2.Target)) { innerLoops.Add(innerLoop2); indexTarget = index2.Target; // This limit must match the number of handled cases below. if (innerLoops.Count == 3) { break; } } else { break; } } else { break; } } WarnIfLocal(indexTarget, iaie.Target, originalExpr); innerLoops.Reverse(); var loopSizes = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopSizeExpression(ifs) }); var newIndexVars = innerLoops.ListSelect(ifs => new[] { Recognizer.LoopVariable(ifs) }); newvd = varInfo.DeriveArrayVariable(stmts, context, name, loopSizes, newIndexVars, indices); if (!context.InputAttributes.Has <DerivedVariable>(newvd)) { context.InputAttributes.Set(newvd, new DerivedVariable()); } IExpression getItems; if (innerLoops.Count == 1) { getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <int>, PlaceHolder[]>(Collection.GetItems), new Type[] { tp }, iaie.Target, indexTarget); } else if (innerLoops.Count == 2) { getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <int> >, PlaceHolder[][]>(Collection.GetJaggedItems), new Type[] { tp }, iaie.Target, indexTarget); } else if (innerLoops.Count == 3) { getItems = Builder.StaticGenericMethod(new Func <IReadOnlyList <PlaceHolder>, IReadOnlyList <IReadOnlyList <IReadOnlyList <int> > >, PlaceHolder[][][]>(Collection.GetDeepJaggedItems), new Type[] { tp }, iaie.Target, indexTarget); } else { throw new NotImplementedException($"innerLoops.Count = {innerLoops.Count}"); } context.InputAttributes.CopyObjectAttributesTo <Algorithm>(baseVar, context.OutputAttributes, getItems); stmts.Add(Builder.AssignStmt(Builder.VarRefExpr(newvd), getItems)); var newIndices = newIndexVars.ListSelect(ivds => Util.ArrayInit(ivds.Length, i => Builder.VarRefExpr(ivds[i]))); newExpr = Builder.JaggedArrayIndex(Builder.VarRefExpr(newvd), newIndices); rhsExpr = getItems; } } } if (newvd == null) { if (UseGetItems && info.count < 2) { return(iaie); } try { newvd = varInfo.DeriveIndexedVariable(stmts, context, name, indices, copyInitializer: isDef); } catch (Exception ex) { Error(ex.Message, ex); return(iaie); } context.OutputAttributes.Remove <DerivedVariable>(newvd); newExpr = Builder.VarRefExpr(newvd); rhsExpr = iaie; if (isDef) { // change: // array[0] = f() // into: // array_item0 = f() // array[0] = Copy(array_item0) IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, newExpr); IStatement copySt = Builder.AssignStmt(iaie, copy); stmtsAfter.Add(copySt); if (!context.InputAttributes.Has <DerivedVariable>(baseVar)) { context.InputAttributes.Set(baseVar, new DerivedVariable()); } } else if (!info.IsAssignedTo) { // change: // x = f(array[0]) // into: // array_item0 = Copy(array[0]) // x = f(array_item0) IExpression copy = Builder.StaticGenericMethod(new Func <PlaceHolder, PlaceHolder>(Clone.Copy), new Type[] { tp }, iaie); IStatement copySt = Builder.AssignStmt(Builder.VarRefExpr(newvd), copy); //if (attr != null) context.OutputAttributes.Set(copySt, attr); stmts.Add(copySt); context.InputAttributes.Set(newvd, new DerivedVariable()); } } } // Reduce memory consumption by declaring the clone outside of unnecessary loops. // This way, the item is cloned outside the loop and then replicated, instead of replicating the entire array and cloning the item. containers = Containers.RemoveUnusedLoops(containers, context, rhsExpr); if (context.InputAttributes.Has <DoNotSendEvidence>(originalBaseVar)) { containers = Containers.RemoveStochasticConditionals(containers, context); } if (true) { IStatement st = GetBindingSetContainer(FilterBindingSet(info.bindings, binding => Containers.ContainsExpression(containers.inputs, context, binding.GetExpression()))); if (st != null) { containers.Add(st); } } // To put the declaration in the desired containers, we find an ancestor which includes as many of the containers as possible, // then wrap the declaration with the remaining containers. int ancIndex = containers.GetMatchingAncestorIndex(context); Containers missing = containers.GetContainersNotInContext(context, ancIndex); stmts = Containers.WrapWithContainers(stmts, missing.outputs); context.AddStatementsBeforeAncestorIndex(ancIndex, stmts); stmtsAfter = Containers.WrapWithContainers(stmtsAfter, missing.outputs); context.AddStatementsAfterAncestorIndex(ancIndex, stmtsAfter); context.InputAttributes.Set(newvd, containers); info.clone = newExpr; return(newExpr); }
protected override IExpression ConvertVariableRefExpr(IVariableReferenceExpression ivre) { ProcessExpression(ivre); return(ivre); }
public virtual void VisitVariableReferenceExpression(IVariableReferenceExpression e) { }
private static void WriteAssign(LanguageWriter w, IAssignExpression exp) { #if EXTRA_TEMP // 無駄な変数の除去 // 之はその内に StatementAnalyze に引っ越した方が分かりやすいかも知れない // 但し、その場合には式内で代入を行う場合には対応出来ない (例: (i=j)==0 等) IVariableDeclarationExpression target = exp.Target as IVariableDeclarationExpression; IVariableReferenceExpression target2 = exp.Target as IVariableReferenceExpression; IVariableReferenceExpression right = exp.Expression as IVariableReferenceExpression; if (w.ExtraTemporaries != null) { // 無駄変数の宣言 if (target != null) { for (int i = 0; i < w.ExtraTemporaries.Length; i++) { if (!w.EssentialTemporaries[i] && target.Variable.Name == w.ExtraTemporaries[i]) { return; } } } // 無駄変数から無駄変数への受け渡し if (target2 != null && right != null) { int iTarget = -1; int iRight = -1; for (int j = 0; j < w.ExtraTemporaries.Length; j++) { if (target2.Variable.ToString() == w.ExtraTemporaries[j]) { iTarget = j; w.VerifyCorrectBlock(j); } if (right.Variable.ToString() == w.ExtraTemporaries[j]) { iRight = j; w.VerifyCorrectBlock(j); } } if (iTarget >= 0 && !w.EssentialTemporaries[iTarget]) { string str; if (iRight >= 0 && !w.EssentialTemporaries[iRight]) { if (w.ExtraMappings[iRight] == null) { w.EssentialTemporaries[iRight] = true; str = null; } else { str = w.ExtraMappings[iRight]; } } else { str = right.Variable.ToString(); } if (str != null && target2.Variable.ToString()[0] == str[0]) { w.ExtraMappings[iTarget] = str; return; } } } } #endif WriteExpression(w, exp.Target, false); w.Write(" = "); WriteExpression(w, exp.Expression, false); }
//=========================================================== // using の変換 //=========================================================== /// <summary> /// Using 文を他の構文に変換して、yields に変換後の Statement を書き込みます。 /// </summary> /// <param name="yields">変換後の Statement の書き込み先を指定します。</param> /// <param name="state">using 構文を表現する Statement を指定します。</param> /// <param name="last">state が Statements の中で最後の Statement か否かを指定します。</param> public static void TransformUsingStatement(Gen::List <IStatement> yields, IUsingStatement state, bool last) { // 変数の宣言の場合 IAssignExpression assig = state.Expression as IAssignExpression; if (assig != null) { do { IVariableDeclarationExpression var_decl_x = assig.Target as IVariableDeclarationExpression; if (var_decl_x == null) { continue; } IVariableDeclaration var_decl = var_decl_x.Variable as IVariableDeclaration; if (var_decl == null) { continue; } IObjectCreateExpression exp_create = assig.Expression as IObjectCreateExpression; if (exp_create != null) { LocalRefVariableStatement s_lr = new LocalRefVariableStatement(var_decl, assig.Expression, state.Body); s_lr.noblock = last; yields.Add(s_lr); } else { //yields.Add(new ExpressionStatement(assig)); //yields.Add(state.Body); //yields.Add(new DeleteStatement(new VariableReferenceExpression(var_decl))); //↑ 中で例外が起こったときのことを考えていない。 // 宣言部分と代入部分を分離 IStatement s_decl = new ExpressionStatement(var_decl_x); IStatement s_asgn = new ExpressionStatement( new AssignExpression( new VariableReferenceExpression(var_decl), assig.Expression ) ); IStatement s_delete = new DeleteStatement(new VariableReferenceExpression(var_decl)); // 宣言 yields.Add(s_decl); // try-finally BlockStatement try_block = new BlockStatement(); try_block.Statements.Add(s_asgn); try_block.Statements.AddRange(state.Body.Statements); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(try_block); s_tcf.Finally = finally_block; yields.Add(s_tcf); } return; }while(false); throw new InterfaceNotImplementedException("×実装中×", typeof(IVariableDeclarationExpression), assig.Target); } // 変数の参照の場合 IVariableReferenceExpression varref = state.Expression as IVariableReferenceExpression; if (varref != null) { IStatement s_delete = new DeleteStatement(varref); // try-finally TryCatchFinallyStatement s_tcf = new TryCatchFinallyStatement(state.Body); BlockStatement finally_block = new BlockStatement(); finally_block.Statements.Add(s_delete); s_tcf.Finally = finally_block; yields.Add(s_tcf); return; } throw new InterfaceNotImplementedException( "Unexpected using-statement expression interface (expects IAssignExpression or IVariableReferenceExpression)", typeof(IAssignExpression), state.Expression); }
protected override IExpression ConvertMethodInvoke(IMethodInvokeExpression imie) { if (Recognizer.IsStaticGenericMethod(imie, new Func <PlaceHolder, ICompilerAttribute, PlaceHolder>(Attrib.Var))) { IVariableReferenceExpression ivre = imie.Arguments[0] as IVariableReferenceExpression; IVariableDeclaration target = ivre.Variable.Resolve(); IExpression expr = CodeRecognizer.RemoveCast(imie.Arguments[1]); AddAttribute(target, expr); return(null); } else if (Recognizer.IsStaticMethod(imie, new Action <object, object>(Attrib.InitialiseTo))) { IVariableReferenceExpression ivre = CodeRecognizer.RemoveCast(imie.Arguments[0]) as IVariableReferenceExpression; IVariableDeclaration target = ivre.Variable.Resolve(); context.OutputAttributes.Set(target, new InitialiseTo(imie.Arguments[1])); return(null); } else if (CodeRecognizer.IsInfer(imie)) { inferCount++; object decl = Recognizer.GetDeclaration(imie.Arguments[0]); if (decl != null && !context.InputAttributes.Has <IsInferred>(decl)) { context.InputAttributes.Set(decl, new IsInferred()); } // the arguments must not be substituted for their values, so we don't call ConvertExpression List <IExpression> newArgs = new List <IExpression>(); foreach (var arg in imie.Arguments) { newArgs.Add(CodeRecognizer.RemoveCast(arg)); } IMethodInvokeExpression mie = Builder.MethodInvkExpr(); mie.Method = imie.Method; mie.Arguments.AddRange(newArgs); context.InputAttributes.CopyObjectAttributesTo(imie, context.OutputAttributes, mie); return(mie); } IExpression converted = base.ConvertMethodInvoke(imie); if (converted is IMethodInvokeExpression) { var mie = (IMethodInvokeExpression)converted; bool isAnd = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.And)); bool isOr = Recognizer.IsStaticMethod(converted, new Func <bool, bool, bool>(Factors.Factor.Or)); bool anyArgumentIsLiteral = mie.Arguments.Any(arg => arg is ILiteralExpression); if (anyArgumentIsLiteral) { if (isAnd) { if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(false))) { return(Builder.LiteralExpr(false)); } // any remaining literals must be true, and therefore can be ignored. var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression)); if (reducedArguments.Count() == 1) { return(reducedArguments.First()); } else { return(Builder.LiteralExpr(true)); } } else if (isOr) { if (mie.Arguments.Any(arg => arg is ILiteralExpression && ((ILiteralExpression)arg).Value.Equals(true))) { return(Builder.LiteralExpr(true)); } // any remaining literals must be false, and therefore can be ignored. var reducedArguments = mie.Arguments.Where(arg => !(arg is ILiteralExpression)); if (reducedArguments.Count() == 1) { return(reducedArguments.First()); } else { return(Builder.LiteralExpr(false)); } } else if (Recognizer.IsStaticMethod(converted, new Func <bool, bool>(Factors.Factor.Not))) { bool allArgumentsAreLiteral = mie.Arguments.All(arg => arg is ILiteralExpression); if (allArgumentsAreLiteral) { return(Builder.LiteralExpr(evaluator.Evaluate(mie))); } } } foreach (IExpression arg in mie.Arguments) { if (arg is IAddressOutExpression) { IAddressOutExpression iaoe = (IAddressOutExpression)arg; IVariableDeclaration ivd = Recognizer.GetVariableDeclaration(iaoe.Expression); if (ivd != null) { FactorManager.FactorInfo info = CodeRecognizer.GetFactorInfo(context, mie); if (info != null && info.IsDeterministicFactor && !context.InputAttributes.Has <DerivedVariable>(ivd)) { context.InputAttributes.Set(ivd, new DerivedVariable()); } } } } } return(converted); }
protected override IExpression ConvertArrayIndexer(IArrayIndexerExpression iaie) { bool isDef = Recognizer.IsBeingMutated(context, iaie); if (isDef) { // do not clone the lhs of an array create assignment. IAssignExpression assignExpr = context.FindAncestor <IAssignExpression>(); if (assignExpr.Expression is IArrayCreateExpression) { return(iaie); } } base.ConvertArrayIndexer(iaie); IndexInfo info; // TODO: Instead of storing an IndexInfo for each distinct expression, we should try to unify expressions, as in GateAnalysisTransform. // For example, we could unify a[0,i] and a[0,0] and use the same clone array for both. if (indexInfoOf.TryGetValue(iaie, out info)) { Containers containers = new Containers(context); if (info.bindings.Count > 0) { List <ConditionBinding> bindings = GetBindings(context, containers.inputs); if (bindings.Count == 0) { info.bindings.Clear(); } else { info.bindings.Add(bindings); } } info.containers = Containers.Intersect(info.containers, containers); info.count++; if (isDef) { info.IsAssignedTo = true; } return(iaie); } CheckIndicesAreNotStochastic(iaie.Indices); IVariableDeclaration baseVar = Recognizer.GetVariableDeclaration(iaie); // If not an indexed variable reference, skip it (e.g. an indexed argument reference) if (baseVar == null) { return(iaie); } // If the variable is not stochastic, skip it if (!CodeRecognizer.IsStochastic(context, baseVar)) { return(iaie); } // If the indices are all loop variables, skip it var indices = Recognizer.GetIndices(iaie); bool allLoopIndices = indices.All(bracket => bracket.All(indexExpr => { if (indexExpr is IVariableReferenceExpression) { IVariableReferenceExpression ivre = (IVariableReferenceExpression)indexExpr; return(Recognizer.GetLoopForVariable(context, ivre) != null); } else { return(false); } })); if (allLoopIndices) { return(iaie); } info = new IndexInfo(); info.containers = new Containers(context); List <ConditionBinding> bindings2 = GetBindings(context, info.containers.inputs); if (bindings2.Count > 0) { info.bindings.Add(bindings2); } info.count = 1; info.IsAssignedTo = isDef; indexInfoOf[iaie] = info; return(iaie); }
public virtual IExpression TransformVariableReferenceExpression(IVariableReferenceExpression value) { value.Variable = this.TransformVariableReference(value.Variable); return value; }