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); }
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); }
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; }
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; }