Beispiel #1
0
        public static bool TryCreateFromDeclaration(string name, string body, out MethodMacro method)
        {
            method = null;

            try
            {
                PreProcessorEngine engine = new PreProcessorEngine(new PreProcessorOptions());
                using (var reader = new StringReader("#define " + name + body))
                {
                    engine.Process(new TextReaderBag(reader));
                    Macro created = null;
                    if (engine.MacroMap.TryGetValue(name, out created) && created.IsMethod)
                    {
                        method = (MethodMacro)created;
                        return(true);
                    }
                }
            }
            catch
            {
                return(false);
            }

            return(false);
        }
Beispiel #2
0
        /// <summary>
        /// Called when a define token is hit
        /// </summary>
        /// <remarks></remarks>

        private void ProcessPoundDefine(PreprocessorLine line)
        {
            // Get the non whitespace tokens
            List <Token> list = line.GetValidTokens();

            ThrowIfFalse(list[0].TokenType == TokenType.PoundDefine);

            Macro macro = null;

            if (list.Count == 3 && list[1].TokenType == TokenType.Word)
            {
                string name = list[1].Value;
                macro = new Macro(name, list[2].Value);
            }
            else if (list.Count == 2 && list[1].TokenType == TokenType.Word)
            {
                string name = list[1].Value;
                macro = new Macro(name, string.Empty);
            }
            else if (list.Count == 1)
            {
                _scanner.AddWarning("Encountered an empty #define");
            }
            else if (list.Count > 3 && list[1].TokenType == TokenType.Word && list[2].TokenType == TokenType.ParenOpen)
            {
                macro = ProcessPoundDefineMethod(line);
            }
            else
            {
                macro = ProcessPoundDefineComplexMacro(line);
            }

            if (macro != null)
            {
                Macro oldMacro = null;
                if (_macroMap.TryGetValue(macro.Name, out oldMacro) && oldMacro.IsPermanent)
                {
                    TraceToStream("Kept: {0} -> {1} Attempted Value {2}", oldMacro.Name, oldMacro.Value, macro.Value);
                }
                else
                {
                    _macroMap[macro.Name] = macro;
                    if (macro.IsMethod)
                    {
                        MethodMacro method = (MethodMacro)macro;
                        TraceToStream("Defined: {0} -> {1}", macro.Name, method.MethodSignature);
                    }
                    else
                    {
                        TraceToStream("Defined: {0} -> {1}", macro.Name, macro.Value);
                    }
                }
            }
        }
Beispiel #3
0
        /// <summary>
        /// Convert the macros in the result into a list of constants
        /// </summary>
        /// <returns></returns>
        /// <remarks></remarks>
        public List <NativeConstant> ConvertMacrosToConstants()
        {
            var list = new List <NativeConstant>();

            foreach (Macro macro in MacroMap.Values)
            {
                if (macro.IsMethod)
                {
                    MethodMacro method = (MethodMacro)macro;
                    list.Add(new NativeConstant(macro.Name, method.MethodSignature, ConstantKind.MacroMethod));
                }
                else
                {
                    list.Add(new NativeConstant(macro.Name, macro.Value));
                }
            }

            return(list);
        }
Beispiel #4
0
        private List <Token> ReplaceMethodMacro(MethodMacro method, List <Token> args)
        {
            // First run the replacement
            List <Token> retList = method.Replace(args);

            // When creating the arguments for a macro, non-trivial arguments (1+2) come accross
            // as text macros.  For those items we need to reparse them here and put them back into the stream.
            // Have to do this after the above loop so that ## and # are processed correctly
            int i = 0;

            while (i < retList.Count)
            {
                Token cur = retList[i];
                if (cur.TokenType == TokenType.Text && args.IndexOf(cur) >= 0)
                {
                    retList.RemoveAt(i);
                    retList.InsertRange(i, Scanner.TokenizeText(cur.Value, _scanner.Options));
                }

                i += 1;
            }

            return(retList);
        }
Beispiel #5
0
        private void ReplaceDefinedTokens(PreprocessorLine line)
        {
            ThrowIfNull(line);

            int          i    = 0;
            List <Token> list = line.TokenList;

            while ((i < list.Count))
            {
                Token token = list[i];
                if (token.TokenType != TokenType.Word)
                {
                    i += 1;
                    continue;
                }

                Macro macro = null;
                if (_macroMap.TryGetValue(token.Value, out macro))
                {
                    // Remove the original token
                    list.RemoveAt(i);

                    List <Token> replaceList = null;
                    if (macro.IsMethod)
                    {
                        MethodMacro  method = (MethodMacro)macro;
                        List <Token> args   = ParseAndRemoveMacroMethodArguments(list, i);
                        if (args == null)
                        {
                            // Parse did not succeed, move to the next token
                            i += 1;
                        }
                        else
                        {
                            // Insert the tokens
                            replaceList = ReplaceMethodMacro(method, args);
                        }
                    }
                    else
                    {
                        // Use the scanner to create the replacement tokens
                        replaceList = Scanner.TokenizeText(macro.Value, CreateScannerOptions());
                    }

                    if (replaceList != null)
                    {
                        CollapseDoublePounds(replaceList);
                        list.InsertRange(i, replaceList);
                    }
                }
                else
                {
                    i += 1;
                }
            }

            // Do one more pass to check and see if we need a recursive replace
            bool needAnotherPass = false;

            foreach (Token cur in line.TokenList)
            {
                if (cur.TokenType == TokenType.Word && _macroMap.ContainsKey(cur.Value))
                {
                    needAnotherPass = true;
                    break;
                }
            }

            if (needAnotherPass)
            {
                ReplaceDefinedTokens(line);
            }
        }