ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
Calculus Struct Reference

Description:


1. Introduction

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:

  1. Derive a custom type from this class.
  2. Create constant value objects and C++ native callback functions.
  3. Create constant (constexpr) tables with all compilation information.
  4. In the constructor of the derived class, feed the tables into to this struct, using the corresponding helper methods.
Note
Sample code and detailed explanations are given with user manual section 5.4 Class Calculus and tutorial section 6. Extending The File Filter Sample
Note
The name "Calculus" seems a little overstated, we admit.

2. Choose Anonymous Namespaces

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.

3. Implementing Identifiers and Functions

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:

  • It can be specified if function names are case sensitive and whether they might be abbreviated.
  • The list of arguments (their types) accepted by a function is to be provided as a 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.
  • Variadic functions are supported by adding a final nulled Box to the argument list. All sample argument types before this box are mandatory, but an arbitrary amount of arguments of likewise arbitrary type may be followed. It is also allowed to add just that one nulled Box to the signature vector, which leads to functions that accept just any number of any type of argument, including zero arguments.
  • With debug builds, besides the callback function pointer, the C++ name of the callback function is to be provided. For this, macro CALCULUS_CALLBACK is defined. The macro creates a stringified version of the given function pointer, separated by a comma.
  • Flag FunctionEntry::IsCTInvokable is a boolean value that denotes whether a function can be evaluated at compile-time in the case that all of the parameters given in the expression are constant. If so, this struct will do the invocation at compile-time and return the constant result value instead of the function call.
    Most built-in functions are compile-time invokable. For example most mathematical functions like 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 from custom scope data. In contrast to this, custom functions, especially even parameterless identifiers usually are dependent on scope information and thus often can not be evaluated at compile-time.

4. Implementing Operators

4.1 Unary And Binary Operators

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:

  • AddOperator
    This function adds compilation information for a single operator to field Operators.
  • OperatorTableEntry
    This is a type definition that allows to define tables with compilation information on operators. It is recommended to create such tables as constexpr data in an anonymous namespace of the compilation unit.
  • AddOperators
    This is a pair of overloaded functions. One of them is templated and just used to deduce the length of the given table of static data. This table is then fed as a pointer, together with the table's size to the second method, which in turn feeds the table entries into field Operators.

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:

  • OperatorAliases
    A hash map that collects information about unary and binary operator aliases.
  • AddOperatorAlias
    This function adds information about an operator alias to field OperatorAliases.
  • OperatorAliasTableEntry A type definition that allows to define tables with information about operator aliases. It is recommended to create such tables as constexpr data in an anonymous namespace of the compilation unit.
  • AddOperatorAliases
    This is a pair of overloaded functions. One of them is templated and just used to deduce the length of the given table of static data. This table is then fed as a pointer, together with the table size to the second method, which in turn feeds the table entries into field OperatorAliases.

4.2 Specifics For Binary Operators

Aliasing '==' With '=':

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 .

Aliasing Bitwise Boolean Operators:

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.

Support For Compile-Time Optimization:

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:

  • BinaryOperatorOptimizations
    A hash-map that collects information about possible optimizations of binary operators when either of the operands are a specific constant value.
  • BinaryOpOptimizationsTableEntry
    A type definition that allows to feed tables (arrays of this type) with information about binary operator optimizations. It is recommended to create such tables as constexpr data in an anonymous namespace of the compilation unit.
  • AddBinaryOpOptimizations
    A pair of overloaded functions. One of them is templated and just used to deduce the length of the given table of static data. This table is then fed as a pointer, together with the table size to the second method, which in turn feeds the table entries into hash map BinaryOperatorOptimizations.

Reference Documentation

Definition at line 233 of file calculus.hpp.

#include <calculus.hpp>

Inheritance diagram for Calculus:
[legend]
Collaboration diagram for Calculus:
[legend]

Inner Type Index:

struct  AutoCastEntry
 
struct  BinOpOptKey
 
struct  ConstantIdentifierEntry
 
struct  FunctionEntry
 
struct  OperatorKey
 

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 Static Field Index:

static constexpr CTInvokable CTI = true
 
static constexpr CTInvokable ETI = false
 

Public Field Index:

MonoAllocator allocator
 
std::vector< AutoCastEntryAutoCasts
 
HashMap< BinOpOptKey, Box, BinOpOptKey::Hash, BinOpOptKey::EqualToBinaryOperatorOptimizations
 
std::vector< ConstantIdentifierEntryConstantIdentifiers
 
std::vector< FunctionEntryFunctions
 
HashMap< OperatorKey, String, OperatorKey::Hash, OperatorKey::EqualToOperatorAliases
 
HashMap< OperatorKey, std::tuple< CallbackDecl, Box, CTInvokable ALIB_DBG(, const char *) >, OperatorKey::Hash, OperatorKey::EqualToOperators
 
