ALib C++ Library
Library Version: 2412 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
expression.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_EXPRESSION
9#define HPP_ALIB_EXPRESSIONS_EXPRESSION
10#pragma once
12
13#if ALIB_TIME && ALIB_DEBUG
14# include "alib/time/ticks.hpp"
15#endif
18#include <memory>
19
20namespace alib { namespace expressions {
21
22// forwards
23class Compiler;
24struct Scope;
25namespace detail{ class Program; struct VirtualMachine; }
26
27//==================================================================================================
28/// This is a central class of library module \alib_expressions_nl representing compiled,
29/// evaluable expressions.
30///
31/// The constructor is protected. Expressions are created using method
32/// \alib{expressions;Compiler::Compile}. The result of this method is a shared pointer
33/// \alib{expressions;Expression} which frees the user from the obligation to manage the life-cylce
34/// of \alib expressions.
35///
36/// For information about general use and features of this class consult the
37/// \ref alib::expressions "ALib Expressions User Manual".
38///
39/// ## Friends ##
40/// class \alib{expressions;Compiler}
41/// class \alib{expressions;detail::Program}
42//==================================================================================================
44{
45 #if !DOXYGEN
46 // The compiler that compiles us.
47 friend class Compiler;
48
49 // The program that evaluates us.
50 friend class detail::Program;
51
52 // The virtual machine our program runs on.
53 friend struct detail::VirtualMachine;
54 #endif
55
56 protected:
57 /// The allocator, provided with construction.
58 /// This usually is the 'self-contained' instance of type \alib{expressions;Expression}.
59 /// This allocator is forwarded to the #ctScope and
60 /// \alib{monomem::TMonoAllocator;DbgLock;locked} after compilation.
62
63 /// Compile-time scope object. Used to allocate constant program object copies.
64 /// Also passed to the compiler plug-ins during compilation to add pre-calculated
65 /// data.
67
68 /// The name of the expression (if named, otherwise resourced, usually "ANONYMOUS" ).
70
71 /// The compiled expression program.
73
74 /// The original source string of the expression.
76
77 /// The normalized string as a result of compilation.
79
80 /// The normalized string generated on request out of optimized expression program.
82
83 public:
84 #if ALIB_TIME && ALIB_DEBUG
85 /// Provides the time needed to parse the expression into an abstract syntax tree.
86 ///
87 /// Note: This field is available only with debug-builds of the library.
88 Ticks::Duration DbgParseTime;
89
90 /// Provides the time needed to parse the expression into an abstract syntax tree.
91 ///
92 /// Note: This field is available only with debug-builds of the library.
93 Ticks::Duration DbgAssemblyTime;
94
95 /// Provides the time needed for the last evaluation of the expression.
96 ///
97 /// Note: This field is available only with debug-builds of the library.
98 Ticks::Duration DbgLastEvaluationTime;
99
100 #endif
101
102 public:
103 //==========================================================================================
104 /// Constructor.
105 /// Expressions are created using \alib{expressions;Compiler::Compile} and thus, this
106 /// constructor is available for the compiler only.
107 /// \note
108 /// The common way to assert accessibility would be to make this constructor protected
109 /// and make class \b Compiler a friend. This is not possible, as this type is
110 /// to be constructed by container type \alib{containers;SharedVal}. Therefore, an
111 /// unused parameter of a protected type has to be passed, which can be created only
112 /// by friend \b Compiler.
113 ///
114 /// @param allocator The allocator to use. Usually this is the self-contained allocator
115 /// of type \alib{expressions;Expression}
116 /// @param sourceString The original string that is to be compiled.
117 /// @param pCTScope The compile-time scope.
118 //==========================================================================================
120 const String& sourceString,
121 Scope* pCTScope );
122
123 //==========================================================================================
124 /// Destructor.
125 //==========================================================================================
127
128 //==========================================================================================
129 /// The name of the expression. A name is only available if the expression was created with
130 /// \alib{expressions;Compiler::AddNamed}. This might be 'automatically' done when nested
131 /// expressions get compiled and the compiler supports retrieval of expression strings by
132 /// name from some custom location (or built-in \alib configuration mechanics).
133 ///
134 /// Otherwise, the name is \b "ANONYMOUS", which is a resourced string of key
135 /// \c "ANON_EXPR_NAME".
136 ///
137 /// @return The expression's name.
138 //==========================================================================================
140 String Name();
141
142 //==========================================================================================
143 /// Evaluates the expression by executing the compiled \p{program}.
144 ///
145 /// @return The result of this evaluation of this expression node.
146 //==========================================================================================
148
149 //==========================================================================================
150 /// Evaluates the expression by executing the compiled \p{program}.
151 ///
152 /// With debug-builds of this library, \alib assertions may be raised.
153 /// Usually this indicates that a native callback function returned a value of erroneous
154 /// type, which usually are caused by erroneous compiler plug-ins, respectively the native
155 /// callback functions that those provide.
156 ///
157 /// The assertion will most probably give detailed information.
158 ///
159 /// @param scope The evaluation scope.
160 /// @return The result of this evaluation of this expression node.
161 //==========================================================================================
162 ALIB_API Box Evaluate(Scope& scope);
163
164
165 //==========================================================================================
166 /// Returns the originally given expression string.
167 ///
168 /// @return The original expression string.
169 //==========================================================================================
171
172 //==========================================================================================
173 /// Returns a normalized version of the original expression string.
174 ///
175 /// The result of normalization can be tweaked with the flags in field configuration field
176 /// \alib{expressions;Compiler::CfgNormalization}. In any case, unnecessary (multiple)
177 /// whitespaces and brackets are removed. Consult the documentation of enumeration
178 /// \alib{expressions;Normalization} for details of the options.
179 ///
180 /// It is guaranteed that the normalized version of the expression string is parsable and
181 /// leads to the identical evaluation program as the original expression string.
182 ///
183 /// Software might choose to write back normalized expressions, for example into
184 /// configuration files.
185 ///
186 /// \note
187 /// This method does not perform the normalization, but returns a normalized version of the
188 /// parsed expression string, which was created with the compilation of the expression.
189 /// A normalized string is always created.
190 ///
191 /// @return The normalized expression string.
192 //==========================================================================================
194
195 //==========================================================================================
196 /// Returns a normalized expression string reflecting an optimized version of this
197 /// expression.
198 /// The number of optimizations performed during compilation of the expression can be
199 /// received by invoking
200 /// \doxlinkproblem{classalib_1_1expressions_1_1detail_1_1Program.html;ad280346af2e021d0a6759401a683e16e;Program::CountOptimizations}
201 /// on the program returned by #GetProgram. If this is \c 0, then the expression string
202 /// returned here matches the normalized expression string received with
203 /// #GetNormalizedString.
204 ///
205 /// \note
206 /// On the first invocation, the string is generated once. For this, an abstract syntax
207 /// tree is created by decompiling the optimized program. This in turn is assembled
208 /// back to a program (by omitting the generation of commands and without invoking
209 /// on compiler plug-ins, etc.) which generates the normalized expression string from the
210 /// AST.
211 ///
212 /// @return The expression string requested.
213 //==========================================================================================
216
217
218 //==========================================================================================
219 /// Returns the program that evaluates the expression.
220 ///
221 /// @return The result of this evaluation of this expression node.
222 //==========================================================================================
224 {
225 return program;
226 }
227};
228
229
230
231/// Implements \alib{monomem;TSharedMonoVal} with type \alib{expressions;ExpressionVal}.
232/// Therefore, the relevant documentation is found with class \alib{expressions;ExpressionVal},
233/// which can be accessed through this type using <c>operator->()</c>.
234///
235/// The result of combining both is an automatic pointer to a \b %ExpressionVal that is
236/// "self-contained" in the first buffer of a \alib{MonoAllocator} together with the
237/// allocator itself.
238/// The expression is deleted and all associated memory is freed when the last copy of the pointer
239/// goes out of scope.
240///
241/// \note
242/// With the documentation of type \b %TSharedMonoVal,
243/// \ref alib_contmono_smv_naming "two naming schemes" are suggested.
244/// Here, the second scheme is used because the method \alib{expressions;Compiler::Compile}
245/// will always return this encapsulated object. Expressions are shared by definition.
246struct Expression : public monomem::TSharedMonoVal<ExpressionVal, HeapAllocator, void>
247{
248 protected:
249 /// The compiler builds this type which by design does not expose a constructor.
250 friend class Compiler;
251
252 #if DOXYGEN
253 /// Forbid this method by making it protected.
254 /// @tparam TArgs The argument types used for re-constructing \p{T}.
255 /// @param args The arguments to re-construct the instance of \p{T}.
256 template<typename... TArgs>
257 void Reset( TArgs&&... args );
258 #else
260 #endif
261
262 /// Constructor.
263 /// Calls the constructor of parent \b TSharedMonoVal and then invokes
264 /// \alib{monomem;TSharedMonoVal::ConstructT} passing the mono allocator that the
265 /// parent creates this instance in.
266 /// @param initialBufferSizeInKB The initial size of memory buffers.
267 /// Passed to the allocator given with parent class
268 /// \alib{monomem;TSharedMonoVal}.<br>
269 /// @param bufferGrowthInPercent Optional growth factor in percent, applied to the buffer size
270 /// with each next buffer allocation.
271 Expression( size_t initialBufferSizeInKB, unsigned int bufferGrowthInPercent )
272 : TSharedMonoVal(initialBufferSizeInKB, bufferGrowthInPercent ) {}
273
274 public:
275 /// Constructs an empty instance, hence a cleared automatic pointer.
276 Expression() = default;
277
278 /// Constructs an empty instance from \c std::nullptr.
279 /// This constructor is necessary to allow assignment of \c nullptr to values of this type,
280 /// which clears the automatic pointer.
281 Expression(std::nullptr_t) noexcept {}
282
283}; // struct Expression
284
285} // namespace alib[::expressions]
286
287/// Type alias in namespace \b alib.
289
290} // namespace [alib]
291
292
293namespace alib::strings {
294#if DOXYGEN
295namespace APPENDABLES {
296#endif
297 //==============================================================================================
298 /// Specialization of functor \alib{strings;T_Append} for type
299 /// \alib{expressions;ExpressionVal}.
300 //==============================================================================================
301 template<> struct T_Append<expressions::ExpressionVal,alib::character, lang::HeapAllocator>
302 {
303 /// Appends the result of \alib{expressions;ExpressionVal::GetNormalizedString} to the
304 /// \p{target}.
305 ///
306 /// @param target The \b AString that method \b Append was invoked on.
307 /// @param src The expression to append.
309 {
310 target << src.GetNormalizedString();
311 }
312 };
313 //==============================================================================================
314 /// Specialization of functor \alib{strings;T_Append} for type
315 /// \alib{expressions;Expression}.
316 //==============================================================================================
318 {
319 /// Appends the result of \alib{expressions;ExpressionVal::GetNormalizedString} to the
320 /// \p{target}.
321 ///
322 /// @param target The \b AString that method \b Append was invoked on.
323 /// @param src The expression to append.
324 void operator()( AString& target, const expressions::Expression& src )
325 {
326 target << src->GetNormalizedString();
327 }
328 };
329
330#if DOXYGEN
331}
332#endif
333} // namespace [alib::strings]
334
335
336#endif // HPP_ALIB_EXPRESSIONS_EXPRESSION
337
ALIB_API ExpressionVal(MonoAllocator &allocator, const String &sourceString, Scope *pCTScope)
String originalString
The original source string of the expression.
detail::Program * program
The compiled expression program.
ALIB_API Box Evaluate(Scope &scope)
Ticks::Duration DbgLastEvaluationTime
String name
The name of the expression (if named, otherwise resourced, usually "ANONYMOUS" ).
AString optimizedString
The normalized string generated on request out of optimized expression program.
AString normalizedString
The normalized string as a result of compilation.
ALIB_API String GetOptimizedString()
ALIB_API ~ExpressionVal()
Destructor.
void Reset(TArgs &&... args)
#define ALIB_API
Definition alib.hpp:639
Definition alib.cpp:69
lox::Scope Scope
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
Definition compiler.hpp:553
Expression()=default
Constructs an empty instance, hence a cleared automatic pointer.
Expression(std::nullptr_t) noexcept
Expression(size_t initialBufferSizeInKB, unsigned int bufferGrowthInPercent)
void Reset(TArgs &&... args)