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