CeresEngine 0.2.0
A game development framework
Loading...
Searching...
No Matches
PreProcessor.hpp
Go to the documentation of this file.
1//
2// CeresEngine - A game development framework
3//
4// Created by Rogiel Sulzbach.
5// Copyright (c) 2018-2022 Rogiel Sulzbach. All rights reserved.
6//
7
8#pragma once
9
10#include "Parser.hpp"
12
14
20
24
27
28#include <functional>
29#include <iostream>
30
32
38 class PreProcessor : public Parser {
39 protected:
40 // Macro object structure.
41 struct Macro {
42 Macro() = default;
43 Macro(const Macro&) = default;
44 Macro& operator=(const Macro&) = default;
45
48
49 Macro(const TokenPtr& identifierToken, const TokenPtrString& value, const Vector<String>& parameters, bool varArgs = false, bool stdMacro = false,
50 bool emptyParamList = false);
51
52 [[nodiscard]] bool hasParameterList() const;
53
54 TokenPtr identifierToken; // Macro identifier token
55 TokenPtrString tokenString; // Macro definition value as token string
56 Vector<String> parameters; // Parameter identifiers
57 bool varArgs = false; // Specifies whether the macro supports variadic arguments
58 bool stdMacro = false; // Specifies whether the macro is a standard macro (i.e. part of the language) or not
59 bool emptyParamList = false; // Macro has an empty parameter list
60 };
61
62 struct IfBlock {
63 void setActive(bool activate);
64
67 bool parentActive = true; // Is the parent if-block active?
68 bool active = true; // Is this if-block active?
69 bool wasActive = false; // Was this if-block active?
70 bool elseAllowed = true; // Is an else-block allowed?
71 };
72
74
75 private:
77
79
82 Map<String, std::size_t> mIncludeCounter; // Counter for each included file
83
87
88 bool mWriteLineMarks = true;
90
91 public:
92 PreProcessor(IncludeHandler& includeHandler, Log* log = nullptr);
93
94 UPtr<std::iostream> process(const SourceCodePtr& input, const String& filename = "", bool writeLineMarks = true, bool writeLineMarkFilenames = true,
95 bool enableWarnings = false);
96
97 // Returns a list of all defined macro identifiers after pre-processing.
99
100 protected:
101 // Parses the specified directive, that is not part of the standard pre-processor directive (e.g. "version" or "extension" for GLSL).
102 virtual void parseDirective(const String& directive, bool ignoreUnknown);
103
104 // Callback function when an auto-generated '#line'-directive is to be written.
105 virtual void writeLineDirective(UInt32 lineNo, const String& filename);
106
107 // Ignores the remaining tokens of the current directive.
109
110 // Defines a macro with the specified identifier, value token string, and parameters.
111 void defineMacro(const Macro& macro);
112
113 // Defines a standard macro (i.e. not part of the source code) with value set to integer literal '1'.
114 void defineStandardMacro(const String& ident, Int32 intValue = 1);
115
116 // Removes the macro definition with the specified identifier.
117 void undefineMacro(const String& ident, const Token* token = nullptr);
118
119 // Returns true if the specified macro identifier is defined.
120 [[nodiscard]] bool isDefined(const String& ident) const;
121
122 // Callback function when a macro is about to be defined
123 virtual bool onDefineMacro(const Macro& macro);
124
125 // Callback function when a macro is about to be redefined, returns true if the redefinition is allowed.
126 virtual bool onRedefineMacro(const Macro& macro, const Macro& previousMacro);
127
128 // Callback function when a macro is about to be undefined, return true if the undefinition is allowed.
129 virtual bool onUndefineMacro(const Macro& macro);
130
131 // Callback function when the standard macro must be substituted (e.g. __FILE__ to string literal).
132 virtual bool onSubstituteStdMacro(const Token& identifierToken, TokenPtrString& tokenString);
133
134 // Evaluate the expression of the specified token string.
135 Variant evaluateExpression(const TokenPtrString& tokenString, const Token* token = nullptr);
136
137 // Parse a token string and evaluate it as expression.
139
140 // Parse a token string as argument and evaluate it as expression.
142
143 // Returns the output stream as reference.
144 inline StringStream& getOutputStream() { return *mOutput; }
145
146 private:
148
149 void pushScannerSource(const SourceCodePtr& source, const String& filename = "") override;
150 bool popScannerSource() override;
151
152 void pushIfBlock(const TokenPtr& directiveToken, bool active = false, bool elseAllowed = true);
153 void setIfBlock(const TokenPtr& directiveToken, bool active = false, bool elseAllowed = true);
155
156 // Returns the if-block state from the top of the stack. If the stack is empty, the default state is returned.
158
162
163 // Writes a '#line'-directive to the output with the current source position and filename.
165
166 private: // Parsing
168
173 void parseMisc();
174
191
194
197
200 };
201
202} // namespace CeresEngine::ShaderCompiler
Interface for handling new include streams.
Definition IncludeHandler.hpp:21
Log base class.
Definition Log.hpp:19
Definition Parser.hpp:34
Pre-processor to substitute macros and include directives.
Definition PreProcessor.hpp:38
Map< String, MacroPtr > mMacros
Definition PreProcessor.hpp:80
Map< String, std::size_t > mIncludeCounter
Definition PreProcessor.hpp:82
void pushIfBlock(const TokenPtr &directiveToken, bool active=false, bool elseAllowed=true)
void undefineMacro(const String &ident, const Token *token=nullptr)
Variant parseAndEvaluateArgumentExpression(const Token *token=nullptr)
Vector< String > listDefinedMacroIdents() const
UPtr< StringStream > mOutput
Definition PreProcessor.hpp:78
void setIfBlock(const TokenPtr &directiveToken, bool active=false, bool elseAllowed=true)
SPtr< Macro > MacroPtr
Definition PreProcessor.hpp:73
void parseDirectiveIfndef(bool skipEvaluation=false)
TokenPtrString expandMacro(const Macro &macro, const Vector< TokenPtrString > &arguments)
Replaces all identifiers (specified by 'macro.parameters') in the token string (specified by 'macro....
TokenPtrString parseDirectiveTokenString(bool expandDefinedDirective=false, bool ignoreComments=false)
bool isDefined(const String &ident) const
virtual void writeLineDirective(UInt32 lineNo, const String &filename)
IncludeHandler & mIncludeHandler
Definition PreProcessor.hpp:76
ExpressionPtr parsePrimaryExpression() override
virtual bool onRedefineMacro(const Macro &macro, const Macro &previousMacro)
virtual void parseDirective(const String &directive, bool ignoreUnknown)
void pushScannerSource(const SourceCodePtr &source, const String &filename="") override
void defineMacro(const Macro &macro)
virtual bool onDefineMacro(const Macro &macro)
void parseDirectiveIf(bool skipEvaluation=false)
virtual bool onSubstituteStdMacro(const Token &identifierToken, TokenPtrString &tokenString)
UPtr< std::iostream > process(const SourceCodePtr &input, const String &filename="", bool writeLineMarks=true, bool writeLineMarkFilenames=true, bool enableWarnings=false)
bool mWriteLineMarks
Definition PreProcessor.hpp:88
StringStream & getOutputStream()
Definition PreProcessor.hpp:144
void parseDirectiveIfOrElifCondition(bool isElseBranch, bool skipEvaluation=false)
Stack< IfBlock > mIfBlockStack
Stack to store the info which if-block in the hierarchy is active.
Definition PreProcessor.hpp:86
PreProcessor(IncludeHandler &includeHandler, Log *log=nullptr)
Variant evaluateExpression(const TokenPtrString &tokenString, const Token *token=nullptr)
void parseDirectiveIfdef(bool skipEvaluation=false)
virtual bool onUndefineMacro(const Macro &macro)
bool mWriteLineMarkFilenames
Definition PreProcessor.hpp:89
Variant parseAndEvaluateExpression(const Token *token=nullptr)
Set< String > mOnceIncluded
Definition PreProcessor.hpp:81
TokenPtrString parseIdentArgumentsForMacro(const TokenPtr &identifierToken, const Macro &macro)
void parseDirectiveElif(bool skipEvaluation=false)
void defineStandardMacro(const String &ident, Int32 intValue=1)
Definition Token.hpp:21
Definition Variant.hpp:20
Definition AST.hpp:33
SPtr< Expression > ExpressionPtr
Definition Visitor.hpp:26
SPtr< SourceCode > SourceCodePtr
Definition SourceCode.hpp:66
SPtr< Token > TokenPtr
Definition Token.hpp:174
SPtr< Scanner > ScannerPtr
Definition Scanner.hpp:147
std::stack< T, Container > Stack
The Stack class is a container adapter that gives the programmer the functionality of a stack - speci...
Definition Stack.hpp:18
std::unique_ptr< T, Deleter > UPtr
UPtr is a smart pointer that owns and manages another object through a pointer and disposes of that o...
Definition SmartPtr.hpp:28
std::shared_ptr< T > SPtr
SPtr is a smart pointer that retains shared ownership of an object through a pointer.
Definition SmartPtr.hpp:37
BasicStringStream< char > StringStream
Wide string stream used for primarily for constructing narrow strings.
Definition StringStream.hpp:32
std::vector< T, ScopedAllocatorAdaptor< StdAllocator< T, RawAllocator > > > Vector
Vector is a sequence container that encapsulates dynamic size arrays.
Definition Vector.hpp:17
std::int32_t Int32
Definition DataTypes.hpp:21
std::uint32_t UInt32
Definition DataTypes.hpp:23
constexpr size_t hash(const T &v)
Generates a hash for the provided type.
Definition Hash.hpp:25
std::set< Key, Compare, ScopedAllocatorAdaptor< StdAllocator< Key, RawAllocator > > > Set
Set is an associative container that contains a sorted set of unique objects of type Key.
Definition Set.hpp:21
std::map< Key, T, Compare, ScopedAllocatorAdaptor< StdAllocator< Pair< const Key, T >, RawAllocator > > > Map
Map is a sorted associative container that contains key-value pairs with unique keys.
Definition Map.hpp:24
bool parentActive
Definition PreProcessor.hpp:67
bool wasActive
Definition PreProcessor.hpp:69
bool elseAllowed
Definition PreProcessor.hpp:70
bool active
Definition PreProcessor.hpp:68
TokenPtr directiveToken
Definition PreProcessor.hpp:65
SourceCodePtr directiveSource
Definition PreProcessor.hpp:66
bool emptyParamList
Definition PreProcessor.hpp:59
TokenPtr identifierToken
Definition PreProcessor.hpp:54
Macro(const TokenPtr &identifierToken, const TokenPtrString &value, const Vector< String > &parameters, bool varArgs=false, bool stdMacro=false, bool emptyParamList=false)
bool stdMacro
Definition PreProcessor.hpp:58
Macro(const TokenPtr &identifierToken)
TokenPtrString tokenString
Definition PreProcessor.hpp:55
Macro(const TokenPtr &identifierToken, const TokenPtrString &value)
Vector< String > parameters
Definition PreProcessor.hpp:56
Macro & operator=(const Macro &)=default
bool varArgs
Definition PreProcessor.hpp:57