This struct specializes CompilerPlugin and provides generic approaches and implementation of variants of method TryCompilation. Consequently, this is the base type of most built-in compiler plug-ins, and is strongly recommended to consider this struct as the preferred base when implementing custom plug-ins.
The class implements virtual, overloaded methods
For each AST node type to compile, this class holds a vector or a hash map to store all information needed for compilation.
The simple schema of using this class is:
constexpr
) tables with all compilation information.A good design pattern is to put the callback functions, constant values and compilation information tables into an anonymous namespace at the start of the compilation unit (.cc or .cpp file) of your custom plug-in. This way, the linker is not bothered with the function and object names, which solely are referenced by their address and never need to get linked to other units.
Just after this anonymous namespace, the implementation of the constructor of the custom plug-in, should be placed. As explained above, its duty is to fills in the vector/hash map using the right combination of operator or function argument types, as well as providing a proper sample box that corresponds to the type of the output parameter of the native function.
When implementing a custom plug-in, it may be helpful to have a look at the source code of the built-in plug-ins provided with module ALib Expressions. You will see that these implementations are quite straight forward and use some 'handy' local preprocessor macros that may be copied and used for custom implementations.
While parent class CompilerPlugin does not make any direct distinction between functions that are always returning a constant value and those that don't, this class does. Arguably such functions are always parameterless, hence identifiers. Samples for such constants are "PI" or "True".
Such constant identifiers are supported by populating table ConstantIdentifiers which is a std::vector
of elements of type ConstantIdentifiersEntry. For details on each "table column", refer to the documentation of the fields of ConstantIdentifierEntry.
Non-constant identifiers and functions are supported by populating table Functions, which is a std::vector
of elements of type FunctionEntry. For details on each "table column", refer to the documentation of the fields of FunctionEntry.
Some notes:
std::vector
of sample boxes. It is recommended to define such vectors once per unique function "signature" in the anonymous namespace section of the compilation unit and fill its contents once in the constructor of the custom plug-in. Such vectors can then be reused for each function that shares the same signature.log(Float)
or sin(Float)
can be evaluated at compile-time (again, only in the case that the given parameters are constant). The reason is that these functions are independent of custom scope data. In contrast to this, custom functions, especially even parameterless identifiers usually are dependent on scope information and thus often cannot be evaluated at compile-time.Apart from some specialities for binary operators documented in the next section, this class treats unary and binary the same. Wherever a second operator argument's type is requested, in case of unary operators static type specifier Types::Void is to be given.
The compilation of unary and binary operators is supported by populating hash map Operators. For feeding the map with entries, the following convenience types and methods are provided:
constexpr
data in an anonymous namespace of the compilation unit.In other words: Method AddOperator defines a single operator, while AddOperators defines "bulk" data on operators which is defined in a static table. For details of the functions and types, consult the corresponding documentation.
As documented in user manual section 9.4 Type-Specific Operator Aliases, module ALib Expressions supports the use of alias operators. This is reflected by this class with:
constexpr
data in an anonymous namespace of the compilation unit.With the use of this class it is not necessary to define alias '='
for binary operator '=='
, because this alias replacement is internally always made for any combination of argument types, when compilation flag Compilation::AliasEqualsOperatorWithAssignOperator is set in field Compiler::CfgCompilation.
In contrast to the above, compilation flag Compilation::AllowBitwiseBooleanOperators affects only built-in type boolean - just as the flag's name suggests. The flag is therefore tested only in derived plug-in plugins::Arithmetics. In other words: to allow for example operator '&'
to be used as an alias for operator '&&'
defined on custom types, this has to be explicitly added as a set alias definitions for each combination of types in question.
For binary operators, this class provides a mechanism to provide information on possible compile-time optimizations. Samples of possible binary operator optimizations are given in documentation of struct CompilerPlugin::CIBinaryOp.
The following fields and methods are provided:
constexpr
data in an anonymous namespace of the compilation unit.Definition at line 228 of file calculus.hpp.
#include <calculus.hpp>
Inner Type Index: | |
struct | AutoCastEntry |
An entry of the field AutoCasts. Defines auto-casts for custom types. More... | |
struct | BinOpOptKey |
Key type for operator hash maps Operators and OperatorAliases. More... | |
struct | ConstantIdentifierEntry |
struct | FunctionEntry |
struct | OperatorKey |
Key type for operator hash maps Operators and OperatorAliases. More... | |
Public Type Index: | |
using | BinaryOpOptimizationsTableEntry = const std::tuple<String, lang::Side, Type, const Box&, const Box&> |
using | CTInvokable = bool |
using | OperatorAliasTableEntry = const std::tuple<String, Type, Type, String> |
using | OperatorTableEntry |
Public Type Index: inherited from Plugin< Compiler, CompilePriorities > | |
using | PluginType |
This exposes the template parameter TPlugin to the outer world. | |
using | PrioritiesType |
This exposes the template parameter pTPlugin to the outer world. | |
Public Static Field Index: | |
static constexpr CTInvokable | CTI = true |
static constexpr CTInvokable | ETI = false |
Public Field Index: | |
MonoAllocator | allocator |
std::vector< AutoCastEntry > | AutoCasts |
List of auto-casts to be compiled by this plug-in. | |
HashMap< MonoAllocator, BinOpOptKey, Box, BinOpOptKey::Hash, BinOpOptKey::EqualTo > | BinaryOperatorOptimizations |
std::vector< ConstantIdentifierEntry > | ConstantIdentifiers |
List of identifiers that return constant values to be compiled by this plug-in. | |
std::vector< FunctionEntry > | Functions |
List of functions to be compiled by this plug-in. | |
HashMap< MonoAllocator, OperatorKey, String, OperatorKey::Hash, OperatorKey::EqualTo > | OperatorAliases |
HashMap< MonoAllocator, OperatorKey, std::tuple< CallbackDecl, Box, CTInvokable ALIB_DBG(, const char *) >, OperatorKey::Hash, OperatorKey::EqualTo > | Operators |
Public Field Index: inherited from CompilerPlugin | |
Compiler & | Cmplr |
The compiler that this plug-in is attached to. | |
const NString | Name |
Public Method Index: | |
Calculus (const NString &name, Compiler &compiler, CompilePriorities pPriority) | |
virtual | ~Calculus () override |
Virtual destructor. | |
ALIB_API void | AddBinaryOpOptimizations (BinaryOpOptimizationsTableEntry *table, size_t length) |
template<size_t TCapacity> | |
void | AddBinaryOpOptimizations (BinaryOpOptimizationsTableEntry(&table)[TCapacity]) |
void | AddOperator (const String &op, Type lhsType, Type rhsType, CallbackDecl callback, const char *dbgCallbackName, Type resultType, CTInvokable cti) |
void | AddOperatorAlias (const String &alias, Type lhsType, Type rhsType, const String &op) |
void | AddOperatorAliases (OperatorAliasTableEntry *table, size_t length) |
template<size_t TCapacity> | |
void | AddOperatorAliases (OperatorAliasTableEntry(&table)[TCapacity]) |
ALIB_API void | AddOperators (OperatorTableEntry *table, size_t length) |
template<size_t TCapacity> | |
void | AddOperators (OperatorTableEntry(&table)[TCapacity]) |
virtual ALIB_API bool | TryCompilation (CIAutoCast &autoCast) override |
virtual ALIB_API bool | TryCompilation (CIBinaryOp &ciBinaryOp) override |
virtual ALIB_API bool | TryCompilation (CIFunction &ciFunction) override |
virtual ALIB_API bool | TryCompilation (CIUnaryOp &ciUnaryOp) override |
Public Method Index: inherited from CompilerPlugin | |
CompilerPlugin (const NString &name, Compiler &compiler, CompilePriorities pPriority) | |
virtual | ~CompilerPlugin () |
Virtual destructor. | |
Public Method Index: inherited from Plugin< Compiler, CompilePriorities > | |
PrioritiesType | GetPriority () const |
Additional Inherited Members | |
Protected Field Index: inherited from Plugin< Compiler, CompilePriorities > | |
PrioritiesType | priority |
The priority of this plug-in. | |
Protected Method Index: inherited from Plugin< Compiler, CompilePriorities > | |
Plugin (PrioritiesType pPriority) | |
using BinaryOpOptimizationsTableEntry = const std::tuple<String, lang::Side, Type, const Box&, const Box&> |
Entry of arrays used with methods AddBinaryOpOptimizations to perform bulk-loading of optimization data to hash map BinaryOperatorOptimizations.
The tuple element's meanings are:
x || true
) or a nulled box, which indicates that the result equals the non-constant argument (as in x && true
). Definition at line 667 of file calculus.hpp.
using CTInvokable = bool |
Boolean to denote if a callback function allows compile-time invocation. If true
, on constant function input (either from expression string literals or sub-expressions that have been optimized to constant input) the program can be optimized by invoking the CallbackDecl already at compile-time.
This flag is set for most built-in functions, e.g., arithmetic calculations, but usually cannot be set custom callbacks, as those usually rely on custom scope objects which are available only at evaluation-time.
Definition at line 244 of file calculus.hpp.
using OperatorAliasTableEntry = const std::tuple<String, Type, Type, String> |
Entry of input tables (arrays) used with method AddOperatorAliases to perform bulk-loading of operator alias definition data into map OperatorAliases.
The tuple elements are:
Definition at line 486 of file calculus.hpp.
using OperatorTableEntry |
Entry of input tables (arrays) used with methods AddOperators to perform bulk-loading of compile definition data into map Operators.
The tuple elements are:
nullptr
if operator evaluates constant.nullptr
, the constant result value.Definition at line 473 of file calculus.hpp.
MonoAllocator allocator |
This class uses monotonic allocation, which is well supported by the common way how this type is used.
Definition at line 258 of file calculus.hpp.
std::vector<AutoCastEntry> AutoCasts |
List of auto-casts to be compiled by this plug-in.
Definition at line 813 of file calculus.hpp.
HashMap<MonoAllocator, BinOpOptKey, Box, BinOpOptKey::Hash, BinOpOptKey::EqualTo> BinaryOperatorOptimizations |
Hash map storing optimization information for binary operators where either argument is constant.
This map may be filled with AddBinaryOpOptimizations, which is usually done in the. constructor of derived classes.
The stored element of type Box may contain either, a constant result value that replaces the binary operator (as in x || true
) or be a nulled box, which indicates that the result equals the non-constant argument (as in x && true
).
Definition at line 654 of file calculus.hpp.
std::vector<ConstantIdentifierEntry> ConstantIdentifiers |
List of identifiers that return constant values to be compiled by this plug-in.
Definition at line 297 of file calculus.hpp.
|
staticconstexpr |
Used for values of CTInvokable flags.
The use of this constant makes code more readable.
Definition at line 249 of file calculus.hpp.
|
staticconstexpr |
Used for values of CTInvokable flags to denote that a callback function is only invokable at evaluation-time.
The use of this constant makes code more readable.
Definition at line 254 of file calculus.hpp.
std::vector<FunctionEntry> Functions |
List of functions to be compiled by this plug-in.
Definition at line 357 of file calculus.hpp.
HashMap<MonoAllocator, OperatorKey, String, OperatorKey::Hash, OperatorKey::EqualTo> OperatorAliases |
Hash map assigning combinations of alias versions of operators and their argument types to the original operator.
Definition at line 455 of file calculus.hpp.
HashMap<MonoAllocator, OperatorKey, std::tuple<CallbackDecl, Box, CTInvokable ALIB_DBG( , const char* ) >, OperatorKey::Hash, OperatorKey::EqualTo> Operators |
Hash map assigning combinations of (unary and binary) operators and its argument types to a tuple providing information about a callback function.
The tuple stored, contains the function pointer and the functions' return type. A third member of type CTInvokable indicates whether the callback function is allowed to be invoked on the Scope object used at compile-time. This scope object is of the same (eventually custom) type as the one for evaluation, however the evaluation-specific data is not set. In other words, the third tuple member denotes if during program compilation the function might be invoked when the operator's argument(s) are constant.
A fourth tuple member of type String is available only with debug-builds and receives the name of the callback function.
Definition at line 442 of file calculus.hpp.
|
inline |
Constructor.
name | Assigned to the field CompilerPlugin::Name. |
compiler | The compiler we will get attached to |
pPriority | The priority of this plugin. |
Definition at line 266 of file calculus.hpp.
|
inlineoverridevirtual |
Virtual destructor.
Definition at line 277 of file calculus.hpp.
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE void AddBinaryOpOptimizations | ( | BinaryOpOptimizationsTableEntry * | table, |
size_t | length ) |
Loads all entries of the given table into hash map BinaryOperatorOptimizations.
Note, that usually, the given table is a constexpr array located in an anonymous namespace of a compilation unit.
It can be passed as a reference to templated helper method, which defers the length of the table implicitly.
table | The table containing operator compilation information. |
length | The table containing operator compilation information. |
Definition at line 203 of file calculus.cpp.
|
inline |
Templated helper method. Deduces the array size of the given table and passes it to AddBinaryOpOptimizations(BinaryOpOptimizationsTableEntry*, size_t).
TCapacity | Implicitly deferred size of the array provided. |
table | The table containing operator compilation information. |
Definition at line 678 of file calculus.hpp.
void AddOperator | ( | const String & | op, |
Type | lhsType, | ||
Type | rhsType, | ||
CallbackDecl | callback, | ||
const char * | dbgCallbackName, | ||
Type | resultType, | ||
CTInvokable | cti ) |
Adds an entry to the operator definition map Operators.
op | The operator. |
lhsType | The type of the first argument that the operator is defined for. |
rhsType | The type of the right-hand side argument that the operator is defined for. For unary operators, value Types::Void is to be provided. |
callback | The callback function to execute. |
dbgCallbackName | The name of the C++ name of the callback function. |
cti | See CTInvokable for the meaning of this flag. |
resultType | The result type of the callback function. |
Definition at line 21 of file calculus.cpp.
ALIB_WARNINGS_RESTORE void AddOperatorAlias | ( | const String & | alias, |
Type | lhsType, | ||
Type | rhsType, | ||
const String & | op ) |
Adds an alias operator to hash table OperatorAliases.
alias | The alias for operator op. |
lhsType | The left-hand side argument type that the operator is defined for. |
rhsType | The right-hand side argument type that the operator is defined for. |
op | The operator aliased by alias. |
Definition at line 97 of file calculus.cpp.
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE void AddOperatorAliases | ( | OperatorAliasTableEntry * | table, |
size_t | length ) |
Loads all entries of the given table into hash map OperatorAliases.
Note, that usually, the given table is a constexpr array located in an anonymous namespace of a compilation unit.
It can be passed as a reference to templated helper method, which defers the length of the table implicitly.
table | The table containing operator compilation information. |
length | The table containing operator compilation information. |
Definition at line 116 of file calculus.cpp.
|
inline |
Templated helper method. Deduces the array size of the given table and passes it to AddOperatorAliases(OperatorAliasTableEntry* table, size_t length).
TCapacity | Implicitly deferred size of the array provided. |
table | The table containing operator compilation information. |
Definition at line 577 of file calculus.hpp.
ALIB_WARNINGS_ALLOW_UNSAFE_BUFFER_USAGE void AddOperators | ( | OperatorTableEntry * | table, |
size_t | length ) |
Loads all entries of the given table into hash map Operators.
Note, that usually, the given table is a constexpr array located in an anonymous namespace of a compilation unit.
It can be passed as a reference to templated helper method, which defers the length of the table implicitly.
table | The table containing operator compilation information. |
length | The table containing operator compilation information. |
Definition at line 50 of file calculus.cpp.
|
inline |
Templated helper method. Deduces the array size of the given table and passes it to AddOperators(OperatorTableEntry* table, size_t length).
TCapacity | Implicitly deferred size of the array provided. |
table | The table containing operator compilation information. |
Definition at line 536 of file calculus.hpp.
|
overridevirtual |
Searches in AutoCasts for an entry matching the combination of CIAutoCast::Operator and the type(s) that might be auto-cast.
An entry in AutoCasts might also be defined to work on just all operators.
For the very frequent use case of auto-casting custom enum types to integral types, only fields AutoCastEntry::Type and AutoCastEntry::ReverseCastFunctionName have to be provided.
autoCast | The compilation info struct. |
true
if a matching entry was found in AutoCasts and a corresponding command was added to autoCast. false
otherwise. Reimplemented from CompilerPlugin.
Definition at line 531 of file calculus.cpp.
|
overridevirtual |
Searches in Operators for an entry matching the combination of CIBinaryOp::Operator and the argument types of operands found with argument iterators CompilationInfo::ArgsBegin and CompilationInfo::ArgsBegin. If found, the corresponding callback function and result type are added the CIBinaryOp.
Before the search, it is checked whether the given operator is an alias for another operator. Operator aliases might be defined by filling map OperatorAliases in the constructor of the derived types. If so, the corrected operator is returned with in/out parameter CIBinaryOp::Operator.
ciBinaryOp | The compilation info struct. |
true
if an entry was found in Operators and a corresponding command was added to ciBinaryOp. false
otherwise. Reimplemented from CompilerPlugin.
Reimplemented in Strings.
Definition at line 242 of file calculus.cpp.
|
overridevirtual |
Searches in vectors Functions and ConstantIdentifiers for an entry matching name and, if found, adds either a constant value or a callback function to ciFunction.
This plug-in corrects abbreviated and letter case differences in functions within in/out parameter CIFunction::Name.
[in,out] | ciFunction | The compilation result. |
true
if an entry was found in Functions and a corresponding command was added to ciFunction. false
otherwise. Reimplemented from CompilerPlugin.
Reimplemented in Arithmetics, and Strings.
Definition at line 346 of file calculus.cpp.
|
overridevirtual |
Searches in Operators for an entry matching the combination of CIUnaryOp::Operator and the argument type of operand found with iterator CompilationInfo::ArgsBegin. (The second argument type of the key of the hash map Operators is set to Types::Void). If found, the corresponding callback function and result type are added the CIUnaryOp.
Before the search, it is checked whether the given operator is an alias for another operator. Operator aliases might be defined by filling map OperatorAliases in the constructor of the derived types. If so, the corrected operator is returned with in/out parameter CIUnaryOp::Operator.
ciUnaryOp | The compilation result. |
true
if an entry was found in Operators and a corresponding command was added to ciUnaryOp. false
otherwise. Reimplemented from CompilerPlugin.
Definition at line 152 of file calculus.cpp.