コード例 #1
0
        // ------------------------------------------------------------------------

        private void SearchForMacros(List <Token> tokenList,
                                     Stack <string> nameStack)
        {
            for (int index = 0; index < tokenList.Count; ++index)
            {
                Token thisToken = tokenList[index];

                /*if (CCompiler_Main.Scanner.Path.Name.Contains("AssertTest")) {
                 * Console.Out.WriteLine("5: " + CCompiler_Main.Scanner.Line);
                 * }*/
                CCompiler_Main.Scanner.Line += thisToken.GetNewlineCount();

                if (thisToken.Id == CCompiler_Pre.Tokens.NAME)
                {
                    string name = (string)thisToken.Value;
                    int    beginNewlineCount = thisToken.GetNewlineCount();

                    if (!nameStack.Contains(name) && Preprocessor.MacroMap.ContainsKey(name))
                    {
                        Token nextToken = tokenList[index + 1];

                        if ((nextToken.Id == CCompiler_Pre.Tokens.LEFT_PARENTHESIS) &&
                            !nextToken.HasWhitespace())
                        {
                            int                  countIndex = index + 2, level = 1, totalNewlineCount = 0;
                            List <Token>         subList  = new List <Token>();
                            List <List <Token> > mainList = new List <List <Token> >();

                            while (true)
                            {
                                nextToken = tokenList[countIndex];
                                int newlineCount = nextToken.GetNewlineCount();
                                totalNewlineCount           += newlineCount;
                                CCompiler_Main.Scanner.Line += newlineCount;

                                /*if (CCompiler_Main.Scanner.Path.Name.Contains("AssertTest")) {
                                 * Console.Out.WriteLine("6: " + CCompiler_Main.Scanner.Line);
                                 * }*/

                                nextToken.ClearNewlineCount();

                                Token token = tokenList[countIndex];
                                Assert.Error(token.Id != CCompiler_Pre.Tokens.EOF,
                                             Message.Invalid_end_of_macro_call);

                                switch (token.Id)
                                {
                                case CCompiler_Pre.Tokens.LEFT_PARENTHESIS:
                                    ++level;
                                    subList.Add(token);
                                    break;

                                case CCompiler_Pre.Tokens.RIGHT_PARENTHESIS:
                                    if ((--level) > 0)
                                    {
                                        subList.Add(token);
                                    }
                                    break;

                                default:
                                    if ((level == 1) && (token.Id == CCompiler_Pre.Tokens.COMMA))
                                    {
                                        Assert.Error(subList.Count > 0, name, Message.Empty_macro_parameter);
                                        SearchForMacros(subList, nameStack); // XXX
                                        mainList.Add(subList);
                                        subList = new List <Token>();
                                    }
                                    else
                                    {
                                        subList.Add(token);
                                    }
                                    break;
                                }

                                if (level == 0)
                                {
                                    Assert.Error(subList.Count > 0, name, Message.Empty_macro_parameter_list);
                                    mainList.Add(subList);
                                    break;
                                }

                                ++countIndex;
                            }

                            Macro macro = Preprocessor.MacroMap[name];
                            Assert.Error(macro.Parameters() == mainList.Count, name,
                                         Message.Invalid_number_of_parameters_in_macro_call);

                            List <Token> cloneListX = CloneList(macro.TokenList());

                            for (int macroIndex = (cloneListX.Count - 1); macroIndex >= 0; --macroIndex)
                            {
                                Token macroToken = cloneListX[macroIndex];

                                if (macroToken.Id == CCompiler_Pre.Tokens.MARK)
                                {
                                    int markIndex = (int)macroToken.Value;
                                    cloneListX.RemoveAt(macroIndex);
                                    List <Token> replaceList = CloneList(mainList[markIndex]);

                                    if ((macroIndex > 0) && (cloneListX[macroIndex - 1].Id == CCompiler_Pre.Tokens.SHARP))
                                    {
                                        string text = "\"" + TokenListToString(replaceList) + "\"";
                                        cloneListX.Insert(macroIndex, new Token(CCompiler_Pre.Tokens.STRING, text));
                                        cloneListX.RemoveAt(--macroIndex);
                                    }
                                    else
                                    {
                                        cloneListX.InsertRange(macroIndex, replaceList);
                                    }
                                }
                            }

                            nameStack.Push(name);
                            SearchForMacros(cloneListX, nameStack);
                            nameStack.Pop();

                            /*for (int removeCount = index; removeCount <= countIndex; ++removeCount) {
                             * tokenList.RemoveAt(index);
                             * }*/

                            tokenList.RemoveRange(index, countIndex - index + 1);
                            tokenList.InsertRange(index, cloneListX);
                            tokenList[index].AddNewlineCount(beginNewlineCount);
                            tokenList[index + cloneListX.Count].AddNewlineCount(totalNewlineCount);
                            index += cloneListX.Count - 1;
                        }
                        else
                        {
                            Macro macro = Preprocessor.MacroMap[name];
                            Assert.Error(macro.Parameters() == 0, name,
                                         Message.Invalid_number_of_parameters_in_macro_call);
                            List <Token> cloneListX = CloneList(macro.TokenList());
                            nameStack.Push(name);
                            SearchForMacros(cloneListX, nameStack);
                            nameStack.Pop();

                            tokenList.RemoveAt(index);
                            tokenList.InsertRange(index, cloneListX);
                            tokenList[index].AddNewlineCount(beginNewlineCount);
                            index += cloneListX.Count - 1;
                        }
                    }
                    else if (name.Equals("__STDC__"))
                    {
                        tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN, 1, beginNewlineCount);
                    }
                    else if (name.Equals("__FILE__"))
                    {
                        string text = "\"" + CCompiler_Main.Scanner.Path.FullName.Replace("\\", "\\\\") + "\"";
                        tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN, text, beginNewlineCount);
                    }
                    else if (name.Equals("__LINE__"))
                    {
                        /*if (CCompiler_Main.Scanner.Path.Name.Contains("AssertTest")) {
                         * Console.Out.WriteLine("__LINE__ " + CCompiler_Main.Scanner.Line);
                         * }*/

                        tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN, CCompiler_Main.Scanner.Line, beginNewlineCount);
                    }
                    else if (name.Equals("__DATE__"))
                    {
                        string text = "\"" + DateTime.Now.ToString("MMMM dd yyyy") + "\"";
                        tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN, text, beginNewlineCount);
                    }
                    else if (name.Equals("__TIME__"))
                    {
                        string text = "\"" + DateTime.Now.ToString("HH:mm:ss") + "\"";
                        tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN, text, beginNewlineCount);
                    }
                }
            }
        }
