ALib C++ Library
Library Version: 2402 R1
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
11#ifndef HPP_ALIB_EXPRESSIONS_EXPRESSIONS
13#endif
14
15#if ALIB_TIME && ALIB_DEBUG && !defined (HPP_ALIB_TIME_TICKS)
16# include "alib/time/ticks.hpp"
17#endif
18
19#if !defined (_GLIBCXX_MEMORY) && !defined(_MEMORY_)
20# include <memory>
21#endif
22
23namespace alib { namespace expressions {
24
25// forwards
26class Compiler;
27struct Scope;
28namespace detail{ class Program; class VirtualMachine; }
29
30/** ************************************************************************************************
31 * This is a central class of library module \alib_expressions_nl representing compiled,
32 * evaluatable expressions.
33 *
34 * The constructor is protected. Expressions are created using method
35 * \alib{expressions;Compiler::Compile}. The result of this method is a shared pointer
36 * \alib{expressions;SPExpression} which frees the user from the obligation to manage the life-cylce
37 * of \alib expressions.
38 *
39 * For information about general use and features of this class consult the
40 * \ref alib::expressions "ALib Expressions User Manual".
41 *
42 * ## Friends ##
43 * class \alib{expressions;Compiler}
44 * class \alib{expressions;detail::Program}
45 **************************************************************************************************/
47{
48 #if !defined(ALIB_DOX)
49 // The compiler builds this this type which by design does not expose a constructor.
50 friend class Compiler;
51
52 // The program that evaluates us.
53 friend class detail::Program;
54
55 // The program that evaluates us.
56 friend class detail::VirtualMachine;
57 #endif
58
59 protected:
60 /**
61 * Compile-time scope object. Used to allocate constant program object copies.
62 * Also passed to the compiler plug-ins for their use.
63 */
65
66 /** The name of the expression (if named, otherwise resourced, usually "ANONYMOUS" ). */
68
69 /** The compiled expression program. */
71
72 /** The original source string of the expression. */
74
75 /** The normalized string as a result of compilation. */
77
78 /** The normalized string generated on request out of optimized expression program. */
80
81 public:
82 #if ALIB_TIME && ALIB_DEBUG
83 /**
84 * Provides the time needed to parse the expression into an abstract syntax tree.
85 *
86 * Note: This field is available only with debug builds of the library.
87 */
88 Ticks::Duration DbgParseTime;
89
90 /**
91 * Provides the time needed to parse the expression into an abstract syntax tree.
92 *
93 * Note: This field is available only with debug builds of the library.
94 */
95 Ticks::Duration DbgAssemblyTime;
96
97 /**
98 * Provides the time needed for the last evaluation of the expression.
99 *
100 * Note: This field is available only with debug builds of the library.
101 */
102 Ticks::Duration DbgLastEvaluationTime;
103
104 #endif
105
106 protected:
107 /** ****************************************************************************************
108 * Protected constructor to disallow creation.
109 * Expressions are created using \alib{expressions;Compiler::Compile}.
110 * @param sourceString The original string that was parsed.
111 * @param pCTScope The compile-time scope.
112 ******************************************************************************************/
113 ALIB_API Expression( const String& sourceString, Scope* pCTScope );
114
115 public:
116 /** ****************************************************************************************
117 * Destructor.
118 ******************************************************************************************/
120
121 /** ****************************************************************************************
122 * The name of the expression. A name is only available if the expression was created with
123 * \alib{expressions;Compiler::AddNamed}. This might be 'automatically' done when nested
124 * expressions get compiled and the compiler supports retrieval of expression strings by
125 * name from some custom location (or built-in \alib configuration mechanics).
126 *
127 * Otherwise, the name is \b "ANONYMOUS", which is a resourced string of key
128 * \c "ANON_EXPR_NAME".
129 *
130 * @return The expression's name.
131 ******************************************************************************************/
133 String Name();
134
135 /** ****************************************************************************************
136 * Evaluates the expression by executing the compiled \p{program}.
137 *
138 * @return The result of this evaluation of this expression node.
139 ******************************************************************************************/
141
142 /** ****************************************************************************************
143 * Evaluates the expression by executing the compiled \p{program}.
144 *
145 * With debug builds of this library, \alib assertions may be raised.
146 * Usually this indicates that a native callback function returned a value of erroneous
147 * type, which usually are caused by erroneous compiler plug-ins, respectively the native
148 * callback functions that those provide.
149 *
150 * The assertion will most probably give detailed information.
151 *
152 * @param scope The evaluation scope.
153 * @return The result of this evaluation of this expression node.
154 ******************************************************************************************/
155 ALIB_API Box Evaluate(Scope& scope);
156
157
158 /** ****************************************************************************************
159 * Returns the originally given expression string.
160 *
161 * @return The original expression string.
162 ******************************************************************************************/
164 {
165 return originalString;
166 }
167
168 /** ****************************************************************************************
169 * Returns a normalized version of the original expression string.
170 *
171 * The result of normalization can be tweaked with the flags in field configuration field
172 * \alib{expressions;Compiler::CfgNormalization}. In any case, unnecessary (multiple)
173 * whitespaces and brackets are removed. Consult the documentation of enumeration
174 * \alib{expressions;Normalization} for details of the options.
175 *
176 * It is guaranteed that the normalized version of the expression string is parsable and
177 * leads to the identical evaluation program as the original expression string.
178 *
179 * Software might choose to write back normalized expressions, for example into
180 * configuration files.
181 *
182 * \note
183 * This method does not perform the normalization, but returns a normalized version of the
184 * parsed expression string, which was created with the compilation of the expression.
185 * A normalized string is always created.
186 *
187 * @return The normalized expression string.
188 ******************************************************************************************/
190 {
191 return normalizedString;
192 }
193
194 /** ****************************************************************************************
195 * Returns a normalized expression string reflecting an optimized version of this
196 * expression.
197 * The number of optimizations performed during compilation of the expression can be
198 * received by invoking
199 * \doxlinkproblem{classalib_1_1expressions_1_1detail_1_1Program.html;ad280346af2e021d0a6759401a683e16e;Program::CountOptimizations}
200 * on the program returned by #GetProgram. If this is \c 0, then the expression string
201 * returned here matches the normalized expression string received with
202 * #GetNormalizedString.
203 *
204 * \note
205 * On the first invocation, the string is generated once. For this, an abstract syntax
206 * tree is created by decompiling the optimized program. This in turn is assembled
207 * back to a program (by omitting the generation of commands and without invoking
208 * on compiler plug-ins, etc.) which generates the normalized expression string from the
209 * AST.
210 *
211 * @return The expression string requested.
212 ******************************************************************************************/
215
216
217 /** ****************************************************************************************
218 * Returns the program that evaluates the expression.
219 *
220 * @return The result of this evaluation of this expression node.
221 ******************************************************************************************/
223 {
224 return program;
225 }
226};
227
228
229/**
230 * As expressions are usually named and cached to enable nested expressions, but also shared
231 * as root expressions, and often encapsulated in more or less volatile custom objects, this shared
232 * pointer type is used to pass expression trees around. This manages their life-cycle
233 * automatically.
234 */
235using SPExpression= std::shared_ptr<Expression>;
236
237} // namespace alib[::expressions]
238
239/// Type alias in namespace \b alib.
241
242} // namespace [alib]
243
244
245namespace alib::strings {
246#if defined(ALIB_DOX)
247namespace APPENDABLES {
248#endif
249 /** ********************************************************************************************
250 * Specialization of functor \alib{strings;T_Append} for type
251 * \alib{expressions;Expression}.
252 **********************************************************************************************/
253 template<> struct T_Append<expressions::Expression,alib::character>
254 {
255 /**
256 * Appends the result of \alib{expressions;Expression::GetNormalizedString} to the
257 * \p{target}.
258 *
259 * @param target The \b AString that method \b Append was invoked on.
260 * @param src The expression to append.
261 */
262 void operator()( AString& target, const expressions::Expression& src )
263 {
264 target << src.GetNormalizedString();
265 }
266 };
267#if defined(ALIB_DOX)
268}
269#endif
270} // namespace [alib::strings]
271
272
273#endif // HPP_ALIB_EXPRESSIONS_EXPRESSION
ALIB_API Expression(const String &sourceString, Scope *pCTScope)
detail::Program * GetProgram()
Ticks::Duration DbgAssemblyTime
ALIB_API Box Evaluate(Scope &scope)
Ticks::Duration DbgLastEvaluationTime
ALIB_API String GetOptimizedString()
#define ALIB_API
Definition alib.hpp:538
std::shared_ptr< Expression > SPExpression
Definition alib.cpp:57
lox::Scope Scope
Type alias in namespace alib.
characters::character character
Type alias in namespace alib.
expressions::SPExpression SPExpression
Type alias in namespace alib.
expressions::Compiler Compiler
Type alias in namespace alib.
Definition compiler.hpp:596
void operator()(AString &target, const expressions::Expression &src)