private static CaseExpression reduceCaseExpression(WordCollection wc)
        {
            CaseExpression ret = new CaseExpression();
            IdentifierWord id  = wc.Current as IdentifierWord;

            if ((id != null) && (id.Code.Equals("IS", Config.SCVariable)))
            {
                wc.ShiftNext();
                ret.CaseType = CaseExpressionType.Is;
                OperatorWord opWT = wc.Current as OperatorWord;
                if (opWT == null)
                {
                    throw new CodeEE("ISキーワードの後に演算子がありません");
                }

                OperatorCode op = opWT.Code;
                if (!OperatorManager.IsBinary(op))
                {
                    throw new CodeEE("ISキーワードの後の演算子が2項演算子ではありません");
                }
                wc.ShiftNext();
                ret.Operator = op;
                ret.LeftTerm = reduceTerm(wc, false, TermEndWith.Comma, VariableCode.__NULL__);
                if (ret.LeftTerm == null)
                {
                    throw new CodeEE("ISキーワードの後に式がありません");
                }
                Type type = ret.LeftTerm.GetOperandType();
                return(ret);
            }
            ret.LeftTerm = reduceTerm(wc, true, TermEndWith.Comma, VariableCode.__NULL__);
            if (ret.LeftTerm == null)
            {
                throw new CodeEE("CASEの引数は省略できません");
            }
            id = wc.Current as IdentifierWord;
            if ((id != null) && (id.Code.Equals("TO", Config.SCVariable)))
            {
                ret.CaseType = CaseExpressionType.To;
                wc.ShiftNext();
                ret.RightTerm = reduceTerm(wc, true, TermEndWith.Comma, VariableCode.__NULL__);
                if (ret.RightTerm == null)
                {
                    throw new CodeEE("TOキーワードの後に式がありません");
                }
                id = wc.Current as IdentifierWord;
                if ((id != null) && (id.Code.Equals("TO", Config.SCVariable)))
                {
                    throw new CodeEE("TOキーワードが2度使われています");
                }
                if (ret.LeftTerm.GetOperandType() != ret.RightTerm.GetOperandType())
                {
                    throw new CodeEE("TOキーワードの前後の型が一致していません");
                }
                return(ret);
            }
            ret.CaseType = CaseExpressionType.Normal;
            return(ret);
        }
Exemple #2
0
        public static IOperandTerm ReduceBinaryTerm(OperatorCode op, IOperandTerm left, IOperandTerm right)
        {
            OperatorMethod method = null;

            if ((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(Int64)))
            {
                if (binaryIntIntDic.ContainsKey(op))
                {
                    method = binaryIntIntDic[op];
                }
            }
            else if ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(string)))
            {
                if (binaryStrStrDic.ContainsKey(op))
                {
                    method = binaryStrStrDic[op];
                }
            }
            else if (((left.GetOperandType() == typeof(Int64)) && (right.GetOperandType() == typeof(string))) ||
                     ((left.GetOperandType() == typeof(string)) && (right.GetOperandType() == typeof(Int64))))
            {
                if (op == OperatorCode.Mult)
                {
                    method = binaryMultIntStr;
                }
            }
            if (method != null)
            {
                return(new FunctionMethodTerm(method, new IOperandTerm[] { left, right }));
            }
            string errMes = "";

            if (left.GetOperandType() == typeof(Int64))
            {
                errMes += "数値型と";
            }
            else if (left.GetOperandType() == typeof(string))
            {
                errMes += "文字列型と";
            }
            else
            {
                errMes += "不定型と";
            }
            if (right.GetOperandType() == typeof(Int64))
            {
                errMes += "数値型の";
            }
            else if (right.GetOperandType() == typeof(string))
            {
                errMes += "文字列型の";
            }
            else
            {
                errMes += "不定型の";
            }
            errMes += "演算に二項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません";
            throw new CodeEE(errMes);
        }
            private int lastPriority()
            {
                if (stack.Count < 3)
                {
                    return(-1);
                }
                object       temp     = (object)stack.Pop();
                OperatorCode opCode   = (OperatorCode)stack.Peek();
                int          priority = OperatorManager.GetPriority(opCode);

                stack.Push(temp);
                return(priority);
            }
Exemple #4
0
            private int lastPriority()
            {
                if (stack.Count < 3)
                {
                    return(-1);
                }
                var temp     = stack.Pop();
                var opCode   = (OperatorCode)stack.Peek();
                var priority = OperatorManager.GetPriority(opCode);

                stack.Push(temp);
                return(priority);
            }
