ALib C++ Library
Library Version: 2402 R1
Documentation generated by doxygen
Loading...
Searching...
No Matches
expressions.hpp
Go to the documentation of this file.
1/** ************************************************************************************************
2 * \file
3 * This header file is part of module \alib_expressions of the \aliblong.
4 *
5 * \emoji :copyright: 2013-2024 A-Worx GmbH, Germany.
6 * Published under \ref mainpage_license "Boost Software License".
7 **************************************************************************************************/
8#ifndef HPP_ALIB_EXPRESSIONS_EXPRESSIONS
9#define HPP_ALIB_EXPRESSIONS_EXPRESSIONS 1
10
11#if !defined(HPP_ALIB_CAMP_MESSAGE_EXCEPTION)
13#endif
14
15ALIB_ASSERT_MODULE(EXPRESSIONS)
16
17#if !defined(HPP_ALIB_COMPATIBILITY_STD_BOXING_FUNCTIONAL)
19#endif
20
21#if !defined(HPP_ALIB_LANG_CAMP)
23#endif
24
25#if !defined(HPP_ALIB_ENUMS_ENUM_B)
26# include "alib/enums/bitwise.hpp"
27#endif
28
29namespace alib { namespace expressions {
30
31struct Scope;
32
33
34/** ************************************************************************************************
35 * Exceptions thrown by module \alib_expressions_nl.
36 *
37 * \note
38 * This enum type is associated with \ref alib_enums_records "ALib Enum Records" according to
39 * the specification documented with class \alib{lang;Exception}.
40 **************************************************************************************************/
41enum class Exceptions
42{
43 /** General error thrown by the parser. */
44 SyntaxError =1 ,
45
46 /** Detail entry (negative element value) used with various exceptions. Shows the expression
47 * in a first line and a marker of the syntax error position in a second. */
48 ExpressionInfo = -1,
49
50 /**
51 * This is added to exceptions when when a \c std::exception is wrapped.
52 * The 'what()' string is included as entry parameter.
53 * (This is a detail entry with negative element value).
54 */
56
57 /** Thrown when an empty string is tried to be compiled. */
59
60 /** Syntax error with concrete information about what the parser expected at given position. */
62
63 /** Unknown unary operator symbol found when parsing expression string. */
65
66 /** Unknown binary operator symbol found when parsing expression string. */
68
69 /** Compile-time exception thrown when an expression uses an unknown identifier name. */
71
72 /** Compile-time exception thrown when an expression uses an unknown function name. */
74
75 /** Optional info entry (negative element value) on a function with matching name but
76 * non-matching arguments found. */
77 FunctionHint =-15,
78
79 /** Compile-time exception thrown when an unary operator is not applicable to the given
80 * argument type. */
82
83 /** Compile-time exception thrown when a binary operator is not applicable to the combination of
84 * left-hand and right-and argument type. */
86
87 /**
88 * Compile-time exception thrown when function parentheses are missing with parameterless
89 * functions, while flag
90 * \alib{expressions::Compilation;AllowOmittingParenthesesOfParameterlessFunctions} is not set
91 * in \alib{expressions;Compiler::CfgCompilation}.
92 */
94
95 /**
96 * Compile-time exception thrown when empty function parentheses are given with identifiers
97 * (parameterless functions), while flag
98 * \alib{expressions::Compilation;AllowEmptyParenthesesForIdentifierFunctions} is not set
99 * in \alib{expressions;Compiler::CfgCompilation}.
100 */
102
103 /**
104 * Compile-time exception thrown when incompatible types are given with conditional
105 * term <c>Q ? T : F</c>. Note that before throwing this exception, the compiler tries to
106 * insert auto-cast callback functions, and if found, performs one second try to compile
107 * the operator for the new pair of operatnd types.
108 */
110
111
112 /**
113 * This is a "wrapper" exception thrown when a plug-in or a compile-time invoked callback
114 * function throws an exception of type \c std::exception or of type
115 * \alib{lang;Exception} with a code that is not of this enumeration type.<br>
116 * Used only if compilation \alib{expressions;Compilation::PluginExceptionFallThrough}
117 * is not set.
118 */
120
121 /**
122 * This is a "wrapper" exception thrown when callback functions throws an exception of type
123 * \c std::exception or of type \alib{lang;Exception}.
124 * Used only if compilation \alib{expressions;Compilation::CallbackExceptionFallThrough}
125 * is not set.
126 */
128
129 // ############################ Nested expressions ##################################
130
131 /**
132 * Compile-time exception thrown when unary expression operator is used with a non-constant
133 * nested expression name. */
135
136 /// Compile-time exception thrown when an expression refers to an unknown named nested expression.
138
139 /**
140 * Compile-time exception thrown when a named nested expression which is searched an inserted
141 * at compile-time could not be found.<br>
142 * Overwrites exception \b %NamedExpressionNotFound.
143 *
144 * \see Manual chapter \ref alib_expressions_nested "10. Nested Expressions".
145 */
147
148 /**
149 * Compile-time exception thrown when when wrong arguments were passed to function
150 * \alib{expressions;Compiler::CfgNestedExpressionFunction}.
151 *
152 * \see Manual chapter \ref alib_expressions_nested "10. Nested Expressions".
153 */
155
156 /**
157 * Evaluation-time exception thrown when a named nested expression which is searched only at
158 * evaluation-time could not be found.<br>
159 * Overwrites exception \b %NamedExpressionNotFound.
160 * \see Manual chapter \ref alib_expressions_nested "10. Nested Expressions".
161 */
163
164 /**
165 * Informational exception entry (negative element value) providing the name of the expression
166 * that caused any other exception than \c NamedExpressionNotFound during evaluation of a
167 * nested expression.
168 *
169 * Note that entries of this type might be repeated when expressions are recursively nested.
170 * The number of entries in the exception corresponds to the depth of nesting.
171 */
173
174 /**
175 * Evaluation-time exception thrown when a named nested expression which was searched and found
176 * only at evaluation-time, returned a different result type than specified.<br>
177 *
178 * \see Manual chapter \ref alib_expressions_nested "10. Nested Expressions".
179 */
181
182 /**
183 * Evaluation-time exception thrown when a circular relationship of nested expressions
184 * is detected, which comprises an infinite loop.
185 */
187
188 /**
189 * A list of informational entries of this type is given with exception
190 * \b %CircularNestedExpressions. Each entry provides the name of the expression that
191 * was evaluated and the name of the nested expression that it called. Hence, the list of
192 * entries of this type comprise the "call stack" that leaded to the circular call that
193 * caused the exception.
194 */
196
197
198 /**
199 * This is an extension entry added to exceptions that occur with compilation or evaluation
200 * of expressions by class \alib{expressions;util::ExpressionFormatter}.
201 */
203};
204
205/** ************************************************************************************************
206 * \alib{enums;T_EnumIsArithmetical;Arithmetical enumeration} of slots used to prioritize
207 * \alib{expressions;CompilerPlugin} instances attached to instances of class
208 * \alib{expressions;Compiler} at run-time.
209 **************************************************************************************************/
211{
212 /** Used to denote that no variable or plug-in was found. */
213 NONE = 0,
214
215 /**
216 * Built-in operator <c>?:</c> (like conditional, but no 'true'-expression).
217 * \see \alib{expressions;plugins::ElvisOperator}
218 */
219 ElvisOperator = 100,
220
221 /**
222 * Auto-cast plug-in.
223 */
224 AutoCast = 200,
225
226 /**
227 * Built-in String comparison and manipulation.
228 */
229 Strings = 300,
230
231
232 /**
233 * Collection of built-in unary and binary operators for boolean, integer and floating point values.
234 */
235 Arithmetics = 400,
236
237 /**
238 * Collection of built-in unary and binary operators for boolean, integer and floating point values.
239 */
240 Math = 500,
241
242 /**
243 * Collection of date and time functions based on \ref alib::time.
244 */
245 DateAndTime = 600,
246
247 /**
248 * This is where custom plug-ins usually should be placed. It gives them a higher priority
249 * than all built-in plug-ins have.<br>
250 * If more than one plug-in should be installed, add 1, 2, ... to the enum element.
251 */
252 Custom = 1000,
253
254};
255
256/** ************************************************************************************************
257 * This struct holds static \ref alib_expressions_prereq_sb "sample values" for
258 * the built-in supported types of module \alib_expressions_nl.
259 *
260 * These boxes are mainly used by built-in compiler plug-ins to denote the corresponding type.
261 * Customized plug-ins are proposed to use these boxes to denote internal types as well and
262 * besides that to define static sample boxes for each custom type that they introduce in a
263 * similar fashion.
264 *
265 * \note
266 * Of-course, just sample any value might be passed where a type is expected, but using these
267 * pre-defined objects is more efficient in respect to code size. In respect to execution
268 * performance, the sample values are rather irrelevant, as those are used almost exclusively
269 * at expression compile-time.
270 **************************************************************************************************/
271struct Types
272{
273 /** Sample <em>type-box</em> for C++ type <c>void</c>. */
275
276 /** Sample <em>type-box</em> for C++ type <c>bool</c>. */
278
279 /** Sample <em>type-box</em> for integer types. (Precisely for type \alib{integer}.)*/
281
282 /** Sample <em>type-box</em> for C++ type <c>double</c>. */
284
285 /** Sample <em>type-box</em> for string types. While internally, \alib class
286 * \alib{strings;TString;String} is used, due to the magic of module \alib_boxing, almost
287 * any custom string type is compatible, including of-course \c std::string. */
289
290 /** Sample <em>type-box</em> for date and time values of type \alib{time;DateTime}). */
292
293 /** Sample <em>type-box</em> for values of type \alib{time;TimePointBase::Duration;DateTime::Duration}). */
295};
296
297/** ************************************************************************************************
298 * This struct holds static arrays of pointers to \ref alib_expressions_prereq_sb "sample values".
299 * The arrays are used with helper class \alib{expressions::plugins;Calculus} to denote accepted
300 * "function signatures" when* initializing column
301 * \doxlinkproblem{structalib_1_1expressions_1_1plugins_1_1Calculus_1_1FunctionEntry.html;a3f9769a430a930630a75d41bc7e4055c;FunctionEntry::Signature}
302 of table
303 * \alib{expressions::plugins;Calculus::Functions}.
304 *
305 * Each static field of this class represents a permutation of function arguments. Note, that only
306 * those permutations which are needed and used by the built-in compiler plugins (
307 * \alib{expressions::plugins;Arithmetics},
308 * \alib{expressions::plugins;Math},
309 * \alib{expressions::plugins;Strings} and
310 * \alib{expressions::plugins;DateAndTime} ) are contained here.
311 *
312 * Custom compiler plug-ins may use the argument signatures given here, if a fitting signature
313 * is already included. Otherwise a custom signature array has to be defined, initialized and
314 * provided to the function definition table.
315 **************************************************************************************************/
317{
318 static ALIB_API Box* Var [1]; ///< Function accepts variadic arguments.
319 static ALIB_API Box* B [1]; ///< Function accepts one boolean argument.
320 static ALIB_API Box* BB [2]; ///< Function accepts two boolean arguments.
321 static ALIB_API Box* I [1]; ///< Function accepts one integral argument.
322 static ALIB_API Box* II [2]; ///< Function accepts two integral arguments.
323 static ALIB_API Box* IVar[2]; ///< Function accepts one integral argument, followed by variadic arguments.
324 static ALIB_API Box* F [1]; ///< Function accepts one floating point argument.
325 static ALIB_API Box* FF [2]; ///< Function accepts two floating point arguments.
326 static ALIB_API Box* S [1]; ///< Function accepts one string argument.
327 static ALIB_API Box* SVar[2]; ///< Function accepts one string argument, followed by variadic arguments.
328 static ALIB_API Box* SS [2]; ///< Function accepts two string arguments.
329 static ALIB_API Box* SI [2]; ///< Function accepts one string argument, followed by an integral argument.
330 static ALIB_API Box* SSB [3]; ///< Function accepts two string arguments, followed by a boolean argument.
331 static ALIB_API Box* SSI [3]; ///< Function accepts two string arguments, followed by an integral argument.
332 static ALIB_API Box* SII [3]; ///< Function accepts one string argument, followed by two integral arguments.
333 static ALIB_API Box* SSS [3]; ///< Function accepts three string arguments.
334#if ALIB_CAMP
335 static ALIB_API Box* D [1]; ///< Function accepts a \alib{time;DateTime} argument.
336 static ALIB_API Box* Dur [1]; ///< Function accepts a \alib{time;TimePointBase::Duration;Duration} argument.
337 static ALIB_API Box* DDur[2]; ///< Function accepts a \alib{time;DateTime} argument; followed by a \alib{time;TimePointBase::Duration;Duration}.
338#endif
339};
340
341
342/** ************************************************************************************************
343 * This enumeration lists the built-in unary operators.
344 * The associated \ref alib_enums_records "ALib Enum Records" provides the operator symbols.
345 **************************************************************************************************/
347{
348 NONE , ///< Not an operator.
349
350 Positive , ///< <c>'+'</c> operator (usually returns identity value).
351 Negative , ///< <c>'-'</c> operator, negates a value.
352
353 BoolNot , ///< Boolean not (<c>'!'</c>).
354 BitNot , ///< Bitwise not (<c>'~'</c>).
355
356 Indirection , ///< Unary <c>'*'</c> operator. Similar to the C++ indirection operator, this
357 ///< is the default operator uses with nested expressions, which is defined
358 ///< with \alib{expressions;Compiler::CfgNestedExpressionOperator}.
359};
360
361/** ************************************************************************************************
362 * This enumeration lists the built-in binary operators.
363 * The associated \ref alib_enums_records "ALib Enum RecordS" of type
364 * \alib{expressions;ERBinaryOperator} provides an operator's symbol an its precedence.
365 **************************************************************************************************/
367{
368 NONE , ///< Not an operator.
369 Subscript , ///< Array subscripting (<c>'[]'</c>). Precedence hardcoded with parser.
370
371 Multiply , ///< Arithmetic multiplication (<c>'*'</c>). Precedence \c 900.
372 Divide , ///< Arithmetic division (<c>'/'</c>). Precedence \c 900.
373 Modulo , ///< Arithmetic modulo (<c>'%%'</c>). Precedence \c 900.
374
375 Add , ///< Arithmetic addition (<c>'+'</c>). Precedence \c 800.
376 Subtract , ///< Arithmetic subtraction (<c>'-'</c>). Precedence \c 800.
377
378 ShiftLeft , ///< Bitwise shifting of integral values (<c>'<<'</c>). Precedence \c 700.
379 ShiftRight , ///< Bitwise shifting of integral values (<c>'>>'</c>). Precedence \c 700.
380
381 Smaller , ///< Smaller operator (<c>'<'</c>). Precedence \c 600.
382 SmallerOrEqual , ///< Smaller or equal operator (<c>'<='</c>). Precedence \c 600.
383 Greater , ///< Greater operator (<c>'>'</c>). Precedence \c 600.
384 GreaterOrEqual , ///< Greater or equal operator (<c>'>='</c>). Precedence \c 600.
385
386 Equal , ///< Equal operator (<c>'=='</c>). Precedence \c 500.
387 NotEqual , ///< Not equal operator (<c>'!='</c>). Precedence \c 500.
388
389 BitAnd , ///< Binary and (<c>'&'</c>). "and"s all bits of two integral values. Precedence \c 470.
390 BitXOr , ///< Binary xor (<c>'^'</c>). "xor"s all bits of two integral values. Precedence \c 460.
391 BitOr , ///< Binary or (<c>'|'</c>). "or"s all bits of two integral values. Precedence \c 450.
392 BoolAnd , ///< Boolean and (<c>'&&'</c>). Result is boolean. Precedence \c 440.
393 BoolOr , ///< Boolean or (<c>'||'</c>). Result is boolean. Precedence \c 430.
394
395 Assign , ///< Assignment. By default, this is used as alias operator for
396 ///< operator \b Equal by the built-in compiler plug-ins.
397 ///< See \alib{expressions::Compilation;AliasEqualsOperatorWithAssignOperator}
398 ///< for more information.<br>
399 ///< Precedence \c 300.
400
401
402 Elvis , ///< Binary version of ternary operator <c>Q ? T : F</c> with
403 ///< second operand (\c T) not given.
404 ///< Whitespaces are allowed between '?' and ':'.<br>
405 ///< Precedence \c 200.
406};
407
408/** ************************************************************************************************
409 * \ref alib_enums_records "ALib Enum Record" associated with enumeration
410 * \alib{expressions;DefaultBinaryOperators}.
411 **************************************************************************************************/
413{
414 /** The parable symbol of an operator. */
416
417 /** The precedence of an operator in respect to other binary operators. */
419
420 /**
421 * Required default constructor leaving the record undefined.
422 * (Requirement is documented with\alib{enums::EnumRecordPrototype}.)
423 */
424 ERBinaryOperator() noexcept = default;
425
426 /**
427 * Required initializing constructor.
428 * (Requirement is documented with\alib{enums::EnumRecordPrototype}.)
429 *
430 * @param symbol The parsable operator symbol.
431 * @param precedence The operator's precedence.
432 */
433 ERBinaryOperator( const String& symbol, int precedence )
434 : Symbol (symbol)
435 , Precedence(precedence)
436 {}
437
438 /** Implementation of \alib{enums;EnumRecordPrototype::Parse}. */
440 void Parse();
441};
442
443
444/** ************************************************************************************************
445 * This enumeration lists the built-in verbal alias names for unary operators.
446 *
447 * The associated \ref alib_enums_records "ALib Enum Records" provides the operator verbs
448 * as well as the replacement operator.
449 *
450 * Flag \alib{expressions;Compilation::DefaultAlphabeticOperatorAliases} controls if method
451 * \alib{expressions;Compiler::SetupDefaults} adds the aliases to the compiler.
452 **************************************************************************************************/
454{
455 Not , ///< Verbal alias \c "Not" to operator <c>'!'</c>.
456};
457
458/** ************************************************************************************************
459 * This enumeration lists the built-in verbal alias names for binary operators.
460 *
461 * The associated \ref alib_enums_records "ALib Enum Records" provides the operator verbs
462 * as well as the replacement operator.
463 *
464 * Flag \alib{expressions;Compilation::DefaultAlphabeticOperatorAliases} controls if method
465 * \alib{expressions;Compiler::SetupDefaults} adds the aliases to the compiler.
466 **************************************************************************************************/
468{
469 And , ///< Verbal alias \c "And" to boolean and operator <c>'&&'</c>.
470 Or , ///< Verbal alias \c "Or" to boolean or operator <c>'||'</c>.
471 Sm , ///< Verbal alias \c "Sm" to operator <c>'<'</c>.
472 Smaller , ///< Verbal alias \c "Smaller" to operator <c>'<'</c>.
473 SmEq , ///< Verbal alias \c "Smeq" to operator <c>'<='</c>.
474 SmallerOrEqual , ///< Verbal alias \c "Smaller_or_equal" to operator <c>'<='</c>.
475 Gt , ///< Verbal alias \c "Gt" to operator <c>'>'</c>.
476 Greater , ///< Verbal alias \c "Greater" to operator <c>'>'</c>.
477 GtEq , ///< Verbal alias \c "Gteq" to operator <c>'>='</c>.
478 GreaterOrEqual , ///< Verbal alias \c "Greater_or_equal" to operator <c>'>='</c>.
479 Eq , ///< Verbal alias \c "Eq" to operator <c>'=='</c>.
480 Equals , ///< Verbal alias \c "Equals" to operator <c>'=='</c>.
481 NEq , ///< Verbal alias \c "Neq" to operator <c>'!='</c>.
482 NotEqual , ///< Verbal alias \c "Not_equals" to operator <c>'!='</c>.
483};
484
485/** ************************************************************************************************
486 * \ref alib_enums_records "ALib Enum Record" associated with enumeration
487 * \alib{expressions;DefaultBinaryOperators}.
488 **************************************************************************************************/
490{
491 /** The parsable symbol of an alias operator. */
493
494 /** The replacement operator symbol. */
496
497 /**
498 * Required default constructor leaving the record undefined.
499 * (Requirement is documented with\alib{enums::EnumRecordPrototype}.)
500 */
501 EROperatorAlias() noexcept = default;
502
503 /**
504 * Required initializing constructor.
505 * (Requirement is documented with\alib{enums::EnumRecordPrototype}.)
506 *
507 * @param symbol The parsable operator symbol.
508 * @param replacement The symbol of the aliased operator.
509 */
510 EROperatorAlias( const String& symbol, const String& replacement )
511 : Symbol (symbol)
512 , Replacement(replacement)
513 {}
514
515 /** Implementation of \alib{enums;EnumRecordPrototype::Parse}. */
517 void Parse();
518};
519
520
521
522/** ************************************************************************************************
523 * \alib{enums;T_EnumIsBitwise;Bitwise} enum class defining options of expression compilation.
524 * Flags defined with this type are set in field \alib{expressions;Compiler::CfgCompilation}.
525 **************************************************************************************************/
526enum class Compilation
527{
528 /**
529 * If this flag is set, all unary operators given in \alib{expressions;DefaultUnaryOperators}
530 * are defined with method \alib{expressions;Compiler::SetupDefaults}.
531 *
532 * Note that the enumeration class is equipped with resourced
533 * \ref alib_enums_records "ALib Enum Records", which might be changed as an
534 * alternative to clearing this flag and provide own definitions.
535 *
536 * This flag is set by default.
537 */
538 DefaultUnaryOperators = (1 << 1),
539
540 /**
541 * If this flag is set, all binary operators given in \alib{expressions;DefaultBinaryOperators}
542 * are defined with method \alib{expressions;Compiler::SetupDefaults}.
543 *
544 * Note that the enumeration class is equipped with resourced
545 * \ref alib_enums_records "ALib Enum Records", which might be changed as an
546 * alternative to clearing this flag and provide own definitions.
547 *
548 * This flag is set by default.
549 */
550 DefaultBinaryOperators = (1 << 2),
551
552 /**
553 * If this flag is set, all alphabetic operator aliases given in enumerations
554 * \alib{expressions;DefaultAlphabeticUnaryOperatorAliases} and
555 * \alib{expressions;DefaultAlphabeticBinaryOperatorAliases}
556 * are defined with method \alib{expressions;Compiler::SetupDefaults}.
557 *
558 * Note that both enumeration classes are equipped with resourced
559 * \ref alib_enums_records "ALib Enum Records", which might be changed as an
560 * alternative to clearing this flag and provide own definitions.
561 *
562 * This flag is set by default.
563 */
565
566 /**
567 * If this flag is set, alphabetic operator aliases defined in
568 * \alib{expressions;Compiler::AlphabeticUnaryOperatorAliases} and
569 * \alib{expressions;Compiler::AlphabeticBinaryOperatorAliases} are parsed ignoring letter
570 * case.
571 *
572 * \note
573 * Even when this flag is cleared, no two verbal operator aliases that are equal
574 * when case is ignored must be defined (e.g "or" and "OR" ).
575 *
576 * This flag is set by default.
577 */
579
580 /**
581 * If not set, array subscript operator <c>[]</c> is not supported and its use will cause
582 * parse errors errors.
583 *
584 * Note that compiler plug-ins get the array subscript operator presented for compilation
585 * as a usual binary operator given as \alib{expressions;DefaultBinaryOperators::Subscript}.
586 * This makes its support with custom types quite simple.
587 *
588 * \attention This flag has to be changed to a custom state prior to performing the first
589 * compilation of an expression with a dedicated \alib{expressions;Compiler}.
590 * The rationale behind this is, that the compiler creates the parser system at its
591 * first use, which in turn does not check the flag after creation.
592 *
593 * This flag is set by default.
594 */
595 AllowSubscriptOperator = (1 << 5),
596
597 /**
598 * Used with constructor of compiler plug-ins
599 * \alib{expressions;plugins::Arithmetics} and
600 * \alib{expressions;plugins::Strings}.
601 * (If they are activated in \alib{expressions;Compiler::CfgBuiltInPlugins} or "manually"
602 * added.)
603 *
604 * Denotes if the assignment operator <c>=</c> is an alias for equal operator <c>==</c>.
605 * If set to \c false, the use of the <c>=</c> operator with several any argument type,
606 * throws a compilation exception, unless it is compiled by a custom plug-in.
607 *
608 * \attention
609 * In addition to aliasing the <c>==</c> with <c>=</c>, the latter also receives a
610 * higher precedence of parsing! If this flag is not set, the precedence of
611 * \e assign <c>=</c>,follows the C++ standards and thus is below the group of
612 * <c>&</c>, <c>^</c>, <c>|</c>, <c>&&</c>, <c>||</c> and <c>? :</c>. If the alias
613 * setting is activated, then the precedence is raised to be on the same level as
614 * boolean equal <c>==</c> and thus higher than the aforementioned operators!
615 */
617
618 /**
619 * Used with constructor of compiler plug-in \alib{expressions;plugins::Arithmetics}.
620 * (If it is activated in \alib{expressions;Compiler::CfgBuiltInPlugins} or "manually" added.)
621 *
622 * Denotes if the unary bitwise operator <c>~</c> and binary bitwise operators
623 * <c>&</c>, <c>|</c> and <c>^</c> should be allowed for boolean values.
624 * If set to \c false, the use of the bitwise operators with boolean arguments, throws
625 * a compilation exception, unless the bitwise operators are compiled by a custom plug-in.
626 */
628
629
630 /**
631 * If \c false, compile-time exception
632 * \alib{expressions;Exceptions::MissingFunctionParentheses} is thrown if a parameterless
633 * function is stated without (otherwise redundant) parentheses <c>'()'</c>.
634 *
635 * If \c true, this is tolerated.
636 *
637 * \note
638 * This flag is not tested, and the exception is not thrown, by the compiler itself, but
639 * by class \alib{expressions::plugins;Calculus}.<br>
640 * Even if this flag is \c false, still functions without parentheses may be allowed
641 * by setting \c nullptr to field
642 * \doxlinkproblem{structalib_1_1expressions_1_1plugins_1_1Calculus_1_1FunctionEntry;a3f9769a430a930630a75d41bc7e4055c;Calculus::FunctionEntry::Signature}
643 * when registering a function. In this case the function is considered rather being an
644 * "identifier" than a function. (Still it is the very same as a function, it is just a
645 * matter of wording here.)<br>
646 *
647 * The other way round, if a function is registered as an identifier, flag
648 * \b %AllowEmptyParenthesesForIdentifierFunctions, controls if exception
649 * \alib{expressions;Exceptions::IdentifierWithFunctionParentheses} is to be thrown
650 * if empty parentheses are given on functions that are registered as
651 * identifier-style functions.
652 */
654
655 /**
656 * If \c false, compile-time exception
657 * \alib{expressions;Exceptions::IdentifierWithFunctionParentheses} is thrown if a
658 * parameterless function, declared as 'identifier style' is used with parentheses
659 * <c>'()'</c>.
660 *
661 * If \c true, this is tolerated.
662 *
663 * \see
664 * For more information, see the note in documentation of flag
665 * \b %AllowOmittingParenthesesOfParameterlessFunctions.
666 */
668
669 /**
670 * If this flag is set (the default), the
671 * \alib{expressions;Compiler::CfgNestedExpressionOperator;unary nested expression operator}
672 * is activated, as well as the single-parameter overload of the
673 * \alib{expressions;Compiler::CfgNestedExpressionFunction;nested expression function}.
674 * If the field is cleared, then only evaluation-time nested expressions are allowed,
675 * which is the two- and three-parameter version of the expression function.
676 * Other uses are then causing compilation exception
677 * \alib{expressions;Exceptions::UnaryOperatorNotDefined}, respectively
678 * \alib{expressions;Exceptions::NestedExpressionCallArgumentMismatch}.
679 */
681
682 /**
683 * If this flag is set (the default), then identifiers that follow the unary nested
684 * expression operator (defaults to <c>'*'</c>), are internally converted to corresponding
685 * string literals - just as if they were given as a quoted string.
686 *
687 * \see
688 * Normalization flag
689 * \alib{expressions::Normalization;QuoteUnaryNestedExpressionOperatorArgument}.
690 */
692
693 /**
694 * If not set (the default), then names of named expressions are not distinguished by
695 * letter case.
696 */
698
699 /**
700 * Controls whether exceptions of type \c std::exception thrown in plug-ins during compilation
701 * are caught by the compiler and transformed to \alib{expressions;Exceptions::ExceptionInPlugin}
702 *
703 * Note that exceptions thrown in callback functions which are evaluated at compile-time
704 * against constant parameters, are considered plug-in exceptions.
705 */
706 PluginExceptionFallThrough = (1 << 13),
707
708
709 /**
710 * This is an "evaluation-time compiler flag". If not set (the default) exceptions of type
711 * \alib{lang;Exception} and \c std::exception thrown in callback functions during expression
712 * evaluation are caught and transformed to \alib{expressions;Exceptions::ExceptionInCallback}
713 * letter case.
714 */
716
717 /**
718 * If this flag is set, no optimizations are performed when assembling the program.
719 *
720 * \note
721 * There is absolutely no reason for setting this flag, other than for running the
722 * unit tests. Or for playing with the little virtual machine implemented with this
723 * library and having fun understanding the non-optimized program listings generated.
724 * The assembly language is easy, it has only four virtual assembly commands - plus a fifth
725 * for invoking programs of nested expressions.
726 */
727 NoOptimization = (1 << 20),
728
729
730 /**
731 * Default value. Evaluates to:<br>
732 * <c> DefaultUnaryOperators + </c><br>
733 * <c> DefaultBinaryOperators + </c><br>
734 * <c> DefaultAlphabeticOperatorAliases + </c><br>
735 * <c> AlphabeticOperatorsIgnoreCase + </c><br>
736 * <c> AliasEqualsOperatorWithAssignOperator + </c><br>
737 * <c> AllowBitwiseBooleanOperators + </c><br>
738 * <c> AllowSubscriptOperator + </c><br>
739 * <c> AllowOmittingParenthesesOfParameterlessFunctions + </c><br>
740 * <c> AllowEmptyParenthesesForIdentifierFunctions + </c><br>
741 * <c> AllowCompileTimeNestedExpressions + </c><br>
742 * <c> AllowIdentifiersForNestedExpressions + </c><br>
743 */
755};
756
757/** ************************************************************************************************
758 * \alib{enums;T_EnumIsBitwise;Bitwise} enum class defining options for formatting parsed
759 * expressions. The normalized conversion of the expression input string is available
760 * with method \alib{expressions;Expression::GetNormalizedString}, after an expression was
761 * successfully \alib{expressions;Compiler::Compiler;compiled}.
762 *
763 * The normalization flags are stored per compiler instance, consequently using a public compiler
764 * field namely \alib{expressions;Compiler::CfgNormalization}.
765 **************************************************************************************************/
766enum class Normalization : uint64_t
767{
768 /**
769 * Replace given shortened and letter case mismatched identifier and function names with
770 * completed versions.<br>
771 * This flag is set with \b %DEFAULT.
772 */
773 ReplaceFunctionNames = (1LLU << 1),
774
775 /**
776 * Replace alias operators with effective operators.<br>
777 * This flag is not set with \b %DEFAULT.
778 */
779 ReplaceAliasOperators = (1LLU << 2),
780
781 /**
782 * This is one of four flags that together allow five possible normalization options for
783 * \ref alib_expressions_operators_verbal "verbal alias operators".
784 * If more than one flag is set, the one with the highest precedence is used.
785 *
786 * The following table lists the flags, their precedence and the type of normalization:
787 *
788 * |Precedence | Flag | Description
789 * |------------|----------------------------------|------------------------------
790 * | 0 | <none set> | A verbal operator is normalized as given in original expression string.
791 * | 1 | ReplaceVerbalOperatorsToSymbolic | Replaces verbal operators with the symbolic operator that they represent.
792 * | 2 | ReplaceVerbalOperatorsToLowerCase | Converts verbal operators to lower case letters.
793 * | 3 | ReplaceVerbalOperatorsToUpperCase | Converts verbal operators to upper case letters.
794 * | 4 | ReplaceVerbalOperatorsToDefinedLetterCase | Uses the writing specified with the definition of the verbal operator.
795 *
796 * With configuration \alib{expressions::Normalization;DEFAULT}, flag
797 * \b %ReplaceVerbalOperatorsToUpperCase is set.
798 */
800
801 /**
802 * See sibling flag \alib{expressions::Normalization;ReplaceVerbalOperatorsToSymbolic}.
803 */
805
806 /**
807 * See sibling flag \alib{expressions::Normalization;ReplaceVerbalOperatorsToSymbolic}.
808 */
810
811 /**
812 * See sibling flag \alib{expressions::Normalization;ReplaceVerbalOperatorsToSymbolic}.
813 */
815
816 /**
817 * Converts nested expression names that have been given unquoted to a quoted string literal.
818 * If this is not set, the quotation remains as given in original expression string.
819 * This flag is \e not set with \b %DEFAULT.
820 *
821 * \see
822 * Compilation flag
823 * \alib{expressions::Compilation;AllowIdentifiersForNestedExpressions}.
824 */
826
827 /**
828 * Remove redundant provisions unary operators <c>'+'</c> and <c>'-'</c> from number
829 * literals.<br>
830 * This flag is \e not set with \b %DEFAULT.
831 */
833
834 /**
835 * Write a space after an unary operator (if no brackets around arguments and no unary operator
836 * follows).<br>
837 * This flag is \e not set with \b %DEFAULT.
838 */
839 UnaryOpSpace = (1LLU << 9),
840
841 /**
842 * Write a space between two unary operators.<br>
843 * This flag is \e not set with \b %DEFAULT.
844 */
845 UnaryOpSpaceIfUnaryFollows = (1LLU << 10),
846
847 /**
848 * Write a space before opening bracket of bracketed arguments of unary operators.<br>
849 * This flag is \e not set with \b %DEFAULT.
850 */
851 UnaryOpSpaceIfBracketFollows = (1LLU << 11),
852
853 /**
854 * Write a space after an opening and before a closing bracket of arguments of unary operators.<br>
855 * This flag is \e not set with \b %DEFAULT.
856 */
857 UnaryOpInnerBracketSpace = (1LLU << 12),
858
859 /**
860 * If this flag is set, normalization inserts redundant brackets to the argument of an
861 * unary operator, if that argument is an unary operator itself.
862 *
863 * This flag is superseded by \b %RedundantUnaryOpBrackets.<br>
864 * This flag is \e not set with \b %DEFAULT.
865 */
867
868 /**
869 * If this flag is set, normalization inserts redundant brackets to arguments of unary
870 * operators.
871 *
872 * This flag supersedes by \b %RedundantBracketsBetweenTwoUnaryOps.<br>
873 * This flag is \e not set with \b %DEFAULT.
874 */
875 RedundantUnaryOpBrackets = (1LLU << 14),
876
877
878 /**
879 * Write a space before and after binary operator symbol.<br>
880 * This flag is set with \b %DEFAULT.
881 */
882 BinaryOpSpaces = (1LLU << 15),
883
884 /**
885 * Write a space after an opening and before a closing bracket of arguments of binary
886 * operators and around a conditional expression.<br>
887 * This flag is \e not set with \b %DEFAULT.
888 */
889 InnerBracketSpace = (1LLU << 16),
890
891 /**
892 * Write a space before opening and after closing bracket of arguments of binary
893 * operators and around a conditional expression.<br>
894 * This flag is \e not set with \b %DEFAULT.
895 */
896 OuterBracketSpace = (1LLU << 17),
897
898 /**
899 * If this flag is set, normalization inserts redundant brackets to the right-hand side
900 * operand of binary operators if that operand is a binary operator itself and has a higher
901 * precedence.
902 *
903 * The following samples demonstrate why this is useful if normalization targets humans:
904 *
905 * Without flag set | With flag set
906 * ---------------------|----------------------
907 * 1 - 2 - 3 | <em>no change</em>
908 * 1 - 2 * 3 | 1 - (2 * 3)
909 * 1 * 2 - 3 | <em>no change</em>
910 * 1 - 2 * 3 - 4 - 5 * 6 - 7 | 1 - (2 * 3) - 4 - (5 * 6) - 7
911 * true == false && true | <em>no change</em>
912 * true && false == true | true && (false == true)
913 * true && false == false && true | true && (false == false) && true
914 * true && false == (false && true) | true && (false == (false && true))
915 * true && false == true < false | true && (false == (true < false))
916 * true && false == false == true | true && (false == false == true)
917 * This flag is superseded by \b %RedundantBinaryOpBrackets.<br>
918 * This flag is set with \b %DEFAULT.
919 */
921
922 /**
923 * If this flag is set, normalization inserts redundant brackets to both
924 * operands of binary operators if both are binary operators themselves.
925 *
926 * The following samples demonstrate why this is useful if normalization strings target humans:
927 *
928 * Without flag set | With flag set
929 * ---------------------|----------------------
930 * 1 - 2 - 3 | <em>no change</em>
931 * 1 - 2 - 3 - 4 | <em>no change</em>
932 * 1 - 2 - (3 - 4) | (1 - 2) - (3 - 4)
933 * 1 - 2 - 3 - (4 - 5) | (1 - 2 - 3) - (4 - 5)
934 * 1 - 2 - (3 - 4) - 5 | (1 - 2) - (3 - 4) - 5
935 *
936 * This flag is superseded by \b %RedundantBinaryOpBrackets.<br>
937 * This flag is set with \b %DEFAULT.
938 */
940
941 /**
942 * If this flag is set, normalization inserts redundant brackets around each binary operator
943 * sub-expression. This flag supersedes flags
944 * \b %RedundantRhsBracketsIfRhsIsStrongerBinaryOp and
945 * \b %RedundantBracketsIfLhsAndRhsAreBinaryOps.
946 *
947 * It is not recommended to set this flag. It is only useful to debug expressions and
948 * understand exactly what precedences operators have.
949 *
950 * This flag is set with \b %DEFAULT.
951 */
952 RedundantBinaryOpBrackets = (1LLU << 20),
953
954
955 /**
956 * Write a space before character <c>?</c> of ternary conditional operator.<br>
957 * This flag is set with \b %DEFAULT.
958 */
959 ConditionalOpSpaceBeforeQM = (1LLU << 21),
960
961 /**
962 * Write a space after character <c>?</c> of a ternary conditional operator.<br>
963 * This flag is set with \b %DEFAULT.
964 */
965 ConditionalOpSpaceAfterQM = (1LLU << 22),
966
967 /**
968 * Write a space before character <c>:</c> of ternary conditional operator.<br>
969 * This flag is set with \b %DEFAULT.
970 */
971 ConditionalOpSpaceBeforeColon = (1LLU << 23),
972
973 /**
974 * Write a space after character <c>:</c> of ternary conditional operator.<br>
975 * This flag is set with \b %DEFAULT.
976 */
977 ConditionalOpSpaceAfterColon = (1LLU << 24),
978
979 /**
980 * If this flag is set, normalization inserts redundant brackets around the conditional
981 * operator expressions <c>Q ? T : F</c>, if it is not the root node.
982 *
983 * This flag is set with \b %DEFAULT.
984 */
985 RedundantConditionalOpBrackets = (1LLU << 25),
986
987 /**
988 * Write a space before between the function identifier name and the opening bracket of the
989 * argument list.<br>
990 * This flag is \e not set with \b %DEFAULT.
991 */
993
994 /**
995 * Write a space after the opening and before the closing bracket of argument list of a
996 * function.<br>
997 * This flag is set with \b %DEFAULT.
998 */
999 FunctionInnerBracketSpace = (1LLU << 27),
1000
1001 /**
1002 * Write a space between the opening and the closing bracket of an empty argument list of a
1003 * function.<br>
1004 * This flag is set with \b %DEFAULT.
1005 */
1007
1008 /**
1009 * Write a space before a comma of an argument separator of an function's argument list.<br>
1010 * This flag is \e not set with \b %DEFAULT.
1011 */
1012 FunctionSpaceBeforeComma = (1LLU << 29),
1013
1014 /**
1015 * Write a space after a comma of an argument separator of a function's argument list.<br>
1016 * This flag is set with \b %DEFAULT.
1017 */
1018 FunctionSpaceAfterComma = (1LLU << 30),
1019
1020 /**
1021 * Write a space before array subscript operator <c>'[]'</c>.<br>
1022 * This flag is \e not set with \b %DEFAULT.
1023 */
1024 SubscriptSpaceBeforeBrackets = (1LLU << 31),
1025
1026 /**
1027 * Write a space after the opening and before the closing bracket of array subscript operator
1028 * <c>'[]'</c>.<br>
1029 * This flag is \e not set with \b %DEFAULT.
1030 */
1031 SubscriptInnerBracketSpace = (1LLU << 32),
1032
1033
1034 /**
1035 * If this flag is set, floating point literals are normalized in scientific format when
1036 * given in scientific format. If it is not set, then numbers given in scientific format
1037 * might be written as usual floating point values, dependent on their value. E.g.
1038 * a given <c>1.0e1</c> would be converted to <c>10.0</c>.
1039 *
1040 * Note that scientific format can be forced for all floating point number output by setting
1041 * flag \alib{strings;NumberFormatFlags;ForceScientific} in field
1042 * \alib{strings::NumberFormat;Flags} of variable
1043 * \alib{lang::format;Formatter::DefaultNumberFormat}, which in turn is found
1044 * in member \alib{expressions;Compiler::CfgFormatter}. Such setting would supersede
1045 * this flag.
1046 *
1047 * This flag is \e not set with \b %DEFAULT.
1048 */
1049 KeepScientificFormat = (1LLU << 33 ),
1050
1051 /**
1052 * If this flag is set, integral literals will be normalized to hexadecimal format.
1053 * If this flag is not set, then integrals will be normalized in the number system that they had
1054 * been provided in.
1055 *
1056 * This flags supersedes flags \b %ForceOctal and \b %ForceBinary.
1057 *
1058 * This flag is \e not set with \b %DEFAULT.
1059 */
1060 ForceHexadecimal = (1LLU << 34 ),
1061
1062 /**
1063 * If this flag is set, integral literals will be normalized to octal format.
1064 * If this flag is not set, then integrals will be normalized in the number system that they had
1065 * been provided in.
1066 *
1067 * This flags is superseded by flag \b %ForceHexadecimal and supersedes flag \b %ForceBinary.
1068 *
1069 * This flag is \e not set with \b %DEFAULT.
1070 */
1071 ForceOctal = (1LLU << 35 ),
1072
1073 /**
1074 * If this flag is set, integral literals will be normalized to binary format.
1075 * If this flag is not set, then integrals will be normalized in the number system that they had
1076 * been provided in.
1077 *
1078 * This flags is superseded by flags \b %ForceHexadecimal and \b %ForceOctal.
1079 *
1080 * This flag is \e not set with \b %DEFAULT.
1081 */
1082 ForceBinary = (1LLU << 36 ),
1083
1084 /**
1085 * All flags are cleared, may be used for testing bits.
1086 */
1087 NONE = 0L,
1088
1089 /**
1090 * All flags are cleared, hence no whitespaces and unnecessary brackets are written and
1091 * identifiers as they have been given (potentially abbreviated and ignoring letter case).
1092 */
1093 COMPACT = 0L,
1094
1095 /**
1096 * Default value. Evaluates to:<br>
1097 * <c>ReplaceFunctionNames + </c><br>
1098 * <c>ReplaceVerbalOperatorsToUpperCase + </c><br>
1099 * <br>
1100 * <c>RemoveRedundantUnaryOpsOnNumberLiterals + </c><br>
1101 * <c>BinaryOpSpaces + </c><br>
1102 * <c>RedundantRhsBracketsIfRhsIsStrongerBinaryOp + </c><br>
1103 * <c>RedundantBracketsIfLhsAndRhsAreBinaryOps + </c><br>
1104 * <br>
1105 * <c>ConditionalOpSpaceBeforeQM + </c><br>
1106 * <c>ConditionalOpSpaceBeforeColon + </c><br>
1107 * <c>ConditionalOpSpaceAfterQM + </c><br>
1108 * <c>ConditionalOpSpaceAfterColon + </c><br>
1109 * <c>RedundantConditionalOpBrackets + </c><br>
1110 * <br>
1111 * <c>FunctionInnerBracketSpace + </c><br>
1112 * <c>FunctionSpaceAfterComma + </c><br>
1113 */
1116
1121
1127
1130};
1131
1132/**
1133 * Type definition for passing boxes as sample types.
1134 *
1135 * \see For more information, see
1136 * \ref alib_expressions_prereq_sb "3.2 Type definitions With Sample Boxes".
1137 */
1139
1140/**
1141 * Type definition for passing arguments to expression callbacks.
1142 *
1143 * \see For more information, see
1144 * \ref alib_expressions_prereq_sb "3.2 Type definitions With Sample Boxes".
1145 */
1146using ArgIterator= std::vector<Box>::iterator;
1147
1148/**
1149 * Function pointer implementing native callback functions, for expression functions and
1150 * operators. The implementations are are defined and selected by the compiler plugins.
1151 * They are called (executed) when an expression is evaluated.
1152 *
1153 * @param scope The expression's evaluation scope.
1154 * @param[out] argsBegin An iterator that returns \b %Box objects.
1155 * The first entry takes also the result.
1156 * @param[out] argsEnd The end-iterator.
1157 *
1158 */
1159using CallbackDecl = Box (*)( Scope& scope, ArgIterator argsBegin, ArgIterator argsEnd );
1160
1161
1162/**
1163 * This struct constitutes a type declaration for a \ref alib_boxing_functions "box-function".
1164 * The function is used to create parsable expression "literals" from constant values of custom
1165 * type stored in boxes.
1166 *
1167 * The function is used by the library if all of the following occurs:
1168 * - If custom identifiers, functions or operator callback functions return a custom type.
1169 * - If such types can be constants and are announced to the compiler as such.
1170 * - If method \alib{expressions;Expression::GetOptimizedString} is called.
1171 * - If such string is to be used as input to compiling expressions.
1172 *
1173 * If the last condition is met, compilation of the "normalized optimized expression string " would
1174 * fail. If it is not met, then without a proper implementation of this function, the only
1175 * "damage" is that such string would show an integral value where a constant custom type was
1176 * expected.
1177 *
1178 * The challenge of implementing this box-function for a custom type, is to convert constants of
1179 * custom types back into a normalized, human readable but also compilable expression string.
1180 * As the expression syntax only defines the built-in literal types
1181 * \alib{expressions::Types;Integer}, \alib{expressions::Types;Float} and
1182 * \alib{expressions::Types;String}, the constants have to be created using either appropriate
1183 * custom identifiers or "constructor functions" that have to be provided in addition along with
1184 * the implementation of this box-function to make it compilable.
1185 *
1186 * A sample for that situation is given in chapter \ref alib_expressions_details_optimizations_norm
1187 * of the Programmer's Manual.
1188 *
1189 * The identifiers and constructor functions in turn need to be compile-time evaluatable
1190 * to ensure that recompiling the optimized string results to constants so that the same
1191 * optimized expression program is generated..
1192 *
1193 * #### Sample: ####
1194 * So far, this probably sounded a little complicated. Let us look step by step at the sample
1195 * given in the aforementioned manual section, that is solved internally by the library using
1196 * this box-function declaration.
1197 *
1198 * %Compiler plug-in \alib{expressions::plugins;DateAndTime} introduces \alib class
1199 * \alib{time;TimePointBase::Duration} to expressions. This is for example done by defining
1200 * identifiers as follows:
1201 *
1202 * \snippet "plugins/dateandtime.cpp" DOX_ALIB_EXPR_FToLiteral_1
1203 *
1204 * The "constructor functions" are declared to be
1205 * \alib{expressions::plugins;Calculus::CTI;compile-time invokable}
1206 * and return a constant value at compile-time in case their input parameter is constant.
1207 * When the program - that may due to optimization not contain the identifiers any more - becomes
1208 * de-compiled, these constants have to be written to the normalized expression string in a way that
1209 * corresponding constant values of type \b %Duration are expressed.
1210 *
1211 * To perform this task, an implementation of the box-function that this struct declares
1212 * has to be registered with boxes containing values of \b TimePointBase::Duration.<br>
1213 * Registrations of box-functions have to be done in the \ref alib_manual_bootstrapping "bootstrap"
1214 * code of the library. In this case it is done in static method
1215 * \alib{expressions;plugins::DateAndTime::Bootstrap}.
1216 * The function name that is used for the implementation is \b %FToLiteral_Duration. Here is
1217 * the line of code that registers the function with the boxed type:
1218 *
1219 * \snippet "expressions/plugins/dateandtime.cpp" DOX_ALIB_EXPR_FToLiteral_2
1220 *
1221 * The implementation is given in an anonymous namespace of the compilation unit of compiler plug-in
1222 * \b %DateAndTime. The function's signature has to meet the one given with type definition #Signature
1223 * of this struct. Besides the first parameter that passes the box that the function is invoked
1224 * on (the one containing the constant value of custom type), second parameter \p{expressionString}
1225 * provides the \b AString that the function is requested to write the "generation expression" to.<br>
1226 * The implementation code looks as follows:
1227 *
1228 * \snippet "expressions/plugins/dateandtime.cpp" DOX_ALIB_EXPR_FToLiteral_3
1229 *
1230 * As it can be understood from the code, the interface implementation tries to find the best
1231 * matching "constructor function" for teh time span given, writes its name and the constant parameter
1232 * enclosed by brackets \c "()".
1233 *
1234 * Only with such interface implementation in place - one that covers all possible constants - this
1235 * library is able to create <b>parsable, normalized, optimized expression strings</b>.
1236 * To finalize this example, we check what the result for three sample expressions looks like:
1237 *
1238 * \snippet "DOX_ALIB_EXPRESSIONS_TUT_WONO-100.txt" OUTPUT
1239 * \snippet "DOX_ALIB_EXPRESSIONS_TUT_WONO-101.txt" OUTPUT
1240 * \snippet "DOX_ALIB_EXPRESSIONS_TUT_WONO-102.txt" OUTPUT
1241 *
1242 * \note
1243 * When integrating module \alib_expressions_nl into a software, a decision has to be
1244 * taken: "Should optimized expression strings be presented to the end-user?"<br>
1245 *
1246 * \note
1247 * While it is obvious, that sample two demonstrates that to be useful, sample three probably
1248 * demonstrates the opposite!<br>
1249 * It is important to understand, that the decision depends on the custom use case, where for
1250 * example the technical understanding of a typical end-user may be taken into account.
1251 *
1252 * \note
1253 * If the decision is taken, \b not to present optimized expression strings to the end-user, this
1254 * has absolutely no influence on the evaluation performance: The compilation of all three
1255 * expression strings, namely
1256 * - the original input,
1257 * - the normalized output and
1258 * - the optimized, normalized output,
1259 * \note
1260 * are leading to the very same (optimized) internal program when compiled!
1261 *
1262 * \note
1263 * Of-course, if no optimization strings are presented to the end-user and hence are not
1264 * recompiled (or copy/pasted by such users), then the implementation of this box-function is
1265 * not needed for your custom type, as it is only invoked with method
1266 * \alib{expressions;Expression::GetOptimizedString}!
1267 */
1269{
1270 /**
1271 * Signature of the invokable function.
1272 *
1273 * @param constantValue The constant program value that is about to be written into
1274 * \p{expressionString}.
1275 * @param expressionString The expression string that is currently generated.
1276 */
1277 using Signature = void (*) ( const Box& constantValue, AString& expressionString );
1278};
1279
1280
1281/** ************************************************************************************************
1282 * The module class for module \alib_expressions_nl.
1283 *
1284 * This is a strict singleton class. The only instance found with namespace variable
1285 * \ref alib::EXPRESSIONS.
1286 **************************************************************************************************/
1288{
1289 public:
1290 /** ****************************************************************************************
1291 * Constructor.<br>
1292 * While this is public, it must not be invoked as this is a strict singleton type.
1293 * (See notes in \ref alib_manual_camp_modules_campmodule).
1294 ******************************************************************************************/
1295 Expressions();
1296
1297 protected:
1298 /** ****************************************************************************************
1299 * Initializes this module and namespace.
1300 *
1301 * @param phase The initialization phase to perform.
1302 ******************************************************************************************/
1303 virtual void bootstrap( BootstrapPhases phase ) override;
1304
1305 /** ****************************************************************************************
1306 * Terminates this module. (Nothing to do.)
1307 * @param phase The shutdown phase to perform.
1308 ******************************************************************************************/
1309 virtual void shutdown( ShutdownPhases phase ) override
1310 { (void) phase; }
1311
1312}; // class Expressions
1313
1314} // namespace alib[::expressions]
1315
1316/** The singleton instance of \alibcamp class \alib{expressions;Expressions}. */
1317extern ALIB_API expressions::Expressions EXPRESSIONS;
1318
1319} // namespace [alib]
1320
1322
1326
1334
1337
1338#endif // HPP_ALIB_EXPRESSIONS_EXPRESSIONS
virtual void bootstrap(BootstrapPhases phase) override
virtual void shutdown(ShutdownPhases phase) override
#define ALIB_ASSERT_MODULE(modulename)
Definition alib.hpp:190
#define ALIB_ENUMS_MAKE_BITWISE(TEnum)
Definition bitwise.hpp:120
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
Definition records.hpp:752
#define ALIB_API
Definition alib.hpp:538
#define ALIB_BOXING_VTABLE_DECLARE(TMapped, Identifier)
Definition vtable.inl:477
#define ALIB_ENUMS_MAKE_ARITHMETICAL(TEnum)
#define ALIB_RESOURCED_IN_MODULE(T, Camp, ResName)
std::vector< Box >::iterator ArgIterator
@ Positive
'+' operator (usually returns identity value).
@ Negative
'-' operator, negates a value.
@ Equals
Verbal alias "Equals" to operator '=='.
@ Or
Verbal alias "Or" to boolean or operator '||'.
@ SmEq
Verbal alias "Smeq" to operator '<='.
@ GtEq
Verbal alias "Gteq" to operator '>='.
@ And
Verbal alias "And" to boolean and operator '&&'.
@ BitOr
Binary or ('|'). "or"s all bits of two integral values. Precedence 450.
@ SmallerOrEqual
Smaller or equal operator ('<='). Precedence 600.
@ Divide
Arithmetic division ('/'). Precedence 900.
@ NotEqual
Not equal operator ('!='). Precedence 500.
@ Subtract
Arithmetic subtraction ('-'). Precedence 800.
@ BoolAnd
Boolean and ('&&'). Result is boolean. Precedence 440.
@ Modulo
Arithmetic modulo ('%'). Precedence 900.
@ BoolOr
Boolean or ('||'). Result is boolean. Precedence 430.
@ GreaterOrEqual
Greater or equal operator ('>='). Precedence 600.
@ BitXOr
Binary xor ('^'). "xor"s all bits of two integral values. Precedence 460.
@ Greater
Greater operator ('>'). Precedence 600.
@ Subscript
Array subscripting ('[]'). Precedence hardcoded with parser.
@ Smaller
Smaller operator ('<'). Precedence 600.
@ ShiftLeft
Bitwise shifting of integral values ('<<'). Precedence 700.
@ Multiply
Arithmetic multiplication ('*'). Precedence 900.
@ BitAnd
Binary and ('&'). "and"s all bits of two integral values. Precedence 470.
@ Add
Arithmetic addition ('+'). Precedence 800.
@ ShiftRight
Bitwise shifting of integral values ('>>'). Precedence 700.
@ Equal
Equal operator ('=='). Precedence 500.
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
@ NamedExpressionNotFound
Compile-time exception thrown when an expression refers to an unknown named nested expression.
Definition alib.cpp:57
ShutdownPhases
Definition camp.hpp:35
expressions::Expressions EXPRESSIONS
BootstrapPhases
Definition camp.hpp:26
lox::Scope Scope
Type alias in namespace alib.
boxing::Box Box
Type alias in namespace alib.
EROperatorAlias() noexcept=default
void(*)(const Box &constantValue, AString &expressionString) Signature
static ALIB_API Box * SS[2]
Function accepts two string arguments.
static ALIB_API Box * IVar[2]
Function accepts one integral argument, followed by variadic arguments.
static ALIB_API Box * D[1]
Function accepts a DateTime argument.
static ALIB_API Box * DDur[2]
Function accepts a DateTime argument; followed by a Duration .
static ALIB_API Box * B[1]
Function accepts one boolean argument.
static ALIB_API Box * Var[1]
Function accepts variadic arguments.
static ALIB_API Box * SII[3]
Function accepts one string argument, followed by two integral arguments.
static ALIB_API Box * SSI[3]
Function accepts two string arguments, followed by an integral argument.
static ALIB_API Box * II[2]
Function accepts two integral arguments.
static ALIB_API Box * SVar[2]
Function accepts one string argument, followed by variadic arguments.
static ALIB_API Box * BB[2]
Function accepts two boolean arguments.
static ALIB_API Box * SSB[3]
Function accepts two string arguments, followed by a boolean argument.
static ALIB_API Box * SSS[3]
Function accepts three string arguments.
static ALIB_API Box * SI[2]
Function accepts one string argument, followed by an integral argument.
static ALIB_API Box * F[1]
Function accepts one floating point argument.
static ALIB_API Box * Dur[1]
Function accepts a Duration argument.
static ALIB_API Box * S[1]
Function accepts one string argument.
static ALIB_API Box * FF[2]
Function accepts two floating point arguments.
static ALIB_API Box * I[1]
Function accepts one integral argument.
static ALIB_API Box DateTime
static ALIB_API Box Duration
static ALIB_API Box Void
static ALIB_API Box Integer
static ALIB_API Box Boolean
static ALIB_API Box String
static ALIB_API Box Float