- Public Field Index: inherited from CompilerPlugin
CompilerCmplr
 
const NString Name
 

Public Method Index:

 Calculus (const NString &name, Compiler &compiler)
 
virtual ~Calculus () override
 
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)
 
virtual ~CompilerPlugin ()
 

Type Definition Details:

◆ BinaryOpOptimizationsTableEntry

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:

  • The operator to optimize.
  • Denotes if an optimization applies if the left-hand side or right-hand side argument is constant.
  • The type and value of the constant argument.
  • The type of the non-constant argument.
  • Either, a constant result value that replaces the binary operator (as in x || true) or a nulled box, which indicates that the result equals the non-constant argument (as in x && true).

Definition at line 705 of file calculus.hpp.

◆ CTInvokable

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 can not be set custom callbacks, as those usually rely on custom scope objects which are available only at evaluation-time.

Note
This type is used with helper class plugins::Calculus but exposed as a namespace type for convenience, together with constants CTI and ETI

Definition at line 251 of file calculus.hpp.

◆ OperatorAliasTableEntry

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:

  • The alias operator.
  • The type of first argument of the operator.
  • The type of the right-hand side argument of the operator. For unary operators, value Types::Void is to be provided.
  • The operator that gets aliased.

Definition at line 521 of file calculus.hpp.

◆ OperatorTableEntry

Initial value:
const std::tuple< String, Type, Type,
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
const alib::boxing::Box & Type
strings::TString< character > String
Type alias in namespace alib.

Entry of input tables (arrays) used with methods AddOperators to perform bulk-loading of compile definition data into map Operators.
The tuple elements are:

  • The operator to compile.
  • The type of the first argument of the operator.
  • The type of the right-hand side argument of the operator. For unary operators, value Types::Void is to be provided.
  • The callback function. Set to nullptr if operator evaluates constant.
  • The C++ name of the callback function. (This tuple element is only available in debug compilations of the library.)
  • The result type sample box, respectively, if callback is nullptr, the constant result value.
  • Flag to denote if the callback function allows compile-time invocation and thus on constant input the program can be optimized. This is true e.g. for arithmetic functions, but usually not for custom operators that rely on scope objects available only at evaluation time.

Definition at line 506 of file calculus.hpp.

Field Details:

◆ allocator

MonoAllocator allocator

This class uses monotonic allocation, which is well supported by the common way how this type is used.

Definition at line 271 of file calculus.hpp.

◆ AutoCasts

std::vector<AutoCastEntry> AutoCasts

List of auto-casts to be compiled by this plug-in.

Definition at line 865 of file calculus.hpp.

◆ 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 690 of file calculus.hpp.

◆ ConstantIdentifiers

std::vector<ConstantIdentifierEntry> ConstantIdentifiers

List of identifiers that return constant values to be compiled by this plug-in.

Definition at line 315 of file calculus.hpp.

◆ CTI

constexpr CTInvokable CTI = true
staticconstexpr

Used for values of CTInvokable flags.
The use of this constant makes code more readable.

Definition at line 258 of file calculus.hpp.

◆ ETI

constexpr CTInvokable ETI = false
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 265 of file calculus.hpp.

◆ Functions

std::vector<FunctionEntry> Functions

List of functions to be compiled by this plug-in.

Definition at line 386 of file calculus.hpp.

◆ OperatorAliases

Hash map assigning combinations of alias versions of operators and their argument types to the original operator.

Note
This map, similar to map Operators is best to be filled using corresponding add-methods AddOperatorAlias and AddOperatorAliases.
Usually this is done once in the constructor of derived classes.

Definition at line 486 of file calculus.hpp.

◆ 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.

Note
This map, similar to map OperatorAliases is best to be filled using corresponding add-methods AddOperator and AddOperators.
Usually this is done once in the constructor of derived classes.

Definition at line 472 of file calculus.hpp.

Constructor(s) / Destructor Details::

◆ Calculus()

Calculus ( const NString & name,
Compiler & compiler )
inline

Constructor.

Parameters
nameAssigned to field CompilerPlugin::Name .
compilerThe compiler we will get attached to

Definition at line 278 of file calculus.hpp.

◆ ~Calculus()

virtual ~Calculus ( )
inlineoverridevirtual

Virtual destructor.

Definition at line 293 of file calculus.hpp.

Method Details:

◆ AddBinaryOpOptimizations() [1/2]

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.

Parameters
tableThe table containing operator compilation information.
lengthThe table containing operator compilation information.

Definition at line 208 of file calculus.cpp.

Here is the call graph for this function:

◆ AddBinaryOpOptimizations() [2/2]

template<size_t TCapacity>
void AddBinaryOpOptimizations ( BinaryOpOptimizationsTableEntry(&) table[TCapacity])
inline

