示例#1
0
        private static WordCollection expandMacro(WordCollection wc)
        {
            //マクロ展開
            wc.Pointer = 0;
            int count = 0;

            while (!wc.EOL)
            {
                IdentifierWord word = wc.Current as IdentifierWord;
                if (word == null)
                {
                    wc.ShiftNext();
                    continue;
                }
                string      idStr = word.Code;
                DefineMacro macro = GlobalStatic.IdentifierDictionary.GetMacro(idStr);
                if (macro == null)
                {
                    wc.ShiftNext();
                    continue;
                }
                count++;
                if (count > MAX_EXPAND_MACRO)
                {
                    throw new CodeEE("マクロの展開数が1文あたりの上限" + MAX_EXPAND_MACRO.ToString() + "を超えました(自己参照・循環参照のおそれ)");
                }
                if (!macro.HasArguments)
                {
                    wc.Remove();
                    wc.InsertRange(macro.Statement);
                    continue;
                }
                //関数型マクロ
                wc = expandFunctionlikeMacro(macro, wc);
            }
            wc.Pointer = 0;
            return(wc);
        }
示例#2
0
        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);
        }
示例#3
0
 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;
 }
示例#4
0
 private static WordCollection expandMacro(WordCollection wc)
 {
     //マクロ展開
     wc.Pointer = 0;
     int count = 0;
     while (!wc.EOL)
     {
         IdentifierWord word = wc.Current as IdentifierWord;
         if (word == null)
         {
             wc.ShiftNext();
             continue;
         }
         string idStr = word.Code;
         DefineMacro macro = GlobalStatic.IdentifierDictionary.GetMacro(idStr);
         if (macro == null)
         {
             wc.ShiftNext();
             continue;
         }
         count++;
         if (count > MAX_EXPAND_MACRO)
             throw new CodeEE("マクロの展開数が1文あたりの上限" + MAX_EXPAND_MACRO.ToString() + "を超えました(自己参照・循環参照のおそれ)");
         if (!macro.HasArguments)
         {
             wc.Remove();
             wc.InsertRange(macro.Statement);
             continue;
         }
         //関数型マクロ
         wc = expandFunctionlikeMacro(macro, wc);
     }
     wc.Pointer = 0;
     return wc;
 }