public override void CaseAStringConstExp(AStringConstExp node) { List <string> strings = new List <string>(); StringBuilder name = new StringBuilder(""); bool previousWasUnicode = false; foreach (char c in node.GetStringLiteral().Text) { if (c > 0xFF) { byte[] utf8Bytes = Encoding.UTF8.GetBytes(c.ToString()); foreach (byte b in utf8Bytes) { name.Append("\\x"); name.AppendFormat("{0:x2}", b); } previousWasUnicode = true; } else { if (previousWasUnicode && ((c >= '0' && c <= '9') || (char.ToLower(c) >= 'a' && char.ToLower(c) <= 'f'))) { strings.Add(name.ToString()); name.Clear(); } name.Append(c); previousWasUnicode = false; } } strings.Add(name.ToString()); if (strings.Count == 1) { node.GetStringLiteral().Text = name.ToString(); } else { strings[0] = strings[0].Remove(0, 1); strings[strings.Count - 1] = strings[strings.Count - 1].Substring(0, strings[strings.Count - 1].Length - 1); AStringConstExp left = new AStringConstExp(new TStringLiteral("\"" + strings[0] + "\"")); strings.RemoveAt(0); data.StringsDontJoinRight.Add(left); data.ExpTypes[left] = new ANamedType(new TIdentifier("string"), null); node.ReplaceBy(Combine(left, strings)); } }
//Join string + string to string public override void CaseABinopExp(ABinopExp node) { if (node.GetBinop() is APlusBinop) { PType type = data.ExpTypes[node]; if (type is ANamedType && ((ANamedType)type).IsPrimitive("string")) { PExp other = null; if (node.GetLeft() is ANullExp) { other = node.GetRight(); } if (node.GetRight() is ANullExp) { other = node.GetLeft(); } if (other != null) { node.ReplaceBy(other); other.Apply(this); return; } } //Case (string + string) if (node.GetLeft() is AStringConstExp && node.GetRight() is AStringConstExp) { AStringConstExp left = (AStringConstExp)node.GetLeft(); AStringConstExp right = (AStringConstExp)node.GetRight(); if (!IsJoinAllowed(left.GetStringLiteral().Text, right.GetStringLiteral().Text)) { base.CaseABinopExp(node); return; } left.GetStringLiteral().Text = left.GetStringLiteral().Text.Substring(0, left.GetStringLiteral().Text. Length - 1); left.GetStringLiteral().Text += right.GetStringLiteral().Text.Substring(1); node.ReplaceBy(left); CaseAStringConstExp(left); return; } //Case (<exp> + string) + string if (node.GetLeft() is ABinopExp && node.GetRight() is AStringConstExp) { ABinopExp leftBinop = (ABinopExp)node.GetLeft(); if (leftBinop.GetBinop() is APlusBinop && leftBinop.GetRight() is AStringConstExp) { AStringConstExp left = (AStringConstExp)leftBinop.GetRight(); AStringConstExp right = (AStringConstExp)node.GetRight(); if (!IsJoinAllowed(left.GetStringLiteral().Text, right.GetStringLiteral().Text)) { base.CaseABinopExp(node); return; } left.GetStringLiteral().Text = left.GetStringLiteral().Text.Substring(0, left.GetStringLiteral(). Text. Length - 1); left.GetStringLiteral().Text += right.GetStringLiteral().Text.Substring(1); node.ReplaceBy(leftBinop); CaseABinopExp(leftBinop); return; } } //Case string + (string + <exp>) //Case (<exp> + string) + (string + <exp>) } //Case (int + int) /*if (node.GetLeft() is AIntConstExp && node.GetRight() is AIntConstExp) * { * AIntConstExp left = (AIntConstExp) node.GetLeft(); * AIntConstExp right = (AIntConstExp) node.GetRight(); * * int a = int.Parse(left.GetIntegerLiteral().Text); * int b = int.Parse(right.GetIntegerLiteral().Text); * * if (node.GetBinop() is APlusBinop) * { * a += b; * } * else if (node.GetBinop() is AMinusBinop) * { * a -= b; * } * else if (node.GetBinop() is ATimesBinop) * { * a *= b; * } * else if (node.GetBinop() is ADivideBinop) * { * if (b == 0) * { * base.CaseABinopExp(node); * return; * } * a /= b; * } * else * { * base.CaseABinopExp(node); * return; * } * * left.GetIntegerLiteral().Text = a.ToString(); * node.ReplaceBy(left); * left.Apply(this); * return; * } * //Case (<exp> + int) + int * if (node.GetLeft() is ABinopExp && node.GetRight() is AIntConstExp && (node.GetBinop() is APlusBinop || node.GetBinop() is AMinusBinop)) * { * ABinopExp leftBinop = (ABinopExp) node.GetLeft(); * PType leftType = data.ExpTypes[leftBinop]; * if (leftBinop.GetRight() is AIntConstExp && leftType is ANamedType && ((ANamedType) leftType).GetName().Text == "int" && * (leftBinop.GetBinop() is APlusBinop || leftBinop.GetBinop() is AMinusBinop)) * { * AIntConstExp left = (AIntConstExp)leftBinop.GetRight(); * AIntConstExp right = (AIntConstExp)node.GetRight(); * int a = int.Parse(left.GetIntegerLiteral().Text); * int b = int.Parse(right.GetIntegerLiteral().Text); * * if (node.GetBinop() is APlusBinop) * { * if (leftBinop.GetBinop() is APlusBinop) * { * //(<exp> + int) + int * int c = a + b; * //Test for overflow * if (a > 0 && b > 0 && (c < a || c < b) || * a < 0 && b < 0 && (c > a || c > b)) * { * //Don't add them * base.CaseABinopExp(node); * return; * } * if (c < 0) * { * //Change binop to <exp> - c * if (c != int.MinValue) * { * c = -c; * leftBinop.SetBinop(new AMinusBinop(new TMinus("-"))); * } * } * //Replace node with leftbinop * left.GetIntegerLiteral().Text = c.ToString(); * node.ReplaceBy(leftBinop); * leftBinop.Apply(this); * return; * } * else * { * //(<exp> - int) + int * int c = b - a; * //Test for overflow * if (a < 0 && b > 0 && (c < a || c < b) || * a > 0 && b < 0 && (c > a || c > b)) * { * //Don't add them * base.CaseABinopExp(node); * return; * } * if (c > 0 || c == int.MinValue) * { * //Change binop to <exp> + c * leftBinop.SetBinop(new APlusBinop(new TPlus("+"))); * * } * else * c = -c; * //Replace node with leftbinop * left.GetIntegerLiteral().Text = c.ToString(); * node.ReplaceBy(leftBinop); * leftBinop.Apply(this); * return; * } * } * else * { * if (leftBinop.GetBinop() is APlusBinop) * { * //(<exp> + int) - int * //ALso need to consider <exp> in the other position, and int on the other side of the binop * //Make a more general algorithm * } * else * { * * } * } * } * }*/ base.CaseABinopExp(node); }
public override void CaseAStringConstExp(AStringConstExp node) { Value += node.GetStringLiteral().Text; }
public override void CaseABinopExp(ABinopExp node) { bool pushed = false; if (!(node.Parent() is ABinopExp)) { PushStack(); pushed = true; } try { bool isIntegerType = data.ExpTypes[node] is ANamedType && (((ANamedType)data.ExpTypes[node]).IsPrimitive("int") || ((ANamedType)data.ExpTypes[node]).IsPrimitive("byte")); if (isIntegerType) { if (node.GetBinop() is APlusBinop || node.GetBinop() is AMinusBinop) { node.GetLeft().Apply(this); if (!Util.HasAncestor <AAProgram>(node)) { return; } if (node.GetBinop() is AMinusBinop) { isNegativeRightSide = !isNegativeRightSide; } node.GetRight().Apply(this); if (node.GetBinop() is AMinusBinop) { isNegativeRightSide = !isNegativeRightSide; } if (!Util.HasAncestor <AAProgram>(node)) { return; } for (int i = 0; i < intConsts.Count; i++) { for (int j = i + 1; j < intConsts.Count; j++) { Pair <AIntConstExp, bool> const1 = intConsts[i]; Pair <AIntConstExp, bool> const2 = intConsts[j]; ABinopExp pBinop1 = (ABinopExp)const1.Car.Parent(); ABinopExp pBinop2 = (ABinopExp)const2.Car.Parent(); int a = int.Parse(const1.Car.GetIntegerLiteral().Text); int b = int.Parse(const2.Car.GetIntegerLiteral().Text); int c; if (const1.Cdr != const2.Cdr) { c = a - b; } else { c = a + b; } //Eliminate stuff like <exp> + -1 if (c < 0 && pBinop1.GetRight() == const1.Car) { c = -c; if (pBinop1.GetBinop() is AMinusBinop) { pBinop1.SetBinop(new APlusBinop(new TPlus("+"))); } else { pBinop1.SetBinop(new AMinusBinop(new TMinus("-"))); } const1.Cdr = !const1.Cdr; } const1.Car.GetIntegerLiteral().Text = c.ToString(); //Remove binop2 if (pBinop2.GetLeft() == const2.Car) { if (pBinop2.GetBinop() is AMinusBinop) { if (pBinop2.GetRight() is AIntConstExp) { AIntConstExp const3 = (AIntConstExp)pBinop2.GetRight(); const3.GetIntegerLiteral().Text = (-int.Parse(const3.GetIntegerLiteral().Text)).ToString(); pBinop2.ReplaceBy(const3); intConsts.Add(new Pair <AIntConstExp, bool>(const3, isNegativeRightSide)); } else { AUnopExp unop = new AUnopExp(new ANegateUnop(new TMinus("-")), pBinop2.GetRight()); data.ExpTypes[unop] = new ANamedType(new TIdentifier("int"), null); pBinop2.ReplaceBy(unop); } } else { pBinop2.ReplaceBy(pBinop2.GetRight()); } } else { pBinop2.ReplaceBy(pBinop2.GetLeft()); } intConsts.RemoveAt(j); j--; } } return; } } { PushStack(); node.GetLeft().Apply(this); PopStack(); PushStack(); node.GetRight().Apply(this); PopStack(); } if (isIntegerType && (node.GetBinop() is ATimesBinop || node.GetBinop() is ADivideBinop) && node.GetLeft() is AIntConstExp && node.GetRight() is AIntConstExp) { AIntConstExp const1 = (AIntConstExp)node.GetLeft(); AIntConstExp const2 = (AIntConstExp)node.GetRight(); int a = int.Parse(const1.GetIntegerLiteral().Text); int b = int.Parse(const2.GetIntegerLiteral().Text); int c; if (node.GetBinop() is ATimesBinop || b != 0) { if (node.GetBinop() is ATimesBinop) { c = a * b; } else { c = a / b; } const1.GetIntegerLiteral().Text = c.ToString(); node.ReplaceBy(const1); const1.Apply(this); return; } } if (node.GetBinop() is AEqBinop || node.GetBinop() is ANeBinop) { if (node.GetLeft() is ABooleanConstExp && node.GetRight() is ABooleanConstExp) { bool b1 = ((ABooleanConstExp)node.GetLeft()).GetBool() is ATrueBool; bool b2 = ((ABooleanConstExp)node.GetRight()).GetBool() is ATrueBool; bool b3 = false; if (node.GetBinop() is AEqBinop) { b3 = b1 == b2; } else if (node.GetBinop() is ANeBinop) { b3 = b1 != b2; } ((ABooleanConstExp)node.GetLeft()).SetBool(b3 ? (PBool) new ATrueBool() : new AFalseBool()); node.ReplaceBy(node.GetLeft()); return; } else if (node.GetLeft() is AIntConstExp && node.GetRight() is AIntConstExp) { AIntConstExp const1 = (AIntConstExp)node.GetLeft(); AIntConstExp const2 = (AIntConstExp)node.GetRight(); int a = int.Parse(const1.GetIntegerLiteral().Text); int b = int.Parse(const2.GetIntegerLiteral().Text); bool c = false; if (node.GetBinop() is AEqBinop) { c = a == b; } else if (node.GetBinop() is ANeBinop) { c = a != b; } ABooleanConstExp booleanExp = new ABooleanConstExp(c ? (PBool) new ATrueBool() : new AFalseBool()); data.ExpTypes[booleanExp] = new ANamedType(new TIdentifier("bool"), null); node.ReplaceBy(booleanExp); return; } else if (node.GetLeft() is ANullExp && node.GetRight() is ANullExp) { ABooleanConstExp booleanExp = new ABooleanConstExp(node.GetBinop() is AEqBinop ? (PBool) new ATrueBool() : new AFalseBool()); data.ExpTypes[booleanExp] = new ANamedType(new TIdentifier("bool"), null); node.ReplaceBy(booleanExp); return; } else if (node.GetLeft() is AStringConstExp && node.GetRight() is AStringConstExp) { AStringConstExp const1 = (AStringConstExp)node.GetLeft(); AStringConstExp const2 = (AStringConstExp)node.GetRight(); string a = const1.GetStringLiteral().Text; string b = const2.GetStringLiteral().Text; bool c = false; if (node.GetBinop() is AEqBinop) { c = a == b; } else if (node.GetBinop() is ANeBinop) { c = a != b; } ABooleanConstExp booleanExp = new ABooleanConstExp(c ? (PBool) new ATrueBool() : new AFalseBool()); data.ExpTypes[booleanExp] = new ANamedType(new TIdentifier("bool"), null); node.ReplaceBy(booleanExp); return; } } if ((node.GetLeft() is ABooleanConstExp || node.GetRight() is ABooleanConstExp) && (node.GetBinop() is ALazyAndBinop || node.GetBinop() is ALazyOrBinop)) { ABooleanConstExp boolExp; PExp other; if (node.GetLeft() is ABooleanConstExp) { boolExp = (ABooleanConstExp)node.GetLeft(); other = node.GetRight(); } else { boolExp = (ABooleanConstExp)node.GetRight(); other = node.GetLeft(); } if (node.GetBinop() is ALazyAndBinop) { if (boolExp.GetBool() is ATrueBool) { //true && <exp> node.ReplaceBy(other); } else { //false && <exp> node.ReplaceBy(boolExp); } } else { if (boolExp.GetBool() is ATrueBool) { //true || <exp> node.ReplaceBy(boolExp); } else { //false || <exp> node.ReplaceBy(other); } } return; } } finally { if (pushed) { PopStack(); } } }
public override void DefaultIn(Node node) { if (!canMerge) { return; } if (node is AMethodDecl) { //First node - no need to fetch if (((AMethodDecl)node).GetFormals().Count != ((AMethodDecl)otherNode).GetFormals().Count) { canMerge = false; } return; } //Fetch corrosponding other node int index = 0; GetChildTypeIndex getChildTypeIndex = new GetChildTypeIndex() { Parent = node.Parent(), Child = node }; node.Parent().Apply(getChildTypeIndex); index = getChildTypeIndex.Index; GetChildTypeByIndex getChildTypeByIndex = new GetChildTypeByIndex() { Child = node, Index = index, Parent = otherNode }; otherNode.Apply(getChildTypeByIndex); otherNode = getChildTypeByIndex.Child; if (otherNode.GetType() != node.GetType()) { canMerge = false; return; } if (node is AALocalDecl) { locals.Add((AALocalDecl)node); otherLocals.Add((AALocalDecl)otherNode); return; } if (node is ANamedType) { ANamedType aNode = (ANamedType)node; ANamedType aOther = (ANamedType)otherNode; if (data.StructTypeLinks.ContainsKey(aNode) != data.StructTypeLinks.ContainsKey(aOther)) { canMerge = false; return; } if (data.StructTypeLinks.ContainsKey(aNode) && data.StructTypeLinks[aNode] != data.StructTypeLinks[aOther]) { canMerge = false; } if (!data.StructTypeLinks.ContainsKey(aNode) && aNode.IsSame(aOther, true))//aNode.GetName().Text != aOther.GetName().Text) { canMerge = false; } if (aNode.IsPrimitive() && !aOther.IsPrimitive(aNode.AsIdentifierString())) { canMerge = false; } return; } if (node is AABlock) { AABlock aNode = (AABlock)node; AABlock aOther = (AABlock)otherNode; if (aNode.GetStatements().Count != aOther.GetStatements().Count) { canMerge = false; } return; } if (node is AIntConstExp) { AIntConstExp aNode = (AIntConstExp)node; AIntConstExp aOther = (AIntConstExp)otherNode; if (aNode.GetIntegerLiteral().Text != aOther.GetIntegerLiteral().Text) { canMerge = false; } return; } if (node is AFixedConstExp) { AFixedConstExp aNode = (AFixedConstExp)node; AFixedConstExp aOther = (AFixedConstExp)otherNode; if (aNode.GetFixedLiteral().Text != aOther.GetFixedLiteral().Text) { canMerge = false; } return; } if (node is AStringConstExp) { AStringConstExp aNode = (AStringConstExp)node; AStringConstExp aOther = (AStringConstExp)otherNode; if (aNode.GetStringLiteral().Text != aOther.GetStringLiteral().Text) { canMerge = false; } return; } if (node is ACharConstExp) { ACharConstExp aNode = (ACharConstExp)node; ACharConstExp aOther = (ACharConstExp)otherNode; if (aNode.GetCharLiteral().Text != aOther.GetCharLiteral().Text) { canMerge = false; } return; } if (node is ASimpleInvokeExp) { ASimpleInvokeExp aNode = (ASimpleInvokeExp)node; ASimpleInvokeExp aOther = (ASimpleInvokeExp)otherNode; if (data.SimpleMethodLinks[aNode] != data.SimpleMethodLinks[aOther] && !(data.SimpleMethodLinks[aNode] == Util.GetAncestor <AMethodDecl>(aNode) && data.SimpleMethodLinks[aOther] == Util.GetAncestor <AMethodDecl>(aOther))) { canMerge = false; } return; } if (node is ALocalLvalue) { ALocalLvalue aNode = (ALocalLvalue)node; ALocalLvalue aOther = (ALocalLvalue)otherNode; if (locals.IndexOf(data.LocalLinks[aNode]) != otherLocals.IndexOf(data.LocalLinks[aOther])) { canMerge = false; } return; } if (node is AFieldLvalue) { AFieldLvalue aNode = (AFieldLvalue)node; AFieldLvalue aOther = (AFieldLvalue)otherNode; if (data.FieldLinks[aNode] != data.FieldLinks[aOther]) { canMerge = false; } return; } if (node is AStructLvalue) { AStructLvalue aNode = (AStructLvalue)node; AStructLvalue aOther = (AStructLvalue)otherNode; if (data.StructFieldLinks[aNode] != data.StructFieldLinks[aOther]) { canMerge = false; } return; } }
public override void CaseAStringConstExp(AStringConstExp node) { Write(node.GetStringLiteral().Text); }
public static bool ReturnsTheSame(PExp left, PExp right, SharedData data) { if (left.GetType() != right.GetType()) { return(false); } if (left is ABinopExp) { ABinopExp aLeft = (ABinopExp)left; ABinopExp aRight = (ABinopExp)right; if (aLeft.GetBinop().GetType() != aRight.GetBinop().GetType()) { return(false); } return(ReturnsTheSame(aLeft.GetLeft(), aRight.GetLeft(), data) && ReturnsTheSame(aLeft.GetRight(), aRight.GetRight(), data)); } if (left is AUnopExp) { AUnopExp aLeft = (AUnopExp)left; AUnopExp aRight = (AUnopExp)right; if (aLeft.GetUnop().GetType() != aRight.GetUnop().GetType()) { return(false); } return(ReturnsTheSame(aLeft.GetExp(), aRight.GetExp(), data)); } if (left is AIntConstExp) { AIntConstExp aLeft = (AIntConstExp)left; AIntConstExp aRight = (AIntConstExp)right; return(int.Parse(aLeft.GetIntegerLiteral().Text) == int.Parse(aRight.GetIntegerLiteral().Text)); } if (left is AFixedConstExp) { AFixedConstExp aLeft = (AFixedConstExp)left; AFixedConstExp aRight = (AFixedConstExp)right; return(aLeft.GetFixedLiteral().Text == aRight.GetFixedLiteral().Text); } if (left is AStringConstExp) { AStringConstExp aLeft = (AStringConstExp)left; AStringConstExp aRight = (AStringConstExp)right; return(aLeft.GetStringLiteral().Text == aRight.GetStringLiteral().Text); } if (left is ACharConstExp) { ACharConstExp aLeft = (ACharConstExp)left; ACharConstExp aRight = (ACharConstExp)right; return(aLeft.GetCharLiteral().Text == aRight.GetCharLiteral().Text); } if (left is ABooleanConstExp) { ABooleanConstExp aLeft = (ABooleanConstExp)left; ABooleanConstExp aRight = (ABooleanConstExp)right; return(aLeft.GetBool().GetType() == aRight.GetBool().GetType()); } if (left is ASimpleInvokeExp) { //A method might not return the same thing each time it is called return(false); } if (left is ALvalueExp) { ALvalueExp aLeft = (ALvalueExp)left; ALvalueExp aRight = (ALvalueExp)right; return(ReturnsTheSame(aLeft.GetLvalue(), aRight.GetLvalue(), data)); } if (left is AParenExp) { AParenExp aLeft = (AParenExp)left; AParenExp aRight = (AParenExp)right; return(ReturnsTheSame(aLeft.GetExp(), aRight.GetExp(), data)); } throw new Exception("Util.ReturnsTheSame. Unexpected type, got " + left.GetType()); }