Exemple #5
0
        public static IOperandTerm ReduceUnaryTerm(OperatorCode op, IOperandTerm o1)
        {
            OperatorMethod method = null;

            if (op == OperatorCode.Increment || op == OperatorCode.Decrement)
            {
                VariableTerm var = o1 as VariableTerm;
                if (var == null)
                {
                    throw new CodeEE("変数以外をインクリメントすることはできません");
                }
                if (var.Identifier.IsConst)
                {
                    throw new CodeEE("変更できない変数をインクリメントすることはできません");
                }
            }
            if (o1.GetOperandType() == typeof(Int64))
            {
                if (op == OperatorCode.Plus)
                {
                    return(o1);
                }
                OperatorMethod operator_method = null;
                if (unaryDic.TryGetValue(op, out operator_method))
                {
                    method = operator_method;
                }
            }
            if (method != null)
            {
                return(new FunctionMethodTerm(method, new IOperandTerm[] { o1 }));
            }
            string errMes = "";

            if (o1.GetOperandType() == typeof(Int64))
            {
                errMes += "数値型";
            }
            else if (o1.GetOperandType() == typeof(string))
            {
                errMes += "文字列型";
            }
            else
            {
                errMes += "不定型";
            }
            errMes += "に単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません";
            throw new CodeEE(errMes);
        }
Exemple #6
0
        public static IOperandTerm ReduceUnaryAfterTerm(OperatorCode op, IOperandTerm o1)
        {
            OperatorMethod method = null;

            if (op == OperatorCode.Increment || op == OperatorCode.Decrement)
            {
                var var = o1 as VariableTerm;
                if (var == null)
                {
                    throw new CodeEE("変数以外をインクリメントすることはできません");
                }
                if (var.Identifier.IsConst)
                {
                    throw new CodeEE("変更できない変数をインクリメントすることはできません");
                }
            }
            if (o1.GetOperandType() == typeof(long))
            {
                if (unaryAfterDic.ContainsKey(op))
                {
                    method = unaryAfterDic[op];
                }
            }
            if (method != null)
            {
                return(new FunctionMethodTerm(method, new[] { o1 }));
            }
            var errMes = "";

            if (o1.GetOperandType() == typeof(long))
            {
                errMes += "数値型";
            }
            else if (o1.GetOperandType() == typeof(string))
            {
                errMes += "文字列型";
            }
            else
            {
                errMes += "不定型";
            }
            errMes += "に後置単項演算子\'" + OperatorManager.ToOperatorString(op) + "\'は適用できません";
            throw new CodeEE(errMes);
        }
            private void reduceLastThree()
            {
                //if (stack.Count < 2)
                //    throw new ExeEE("不正な時期の呼び出し");
                IOperandTerm right = (IOperandTerm)stack.Pop();//後から入れたほうが右側
                OperatorCode op    = (OperatorCode)stack.Pop();
                IOperandTerm left  = (IOperandTerm)stack.Pop();

                if (OperatorManager.IsTernary(op))
                {
                    if (stack.Count > 1)
                    {
                        reduceTernary(left, right, op);
                        return;
                    }
                    throw new CodeEE("式の数が不足しています");
                }

                IOperandTerm newTerm = OperatorMethodManager.ReduceBinaryTerm(op, left, right);

                stack.Push(newTerm);
            }
 public void Add(OperatorCode op)
 {
     if (state == 2 || state == 3)
     {
         throw new CodeEE("式が異常です");
     }
     if (state == 0)
     {
         if (!OperatorManager.IsUnary(op))
         {
             throw new CodeEE("式が異常です");
         }
         stack.Push(op);
         if (op == OperatorCode.Plus || op == OperatorCode.Minus || op == OperatorCode.BitNot)
         {
             state = 2;
         }
         else
         {
             state = 3;
         }
         return;
     }
     if (state == 1)
     {
         //後置単項演算子の場合は特殊処理へ
         if (OperatorManager.IsUnaryAfter(op))
         {
             if (hasAfter)
             {
                 hasAfter = false;
                 throw new CodeEE("後置の単項演算子が複数存在しています");
             }
             if (hasBefore)
             {
                 hasBefore = false;
                 throw new CodeEE("インクリメント・デクリメントを前置・後置両方同時に使うことはできません");
             }
             stack.Push(op);
             reduceUnaryAfter();
             //前置単項演算子が処理を待っている場合はここで解決
             if (waitAfter)
             {
                 reduceUnary();
             }
             hasBefore = false;
             hasAfter  = true;
             waitAfter = false;
             return;
         }
         if (!OperatorManager.IsBinary(op) && !OperatorManager.IsTernary(op))
         {
             throw new CodeEE("式が異常です");
         }
         //先に未解決の前置演算子解決
         if (waitAfter)
         {
             reduceUnary();
         }
         int priority = OperatorManager.GetPriority(op);
         //直前の計算の優先度が同じか高いなら還元。
         while (lastPriority() >= priority)
         {
             this.reduceLastThree();
         }
         stack.Push(op);
         state     = 0;
         waitAfter = false;
         hasBefore = false;
         hasAfter  = false;
         return;
     }
     throw new CodeEE("式が異常です");
 }