コード例 #2
0
        // ------------------------------------------------------------------------

        private void SearchForMacros(List <Token> tokenList,
                                     Stack <string> nameStack)
        {
            for (int index = 0; index < tokenList.Count; ++index)
            {
                Token thisToken = tokenList[index];
                CCompiler_Main.Scanner.Line += thisToken.GetNewlineCount();

                if (thisToken.Id == CCompiler_Pre.Tokens.NAME)
                {
                    string name = (string)thisToken.Value;
                    int    beginNewlineCount = thisToken.GetNewlineCount();

                    if (!nameStack.Contains(name) && m_macroMap.ContainsKey(name))
                    {
                        Macro macro = m_macroMap[name];
                        Error.Check(macro.Parameters == 0, name, Message.
                                    Invalid_number_of_parameters_in_macro_call);
                        List <Token> cloneListX = CloneList(macro.TokenList);
                        nameStack.Push(name);
                        SearchForMacros(cloneListX, nameStack);
                        nameStack.Pop();

                        tokenList.RemoveAt(index);
                        tokenList.InsertRange(index, cloneListX);
                        tokenList[index].AddNewlineCount(beginNewlineCount);
                        index += cloneListX.Count - 1;
                    }
                    else
                    {
                        switch (name)
                        {
                        case "__STDC__":
                            tokenList[index] =
                                new Token(CCompiler_Pre.Tokens.TOKEN, 1, beginNewlineCount);
                            break;

                        case "__FILE__": {
                            string text = "\"" + CCompiler_Main.Scanner.Path
                                          .FullName.Replace("\\", "\\\\") + "\"";
                            tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN,
                                                         text, beginNewlineCount);
                        }
                        break;

                        case "__LINE__":
                            tokenList[index] =
                                new Token(CCompiler_Pre.Tokens.TOKEN,
                                          CCompiler_Main.Scanner.Line, beginNewlineCount);
                            break;

                        case "__DATE__": {
                            string text = "\"" + DateTime.Now.ToString("MMMM dd yyyy") +
                                          "\"";
                            tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN,
                                                         text, beginNewlineCount);
                        }
                        break;

                        case "__TIME__": {
                            string text = "\"" + DateTime.Now.ToString("HH:mm:ss") +
                                          "\"";
                            tokenList[index] = new Token(CCompiler_Pre.Tokens.TOKEN,
                                                         text, beginNewlineCount);
                        }
                        break;
                        }
                    }
                }
                else if (thisToken.Id == CCompiler_Pre.Tokens.NAME_WITH_PARENTHESES)
                {
                    string name = (string)thisToken.Value;
                    int    beginNewlineCount = thisToken.GetNewlineCount();

                    if (!nameStack.Contains(name) && m_macroMap.ContainsKey(name))
                    {
                        int                  countIndex = index + 1, level = 1, totalNewlineCount = 0;
                        List <Token>         subList  = new List <Token>();
                        List <List <Token> > mainList = new List <List <Token> >();

                        while (true)
                        {
                            Token nextToken    = tokenList[countIndex];
                            int   newlineCount = nextToken.GetNewlineCount();
                            totalNewlineCount           += newlineCount;
                            CCompiler_Main.Scanner.Line += newlineCount;
                            nextToken.ClearNewlineCount();

                            Token token = tokenList[countIndex];
                            Error.Check(token.Id != CCompiler_Pre.Tokens.END_OF_LINE,
                                        Message.Invalid_end_of_macro_call);

                            switch (token.Id)
                            {
                            case CCompiler_Pre.Tokens.LEFT_PARENTHESIS:
                                ++level;
                                subList.Add(token);
                                break;

                            case CCompiler_Pre.Tokens.RIGHT_PARENTHESIS:
                                if ((--level) > 0)
                                {
                                    subList.Add(token);
                                }
                                break;

                            default:
                                if ((level == 1) &&
                                    (token.Id == CCompiler_Pre.Tokens.COMMA))
                                {
                                    Error.Check(subList.Count > 0, name,
                                                Message.Empty_macro_parameter);
                                    SearchForMacros(subList, nameStack); // XXX
                                    mainList.Add(subList);
                                    subList = new List <Token>();
                                }
                                else
                                {
                                    subList.Add(token);
                                }
                                break;
                            }

                            if (level == 0)
                            {
                                Error.Check(subList.Count > 0, name,
                                            Message.Empty_macro_parameter_list);
                                mainList.Add(subList);
                                break;
                            }

                            ++countIndex;
                        }

                        Macro macro = m_macroMap[name];
                        Error.Check(macro.Parameters == mainList.Count, name,
                                    Message.Invalid_number_of_parameters_in_macro_call);

                        List <Token>           cloneList       = CloneList(macro.TokenList);
                        IDictionary <int, int> indexToParamMap = macro.IndexToParamMap;

                        for (int macroIndex = (cloneList.Count - 1);
                             macroIndex >= 0; --macroIndex)
                        {
                            Token macroToken = cloneList[macroIndex];

                            int paramIndex;
                            if (indexToParamMap.TryGetValue(macroIndex, out paramIndex))
                            {
                                cloneList.RemoveAt(macroIndex);
                                List <Token> replaceList = CloneList(mainList[paramIndex]);

                                if ((macroIndex > 0) && (cloneList[macroIndex - 1].Id ==
                                                         CCompiler_Pre.Tokens.SHARP))
                                {
                                    string text = "\"" + TokenListToString(replaceList) + "\"";
                                    cloneList.Insert(macroIndex,
                                                     new Token(CCompiler_Pre.Tokens.STRING, text));
                                    cloneList.RemoveAt(--macroIndex);
                                }
                                else
                                {
                                    cloneList.InsertRange(macroIndex, replaceList);
                                }
                            }
                        }

                        nameStack.Push(name);
                        SearchForMacros(cloneList, nameStack);
                        nameStack.Pop();

                        tokenList.RemoveRange(index, countIndex - index + 1);
                        tokenList.InsertRange(index, cloneList);
                        tokenList[index].AddNewlineCount(beginNewlineCount);
                        tokenList[index +
                                  cloneList.Count].AddNewlineCount(totalNewlineCount);
                        index += cloneList.Count - 1;
                    }
                }
            }
        }