Templated helper method. Deduces the array size of the given table and passes it to AddBinaryOpOptimizations(BinaryOpOptimizationsTableEntry*, size_t).

Template Parameters
TCapacityImplicitly deferred size of the array provided.
Parameters
tableThe table containing operator compilation information.

Definition at line 716 of file calculus.hpp.

Here is the call graph for this function:

◆ AddOperator()

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.

See also
If multiple operators are to be defined, consider the use of AddOperators, which is a variant of this method that allows effective bulk loading.
Parameters
opThe operator.
lhsTypeThe type of the first argument that the operator is defined for.
rhsTypeThe type of the right-hand side argument that the operator is defined for. For unary operators, value Types::Void is to be provided.
callbackThe callback function to execute.
dbgCallbackNameThe name of the C++ name of the callback function.
Note
This parameter is available only in debug version of the library.
Parameters
ctiSee CTInvokable for the meaning of this flag.
resultTypeThe result type of the callback function.

Definition at line 26 of file calculus.cpp.

Here is the call graph for this function:

◆ AddOperatorAlias()

ALIB_WARNINGS_RESTORE void AddOperatorAlias ( const String & alias,
Type lhsType,
Type rhsType,
const String & op )

Adds an alias operator to hash table OperatorAliases.

See also
If multiple alias operators are to be defined, consider the use of AddOperatorAliases, which is a variant of this method that allows effective bulk loading.
Parameters
aliasThe alias for operator op .
lhsTypeThe left-hand side argument type that the operator is defined for.
rhsTypeThe right-hand side argument type that the operator is defined for.
opThe operator aliased by alias .

Definition at line 102 of file calculus.cpp.

Here is the call graph for this function:

◆ AddOperatorAliases() [1/2]

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.

Parameters
tableThe table containing operator compilation information.
lengthThe table containing operator compilation information.

Definition at line 121 of file calculus.cpp.

Here is the call graph for this function:

◆ AddOperatorAliases() [2/2]

template<size_t TCapacity>
void AddOperatorAliases ( OperatorAliasTableEntry(&) table[TCapacity])
inline

Templated helper method. Deduces the array size of the given table and passes it to AddOperatorAliases(OperatorAliasTableEntry* table, size_t length).

Template Parameters
TCapacityImplicitly deferred size of the array provided.
Parameters
tableThe table containing operator compilation information.

Definition at line 612 of file calculus.hpp.

Here is the call graph for this function:

◆ AddOperators() [1/2]

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.

Parameters
tableThe table containing operator compilation information.
lengthThe table containing operator compilation information.

Definition at line 55 of file calculus.cpp.

Here is the call graph for this function:

◆ AddOperators() [2/2]

template<size_t TCapacity>
void AddOperators ( OperatorTableEntry(&) table[TCapacity])
inline

Templated helper method. Deduces the array size of the given table and passes it to AddOperators(OperatorTableEntry* table, size_t length).

Template Parameters
TCapacityImplicitly deferred size of the array provided.
Parameters
tableThe table containing operator compilation information.

Definition at line 571 of file calculus.hpp.

Here is the call graph for this function:

◆ TryCompilation() [1/4]

bool TryCompilation ( CIAutoCast & autoCast)
overridevirtual

Searches in AutoCasts for an entry matching the combination of CIAutoCast::Operator and the type(s) that might be auto-casted.

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.

Note
This method of this helper class is not applicable if one of the following conditions apply to a use case:
  • Different auto-casts are to be applied for the first and second arguments of binary operators.
  • The custom auto-cast method is not compile-time invokable.
In this case, a custom implementation of this method has to be provided to fetch these cases. The custom method might then invoke this base implementation.
Parameters
autoCastThe compilation info struct.
Returns
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 538 of file calculus.cpp.

◆ TryCompilation() [2/4]

ALIB_WARNINGS_RESTORE bool TryCompilation ( CIBinaryOp & ciBinaryOp)
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 .

Parameters
ciBinaryOpThe compilation info struct.
Returns
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 247 of file calculus.cpp.

Here is the call graph for this function:

◆ TryCompilation() [3/4]

bool TryCompilation ( CIFunction & ciFunction)
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 .

Parameters
[in,out]ciFunctionThe compilation result.
Returns
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 351 of file calculus.cpp.

Here is the call graph for this function:

◆ TryCompilation() [4/4]

ALIB_WARNINGS_RESTORE bool TryCompilation ( CIUnaryOp & ciUnaryOp)
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 .

Parameters
ciUnaryOpThe compilation result.
Returns
true if an entry was found in Operators and a corresponding command was added to ciUnaryOp . false otherwise.

Reimplemented from CompilerPlugin.

Definition at line 157 of file calculus.cpp.

Here is the call graph for this function:

The documentation for this struct was generated from the following files: