예제 #1
0
        public override void OutABinopExp(ABinopExp node)
        {
            if (node.Parent() is ABinopExp || node.Parent() is AUnopExp)
            {
                AParenExp paren = new AParenExp();
                node.ReplaceBy(paren);
                paren.SetExp(node);

                finalTrans.data.ExpTypes[paren] = finalTrans.data.ExpTypes[node];
            }
            base.OutABinopExp(node);
        }
예제 #2
0
        public override void OutABinopExp(ABinopExp node)
        {
            if (data.ExpTypes[node.GetLeft()] is ANamedType && data.StructTypeLinks.ContainsKey((ANamedType)data.ExpTypes[node.GetLeft()]))
            {
                AStructDecl str            = data.StructTypeLinks[(ANamedType)data.ExpTypes[node.GetLeft()]];
                PExp        replacementExp = new ABooleanConstExp(new ATrueBool());
                data.ExpTypes[replacementExp] = new ANamedType(new TIdentifier("bool"), null);
                foreach (AALocalDecl local in str.GetLocals().OfType <AALocalDecl>())
                {
                    AStructLvalue leftSide = new AStructLvalue(Util.MakeClone(node.GetLeft(), data),
                                                               new ADotDotType(new TDot(".")),
                                                               new TIdentifier(local.GetName().Text));
                    ALvalueExp    leftSideExp = new ALvalueExp(leftSide);
                    AStructLvalue rightSide   = new AStructLvalue(Util.MakeClone(node.GetRight(), data),
                                                                  new ADotDotType(new TDot(".")),
                                                                  new TIdentifier(local.GetName().Text));
                    ALvalueExp rightSideExp = new ALvalueExp(rightSide);


                    data.StructFieldLinks[leftSide]         =
                        data.StructFieldLinks[rightSide]    = local;
                    data.LvalueTypes[leftSide]              =
                        data.ExpTypes[leftSideExp]          =
                            data.LvalueTypes[rightSide]     =
                                data.ExpTypes[rightSideExp] = local.GetType();


                    ABinopExp binop = new ABinopExp(leftSideExp, (PBinop)node.GetBinop().Clone(), rightSideExp);
                    data.ExpTypes[binop] = data.ExpTypes[node];

                    if (replacementExp is ABooleanConstExp)
                    {
                        replacementExp = binop;
                    }
                    else
                    {
                        replacementExp = new ABinopExp(replacementExp, new ALazyAndBinop(new TAndAnd("&&")), binop);
                        data.ExpTypes[replacementExp] = new ANamedType(new TIdentifier("bool"), null);
                    }
                }
                node.ReplaceBy(replacementExp);
                replacementExp.Apply(this);
            }

            base.OutABinopExp(node);
        }
예제 #3
0
        public override void DefaultIn(Node node)
        {
            if (node is PExp)
            {
                PExp exp = (PExp)node;
                if (finalTrans.data.ExpTypes[exp] is ANamedType)
                {
                    ANamedType type = (ANamedType)finalTrans.data.ExpTypes[exp];
                    if (finalTrans.data.StructTypeLinks.ContainsKey(type))
                    {
                        AStructDecl strDecl = finalTrans.data.StructTypeLinks[type];
                        if (strDecl.GetLocals().Cast <PLocalDecl>().Select(decl => decl is AALocalDecl).Count() == 0)
                        {
                            if (node.Parent() is AAssignmentExp)
                            {
                                node = node.Parent().Parent();
                            }
                            MoveMethodDeclsOut mover = new MoveMethodDeclsOut("removedStructVar", finalTrans.data);
                            node.Apply(mover);
                            foreach (PStm pStm in mover.NewStatements)
                            {
                                pStm.Apply(this);
                            }
                            node.Parent().RemoveChild(node);

                            if (node.Parent() is ABinopExp)
                            {
                                ABinopExp        parent = (ABinopExp)node.Parent();
                                ABooleanConstExp replacer;
                                if (parent.GetBinop() is ANeBinop || parent.GetBinop() is AGtBinop || parent.GetBinop() is ALtBinop)
                                {
                                    replacer = new ABooleanConstExp(new AFalseBool());
                                }
                                else
                                {
                                    replacer = new ABooleanConstExp(new ATrueBool());
                                }
                                finalTrans.data.ExpTypes[replacer] = new ANamedType(new TIdentifier("bool"), null);
                                parent.ReplaceBy(replacer);
                            }
                        }
                    }
                }
            }
        }
예제 #4
0
        //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);
        }
예제 #5
0
        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();
                }
            }
        }