コード例 #3
0
        // ------------------------------------------------------------------------

        public void DoDefine(List <Token> tokenList)
        {
            Assert.Error(tokenList[2].Id == CCompiler_Pre.Tokens.NAME,
                         TokenListToString(tokenList), Message.Invalid_define_directive);
            string name = tokenList[2].ToString();
            Macro  macro;

            if ((tokenList[3].Id == CCompiler_Pre.Tokens.LEFT_PARENTHESIS) &&
                !tokenList[3].HasWhitespace())
            {
                int tokenIndex = 4, paramIndex = 0;
                IDictionary <string, int> paramMap = new Dictionary <string, int>();

                while (true)
                {
                    Token nextToken = tokenList[tokenIndex++];
                    Assert.Error(nextToken.Id == CCompiler_Pre.Tokens.NAME,
                                 nextToken.ToString(), Message.Invalid_macro_definitializerion);
                    string paramName = (string)nextToken.Value;
                    Assert.Error(!paramMap.ContainsKey(paramName),
                                 paramName, Message.Repeated_macro_parameter);
                    paramMap.Add(paramName, paramIndex++);

                    nextToken = tokenList[tokenIndex++];
                    if (nextToken.Id == CCompiler_Pre.Tokens.COMMA)
                    {
                        // Empty.
                    }
                    else if (nextToken.Id == CCompiler_Pre.Tokens.RIGHT_PARENTHESIS)
                    {
                        break;
                    }
                    else
                    {
                        Assert.Error(nextToken.ToString(), Message.Invalid_macro_definitializerion);
                    }
                }

                List <Token> macroList             = tokenList.GetRange(tokenIndex, tokenList.Count - tokenIndex);

                foreach (Token macroToken in macroList)
                {
                    if (macroToken.Id == CCompiler_Pre.Tokens.NAME)
                    {
                        string macroName = (string)macroToken.Value;

                        if (paramMap.ContainsKey(macroName))
                        {
                            macroToken.Id    = CCompiler_Pre.Tokens.MARK;
                            macroToken.Value = paramMap[macroName];
                        }
                    }
                }

                macro = new Macro(paramMap.Count, macroList);
            }
            else
            {
                macro = new Macro(0, tokenList.GetRange(3, tokenList.Count - 3));
            }

            if (!Preprocessor.MacroMap.ContainsKey(name))
            {
                Preprocessor.MacroMap.Add(name, macro);
            }
            else
            {
                Assert.Error(Preprocessor.MacroMap[name].Equals(macro),
                             name, Message.Invalid_macro_redefinitializerion);
            }
        }
