internal void AddMacro(DefineMacro mac)
 {
     nameDic.Add(mac.Keyword, DefinedNameType.UserMacro);
     macroDic.Add(mac.Keyword, mac);
 }
        //#define FOO (~~)     id to wc
        //#define BAR($1) (~~)     idwithargs to wc(replaced)
        //#diseble FOOBAR
        //#dim piyo, i
        //#sdim puyo, j
        //static List<string> keywordsList = new List<string>();
        private void analyzeSharpDefine(StringStream st, ScriptPosition position)
        {
            //LexicalAnalyzer.SkipWhiteSpace(st);呼び出し前に行う。
            string srcID = LexicalAnalyzer.ReadSingleIdentifier(st);
            if (srcID == null)
                throw new CodeEE("置換元の識別子がありません", position);
            if (Config.ICVariable)
                srcID = srcID.ToUpper();
            bool hasArg = st.Current == '(';//引数を指定する場合には直後に(が続いていなければならない。ホワイトスペースも禁止。
            //1808a3 代入演算子許可(関数宣言用)
            WordCollection wc = LexicalAnalyzer.Analyse(st, LexEndWith.EoL, false, true);
            if (wc.EOL)
            {
                //throw new CodeEE("置換先の式がありません", position);
                //1808a3 空マクロの許可
                DefineMacro nullmac = new DefineMacro(srcID, new WordCollection(), 0);
                idDic.AddMacro(nullmac);
                return;
            }

            List<string> argID = new List<string>();
            string errMes = "";
            int errLevel = -1;
            idDic.CheckUserMacroName(ref errMes, ref errLevel, srcID);
            if (errLevel >= 0)
            {
                ParserMediator.Warn(errMes, position, errLevel);
                if (errLevel >= 2)
                {
                    noError = false;
                    return;
                }
            }
            if (hasArg)//関数型マクロの引数解析
            {
                wc.ShiftNext();//'('を読み飛ばす
                if (wc.Current.Type == ')')
                    throw new CodeEE("関数型マクロの引数を0個にすることはできません", position);
                while (!wc.EOL)
                {
                    IdentifierWord word = wc.Current as IdentifierWord;
                    if (word == null)
                        throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                    word.SetIsMacro();
                    string id = word.Code;
                    if (argID.Contains(id))
                        throw new CodeEE("置換元の引数に同じ文字が2回以上使われています", position);
                    argID.Add(id);
                    wc.ShiftNext();
                    if (wc.Current.Type == ',')
                    {
                        wc.ShiftNext();
                        continue;
                    }
                    if (wc.Current.Type == ')')
                        break;
                    throw new CodeEE("置換元の引数指定の書式が間違っています", position);
                }
                if (wc.EOL)
                    throw new CodeEE("')'が閉じられていません", position);

                wc.ShiftNext();
            }
            if (wc.EOL)
                throw new CodeEE("置換先の式がありません", position);
            WordCollection destWc = new WordCollection();
            while (!wc.EOL)
            {
                destWc.Add(wc.Current);
                wc.ShiftNext();
            }
            if (hasArg)//関数型マクロの引数セット
            {
                while (!destWc.EOL)
                {
                    IdentifierWord word = destWc.Current as IdentifierWord;
                    if (word == null)
                    {
                        destWc.ShiftNext();
                        continue;
                    }
                    for (int i = 0; i < argID.Count; i++)
                    {
                        if (string.Equals(word.Code, argID[i], Config.SCVariable))
                        {
                            destWc.Remove();
                            destWc.Insert(new MacroWord(i));
                            break;
                        }
                    }
                    destWc.ShiftNext();
                }
                destWc.Pointer = 0;
            }
            if (hasArg)//1808a3 関数型マクロの封印
                throw new CodeEE("関数型マクロは宣言できません", position);
            DefineMacro mac = new DefineMacro(srcID, destWc, argID.Count);
            idDic.AddMacro(mac);
        }
 private static WordCollection expandFunctionlikeMacro(DefineMacro macro, WordCollection wc)
 {
     int macroStart = wc.Pointer;
     wc.ShiftNext();
     SymbolWord symbol = wc.Current as SymbolWord;
     if (symbol == null || symbol.Type != '(')
         throw new CodeEE("関数形式のマクロ" + macro.Keyword + "に引数がありません");
     WordCollection macroWC = macro.Statement.Clone();
     WordCollection[] args = new WordCollection[macro.ArgCount];
     //引数部読み取りループ
     for (int i = 0; i < macro.ArgCount; i++)
     {
         int macroNestBracketS = 0;
         args[i] = new WordCollection();
         while (true)
         {
             wc.ShiftNext();
             if (wc.EOL)
                 throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の用法が正しくありません");
             symbol = wc.Current as SymbolWord;
             if (symbol == null)
             {
                 args[i].Add(wc.Current);
                 continue;
             }
             switch (symbol.Type)
             {
                 case '(': macroNestBracketS++; break;
                 case ')':
                     if (macroNestBracketS > 0)
                     {
                         macroNestBracketS--;
                         break;
                     }
                     if (i != macro.ArgCount - 1)
                         throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の引数の数が正しくありません");
                     goto exitfor;
                 case ',':
                     if (macroNestBracketS == 0)
                         goto exitwhile;
                     break;
             }
             args[i].Add(wc.Current);
         }
     exitwhile:
         if (args[i].Collection.Count == 0)
             throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の引数を省略することはできません");
         continue;
     }
     //引数部読み取りループ終端
     exitfor:
     symbol = wc.Current as SymbolWord;
     if (symbol == null || symbol.Type != ')')
         throw new CodeEE("関数形式のマクロ" + macro.Keyword + "の用法が正しくありません");
     int macroLength = wc.Pointer - macroStart + 1;
     wc.Pointer = macroStart;
     for (int j = 0; j < macroLength; j++)
         wc.Collection.RemoveAt(macroStart);
     while (!macroWC.EOL)
     {
         MacroWord w = macroWC.Current as MacroWord;
         if (w == null)
         {
             macroWC.ShiftNext();
             continue;
         }
         macroWC.Remove();
         macroWC.InsertRange(args[w.Number]);
         macroWC.Pointer += args[w.Number].Collection.Count;
     }
     wc.InsertRange(macroWC);
     wc.Pointer = macroStart;
     return wc;
 }