Beispiel #1
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);
        }
Beispiel #2
0
 public Type GetOperandType()
 {
     if (LeftTerm != null)
     {
         return(LeftTerm.GetOperandType());
     }
     return(typeof(void));
 }
Beispiel #3
0
        public static IOperandTerm ReduceTernaryTerm(OperatorCode op, IOperandTerm o1, IOperandTerm o2, IOperandTerm o3)
        {
            OperatorMethod method = null;

            if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(Int64)) && (o3.GetOperandType() == typeof(Int64)))
            {
                method = ternaryIntIntInt;
            }
            else if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(string)) && (o3.GetOperandType() == typeof(string)))
            {
                method = ternaryIntStrStr;
            }
            if (method != null)
            {
                return(new FunctionMethodTerm(method, new IOperandTerm[] { o1, o2, o3 }));
            }
            throw new CodeEE("三項演算子の使用法が不正です");
        }
Beispiel #4
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);
        }
Beispiel #5
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);
        }
Beispiel #6
0
        ///// <summary>
        ///// 単純文字列、書式付文字列、文字列式のうち、文字列式を取り扱う。
        ///// 終端記号が正しいかどうかは呼び出し元で調べること
        ///// </summary>
        ///// <param name="st"></param>
        ///// <returns></returns>
        //public static IOperandTerm ReduceStringTerm(WordCollection wc, TermEndWith endWith)
        //{
        //    IOperandTerm term = reduceTerm(wc, false, endWith, VariableCode.__NULL__);
        //    if (term.GetOperandType() != typeof(string))
        //        throw new CodeEE("式の結果が文字列ではありません");
        //    return term;
        //}

        public static IOperandTerm ReduceIntegerTerm(WordCollection wc, TermEndWith endwith)
        {
            IOperandTerm term = reduceTerm(wc, false, endwith, VariableCode.__NULL__);

            if (term == null)
            {
                throw new CodeEE("構文を式として解釈できません");
            }
            if (term.GetOperandType() != typeof(Int64))
            {
                throw new CodeEE("式の結果が数値ではありません");
            }
            return(term);
        }
Beispiel #7
0
        /// <summary>
        /// カンマで区切られた引数を一括して取得。
        /// return時にはendWithの次の文字がCurrentになっているはず。終端の適切さの検証はExpressionParserがが行う。
        /// 呼び出し元はCodeEEを適切に処理すること
        /// </summary>
        /// <returns></returns>
        public static IOperandTerm[] ReduceArguments(WordCollection wc, ArgsEndWith endWith, bool isDefine)
        {
            if (wc == null)
            {
                throw new ExeEE("空のストリームを渡された");
            }
            List <IOperandTerm> terms       = new List <IOperandTerm>();
            TermEndWith         termEndWith = TermEndWith.EoL;

            switch (endWith)
            {
            case ArgsEndWith.EoL:
                termEndWith = TermEndWith.Comma;
                break;

            //case ArgsEndWith.RightBracket:
            //    termEndWith = TermEndWith.RightBracket_Comma;
            //    break;
            case ArgsEndWith.RightParenthesis:
                termEndWith = TermEndWith.RightParenthesis_Comma;
                break;
            }
            TermEndWith termEndWith_Assignment = termEndWith | TermEndWith.Assignment;

            while (true)
            {
                Word word = wc.Current;
                switch (word.Type)
                {
                case '\0':
                    if (endWith == ArgsEndWith.RightBracket)
                    {
                        throw new CodeEE("'['に対応する']'が見つかりません");
                    }
                    if (endWith == ArgsEndWith.RightParenthesis)
                    {
                        throw new CodeEE("'('に対応する')'が見つかりません");
                    }
                    goto end;

                case ')':
                    if (endWith == ArgsEndWith.RightParenthesis)
                    {
                        wc.ShiftNext();
                        goto end;
                    }
                    throw new CodeEE("構文解析中に予期しない')'を発見しました");

                case ']':
                    if (endWith == ArgsEndWith.RightBracket)
                    {
                        wc.ShiftNext();
                        goto end;
                    }
                    throw new CodeEE("構文解析中に予期しない']'を発見しました");
                }
                if (!isDefine)
                {
                    terms.Add(ReduceExpressionTerm(wc, termEndWith));
                }
                else
                {
                    terms.Add(ReduceExpressionTerm(wc, termEndWith_Assignment));
                    if (terms[terms.Count - 1] == null)
                    {
                        throw new CodeEE("関数定義の引数は省略できません");
                    }
                    if (wc.Current is OperatorWord)
                    {                    //=がある
                        wc.ShiftNext();
                        IOperandTerm term = reduceTerm(wc, false, termEndWith, VariableCode.__NULL__);
                        if (term == null)
                        {
                            throw new CodeEE("'='の後に式がありません");
                        }
                        if (term.GetOperandType() != terms[terms.Count - 1].GetOperandType())
                        {
                            throw new CodeEE("'='の前後で型が一致しません");
                        }
                        terms.Add(term);
                    }
                    else
                    {
                        if (terms[terms.Count - 1].GetOperandType() == typeof(Int64))
                        {
                            terms.Add(new NullTerm(0));
                        }
                        else
                        {
                            terms.Add(new NullTerm(""));
                        }
                    }
                }
                if (wc.Current.Type == ',')
                {
                    wc.ShiftNext();
                }
            }
end:
            IOperandTerm[] ret = new IOperandTerm[terms.Count];
            terms.CopyTo(ret);
            return(ret);
        }
 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.Readonly)
             throw new CodeEE("変更できない変数をインクリメントすることはできません");
     }
     if (o1.GetOperandType() == typeof(Int64))
     {
         if (op == OperatorCode.Plus)
             return o1;
         if (unaryDic.ContainsKey(op))
             method = unaryDic[op];
     }
     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);
 }
 public static IOperandTerm ReduceTernaryTerm(OperatorCode op, IOperandTerm o1, IOperandTerm o2, IOperandTerm o3)
 {
     OperatorMethod method = null;
     if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(Int64)) && (o3.GetOperandType() == typeof(Int64)))
         method = ternaryIntIntInt;
     else if ((o1.GetOperandType() == typeof(Int64)) && (o2.GetOperandType() == typeof(string)) && (o3.GetOperandType() == typeof(string)))
         method = ternaryIntStrStr;
     if (method != null)
         return new FunctionMethodTerm(method, new IOperandTerm[] { o1, o2, o3 });
     throw new CodeEE("三項演算子の使用法が不正です");
 }
Beispiel #10
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);
 }