Example #1
0
        private static bool ExpandObjectMacro(CodeProcessorContext context, Stream data, TokenStream nodes, Lazy <HashSet <UInt32> > stack, Macro macro)
        {
            if (stack.Value.Contains(macro.Id))
            {
                return(false);
            }

            macro.ReplacementList.Position = 0;

            TokenStream result = new TokenStream();

            while (!macro.ReplacementList.Eof())
            {
                if (!TokenPasting(context, macro.ReplacementList, result, false))
                {
                    result.Add(macro.ReplacementList.Get());
                }
            }

            AnyPreventLineBreak(context, data, result, stack);

            stack.Value.Add(macro.Id);

            AnyPreventLineBreak(context, result, nodes, stack);

            stack.Value.Remove(macro.Id);
            return(true);
        }
Example #2
0
        private static bool FunctionMacro(CodeProcessorContext context, UInt32 id, Stream data, TokenStream nodes)
        {
            Macro macro = new Macro(id);

            data.Get();
            do
            {
                if (Whitespace(context, data, nodes))
                {
                    continue;
                }

                if (LineBreak(context, data, nodes))
                {
                    return(ThrowError(context, PreprocessorCodes.MissingBracket));
                }

                long length = data.Skip(".");
                if (length > 0 && length != 3)
                {
                    return(ThrowError(context, PreprocessorCodes.VariadicParameterMismatch));
                }

                IdentifierToken parameter;
                if (length == 3)
                {
                    macro.Variadic = true;
                    break;
                }
                else if (Identifier(data, out parameter))
                {
                    if (parameter.Id == VariadicKeyword)
                    {
                        return(ThrowError(context, PreprocessorCodes.VariadicMacroInParameterList));
                    }

                    data.Position += parameter.Length;
                    macro.Parameter.Add(parameter.Id);
                }
                else if (data.Peek() == ',')
                {
                    data.Get();
                }
                else
                {
                    return(ThrowError(context, PreprocessorCodes.UnexpectedCharacter));
                }
            }while (data.Peek() != ')');
            if (data.Peek() != ')')
            {
                return(ThrowError(context, PreprocessorCodes.MissingBracket));
            }

            data.Get();

            Whitespace(context, data, nodes);

            ReadLine(context, data, macro.ReplacementList);

            if (nodes.CanWrite)
            {
                if (context.Definitions.ContainsKey(id))
                {
                    return(ThrowError(context, PreprocessorCodes.AlreadyDefined));
                }
                else
                {
                    context.Definitions.Add(id, macro);
                }
            }
            return(true);
        }
Example #3
0
        private static bool ExpandFunctionMacro(CodeProcessorContext context, Stream data, TokenStream nodes, Lazy <HashSet <UInt32> > stack, Macro macro)
        {
            if (stack.Value.Contains(macro.Id))
            {
                return(false);
            }

            Whitespace(context, data, nodes);

            if (data.Peek() == '(')
            {
                long streamPos = data.Position;

                List <TokenStream> parameter = new List <TokenStream>();
                if (FunctionMacroParameter(context, data, parameter))
                {
                    if ((macro.Parameter.Count != parameter.Count && !macro.Variadic))
                    {
                        return(ThrowError(context, PreprocessorCodes.ParameterMismatch));
                    }

                    bool hasVariableParameter = ((parameter.Count - macro.Parameter.Count) > 0);
                    macro.ReplacementList.Position = 0;

                    TokenStream preparsed = new TokenStream();
                    while (!macro.ReplacementList.Eof())
                    {
                        if
                        (
                            !Stringify(context, macro, preparsed, parameter) &&
                            !TokenPasting(context, macro, preparsed, parameter, hasVariableParameter) &&
                            !ParameterReplacement(context, macro, preparsed, parameter) &&
                            !String(context, macro.ReplacementList, preparsed) &&
                            !EscapedLineBreak(context, macro.ReplacementList) &&
                            !Comment(context, macro.ReplacementList)
                        )
                        {
                            preparsed.Add(macro.ReplacementList.Get());
                        }
                    }
                    TokenStream result = new TokenStream();
                    while (!preparsed.Eof())
                    {
                        IdentifierToken token; if (Identifier(preparsed, out token))
                        {
                            object objectMacro; if (context.Definitions.TryGetValue(token.Id, out objectMacro) && (objectMacro as Macro).Parameter.Count == 0 && !(objectMacro as Macro).Variadic)
                            {
                                long tmp = preparsed.Position;
                                preparsed.Position += token.Length;

                                if (ExpandObjectMacro(context, preparsed, result, stack, (objectMacro as Macro)))
                                {
                                    continue;
                                }

                                preparsed.Position = tmp;
                            }
                            preparsed.CopyRange(result, (int)token.Length);
                        }
                        else if (!String(context, preparsed, result) && !Comment(context, macro.ReplacementList))
                        {
                            result.Add(preparsed.Get());
                        }
                    }

                    AnyPreventLineBreak(context, data, result, stack);

                    stack.Value.Add(macro.Id);

                    AnyPreventLineBreak(context, result, nodes, stack);

                    stack.Value.Remove(macro.Id);
                    return(true);
                }

                data.Position = streamPos;
            }
            return(false);
        }
Example #4
0
 private static bool ExpandMacro(CodeProcessorContext context, Stream data, TokenStream nodes, Lazy <HashSet <UInt32> > stack, Macro macro)
 {
     if (macro.Parameter.Count > 0 || macro.Variadic)
     {
         return(ExpandFunctionMacro(context, data, nodes, stack, macro));
     }
     else
     {
         return(ExpandObjectMacro(context, data, nodes, stack, macro));
     }
 }