protected override IEnumerable <BaseStatement> Visit(CompoundAssignment compAss) { var tmp = new VariableName(_names.Name()); var a = new ExpressionDecomposition(_names).Visit(compAss.Expression).ToArray(); var b = new Assignment(tmp, BaseBinaryExpression.Create(compAss.Op, new Variable(new VariableName(compAss.Left.Name)), new Variable(((Assignment)a.Last()).Left))); var c = new Assignment(new VariableName(compAss.Left.Name), new Variable(tmp)); return(a.Append(b).Append(c)); }
public string Name() { while (true) { var n = _inner.Name(); if (!_taken.Contains(n)) { return(n); } } }
protected override BaseStatement Visit(If @if) { // Check that each branch contains just one statement... if (@if.FalseBranch.Statements.Count != 1) { return(@if); } if (@if.TrueBranch.Statements.Count != 1) { return(@if); } // ...and that those statements are goto statements if (!(@if.TrueBranch.Statements.Single() is Goto gotoTrue)) { return(@if); } if (!(@if.FalseBranch.Statements.Single() is Goto gotoFalse)) { return(@if); } // if A then goto B else goto C end var a = new Bracketed(new Or(@if.Condition, new ConstantNumber(0))); var b = new Bracketed(gotoTrue.Destination); var c = new Bracketed(gotoFalse.Destination); // goto A*(B-C)+C var g1 = new Goto(new Add(c, new Multiply(a, new Bracketed(new Subtract(b, c))))); // x=C goto A*(B-x)+x var x = new VariableName(_names.Name()); var g2 = new StatementList( new Assignment(x, c), new Goto(new Add(new Multiply(a, new Bracketed(new Subtract(b, new Variable(x)))), new Variable(x))) ); // Return the shortest one (ignoring the length of the temporary variable name, assume that's optimised to 1 char) var xl = x.Name.Length * 2; if (g1.ToString().Length <= g2.ToString().Length - xl + 2) { return(g1); } else { return(g2); } }
private VariableName MkTmp() => new VariableName(_names.Name());