protected override IStatement ConvertCondition(IConditionStatement ics) { IConditionStatement cs = Builder.CondStmt(); cs.Condition = ConvertExpression(ics.Condition); if (cs.Condition is ILiteralExpression) { bool value = (bool)((ILiteralExpression)cs.Condition).Value; if (value) { if (ics.Then != null) { foreach (IStatement st in ics.Then.Statements) { IStatement ist = ConvertStatement(st); if (ist != null) { context.AddStatementBeforeCurrent(ist); } } } } else { if (ics.Else != null) { foreach (IStatement st in ics.Else.Statements) { IStatement ist = ConvertStatement(st); if (ist != null) { context.AddStatementBeforeCurrent(ist); } } } } return(null); } context.SetPrimaryOutput(cs); IForStatement loop; ConditionBinding binding = GateTransform.GetConditionBinding(cs.Condition, context, out loop); int startIndex = conditionContext.Count; conditionContext.Add(binding); cs.Then = ConvertBlock(ics.Then); if (ics.Else != null) { conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex); binding = binding.FlipCondition(); conditionContext.Add(binding); cs.Else = ConvertBlock(ics.Else); } conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex); if (cs.Then.Statements.Count == 0 && (cs.Else == null || cs.Else.Statements.Count == 0)) { return(null); } return(cs); }
protected override IStatement ConvertCondition(IConditionStatement ics) { context.SetPrimaryOutput(ics); ConvertExpression(ics.Condition); ConditionBinding binding = GateTransform.GetConditionBinding(ics.Condition, context, out IForStatement loop); IExpression caseValue = binding.rhs; if (!GateTransform.IsLiteralOrLoopVar(context, caseValue, out loop)) { Error("If statement condition must compare to a literal or loop counter, was: " + ics.Condition); return(ics); } bool isStochastic = CodeRecognizer.IsStochastic(context, binding.lhs); IExpression gateBlockKey; if (isStochastic) { gateBlockKey = binding.lhs; } else { // definitions must not be unified across deterministic gate conditions gateBlockKey = binding.GetExpression(); } GateBlock gateBlock = null; Set <ConditionBinding> bindings = ConditionBinding.Copy(conditionContext); Dictionary <IExpression, GateBlock> blockMap; if (!gateBlocks.TryGetValue(bindings, out blockMap)) { // first time seeing these bindings blockMap = new Dictionary <IExpression, GateBlock>(); gateBlocks[bindings] = blockMap; } if (!blockMap.TryGetValue(gateBlockKey, out gateBlock)) { // first time seeing this lhs gateBlock = new GateBlock(); blockMap[gateBlockKey] = gateBlock; } if (gateBlock.hasLoopCaseValue && loop == null) { Error("Cannot compare " + binding.lhs + " to a literal, since it was previously compared to a loop counter. Put this test inside the loop."); } if (!gateBlock.hasLoopCaseValue && gateBlock.caseValues.Count > 0 && loop != null) { Error("Cannot compare " + binding.lhs + " to a loop counter, since it was previously compared to a literal. Put the literal case inside the loop."); } gateBlock.caseValues.Add(caseValue); if (loop != null) { gateBlock.hasLoopCaseValue = true; } gateBlockContext.Add(gateBlock); context.OutputAttributes.Set(ics, gateBlock); int startIndex = conditionContext.Count; conditionContext.Add(binding); ConvertBlock(ics.Then); if (ics.Else != null) { conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex); binding = binding.FlipCondition(); conditionContext.Add(binding); ConvertBlock(ics.Else); } conditionContext.RemoveRange(startIndex, conditionContext.Count - startIndex); gateBlockContext.RemoveAt(gateBlockContext.Count - 1); // remove any uses that match a def //RemoveUsesOfDefs(gateBlock); if (gateBlockContext.Count > 0) { GateBlock currentBlock = gateBlockContext[gateBlockContext.Count - 1]; // all variables defined/used in the inner block must be processed by the outer block foreach (ExpressionWithBindings eb in gateBlock.variablesDefined.Values) { if (eb.Bindings.Count > 0) { foreach (List <ConditionBinding> binding2 in eb.Bindings) { ProcessUse(eb.Expression, true, Union(conditionContext, binding2)); } } else { ProcessUse(eb.Expression, true, conditionContext); } } foreach (List <ExpressionWithBindings> ebs in gateBlock.variablesUsed.Values) { foreach (ExpressionWithBindings eb in ebs) { if (eb.Bindings.Count > 0) { foreach (ICollection <ConditionBinding> binding2 in eb.Bindings) { ProcessUse(eb.Expression, false, Union(conditionContext, binding2)); } } else { ProcessUse(eb.Expression, false, conditionContext); } } } } return(ics); }