/// <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);
        }
 /// <summary>
 /// カンマで区切られた引数を一括して取得。
 /// return時にはendWithの次の文字がCurrentになっているはず。終端の適切さの検証はExpressionParserがが行う。
 /// 呼び出し元はCodeEEを適切に処理すること
 /// </summary>
 /// <returns></returns>
 public static IOperandTerm[] ReduceArguments(WordCollection wc, ArgsEndWith endWith, bool isDefine)
 {
     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;
 }