コード例 #4
0
        // ------------------------------------------------------------------------

        public void DoDefine(List <Token> tokenList)
        {
            Error.Check((tokenList[2].Id == CCompiler_Pre.Tokens.NAME) ||
                        (tokenList[2].Id ==
                         CCompiler_Pre.Tokens.NAME_WITH_PARENTHESES),
                        TokenListToString(tokenList),
                        Message.Invalid_define_directive);
            Macro macro;

            if (tokenList[2].Id == CCompiler_Pre.Tokens.NAME)
            {
                macro = new Macro(0, tokenList.GetRange(3, tokenList.Count - 3), null);
            }
            else
            {
                int tokenIndex = 3, paramIndex = 0;
                IDictionary <string, int> paramMap = new Dictionary <string, int>();

                while (true)
                {
                    Token nextToken = tokenList[tokenIndex++];
                    Error.Check(nextToken.Id == CCompiler_Pre.Tokens.NAME,
                                nextToken.ToString(),
                                Message.Invalid_macro_definition);
                    string paramName = (string)nextToken.Value;
                    Error.Check(!paramMap.ContainsKey(paramName),
                                paramName, Message.Repeated_macro_parameter);
                    paramMap.Add(paramName, paramIndex++);

                    nextToken = tokenList[tokenIndex++];
                    if (nextToken.Id == CCompiler_Pre.Tokens.COMMA)
                    {
                        // Empty.
                    }
                    else if (nextToken.Id == CCompiler_Pre.Tokens.RIGHT_PARENTHESIS)
                    {
                        break;
                    }
                    else
                    {
                        Error.Report(nextToken.ToString(),
                                     Message.Invalid_macro_definition);
                    }
                }

                List <Token> macroList             =
                    tokenList.GetRange(tokenIndex, tokenList.Count - tokenIndex);
                for (int index = macroList.Count - 1; index >= 0; --index)
                {
                    if (macroList[index].Id == CCompiler_Pre.Tokens.NAME_WITH_PARENTHESES)
                    {
                        macroList[index].Id = CCompiler_Pre.Tokens.NAME;
                        Token newToken =
                            new Token(CCompiler_Pre.Tokens.LEFT_PARENTHESIS, "(");
                        macroList.Insert(index + 1, newToken);
                    }
                }

                IDictionary <int, int> indexToParamMap = new Dictionary <int, int>();
                for (int index = 0; index < macroList.Count; ++index)
                {
                    Token macroToken = macroList[index];

                    if (macroToken.Id == CCompiler_Pre.Tokens.NAME)
                    {
                        string macroName = (string)macroToken.Value;

                        if (paramMap.ContainsKey(macroName))
                        {
                            indexToParamMap[index] = paramMap[macroName];
                        }
                    }
                }

                macro = new Macro(paramMap.Count, macroList, indexToParamMap);
            }

            string name = (string)tokenList[2].Value;

            if (!m_macroMap.ContainsKey(name))
            {
                m_macroMap.Add(name, macro);
            }
            else
            {
                Error.Check(m_macroMap[name].Equals(macro), name,
                            Message.Invalid_macro_redefinition);
            }
        }