ALib C++ Library
Library Version: 2510 R0
Documentation generated by doxygen
Loading...
Searching...
No Matches
virtualmachine.inl
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-2025 A-Worx GmbH, Germany.
6/// Published under \ref mainpage_license "Boost Software License".
7//==================================================================================================
8
10
11//==================================================================================================
12/// This type implements a very simple stack machine that understands just four commands (!) plus
13/// a fifth to execute sub-programs.
14///
15/// This class is part of module \alib_expressions_nl. It is not too well documented as it
16/// resides in a \c detail namespace and is not to be used from the outside expression API.
17//==================================================================================================
19{
20 /// Type definition for a program counter.
21 using PC = integer;
22
23 /// A command of the VM.
24 class Command
25 {
26 public:
27 /// Some meanings and masks of field #bits.
28 enum Bits
29 {
30 CMD_MASK = 0x07, ///< Used to mask the command out of an opcode.
31 FlagEOC = 0x08, ///< Flags a command to be the last of a conditional.
32 CMD_MASK_WITH_EOC = 0x0F, ///< Used to mask the command out of an opcode,
33 ///< including the EOC flag.
34 TYPE_MASK = 0xF0 ///< The mask for the \b ListingTypes.
35 };
36
37 /// The opcode type of VM commands.
39 {
40 Constant = 0, ///< Pushes a constant to the stack.
41 Function = 1, ///< Invokes a C++ callback function.
42 Subroutine = 2, ///< Invokes another program.
43
44 // leaving out one, so that jumps have bit 3 set.
45 JumpIfFalse = 4, ///< Jumps if top of the stack indicates \c false.
46 Jump = 5, ///< Jumps.
47 };
48
49 /// Denotes the type of parsing de-compilation information attached to the command.
51 {
52 LiteralConstant = 0x00, ///< Command results from a literal constant.
53 OptimizationConstant= 0x10, ///< Command results from a constant resulting from an optimization.
54 UnaryOp = 0x20, ///< Command results from an unary operator.
55 BinaryOp = 0x30, ///< Command results from a binary operator.
56 Identifier = 0x40, ///< Command results from a function call with no parenthesis given.
57 FunctionCall = 0x50, ///< Command results from a function call.
58 AutoCast = 0x60, ///< Command results from an automatically inserted cast.
59 NestedExpression = 0x70, ///< Command results from a nested expression.
60 };
61
62 /// Denotes the two different jump types (used only as parameter, not stored.)
63 enum class JumpType
64 {
65 Conditional, ///< Denotes \b %JumpIfFalse.
66 Unconditional, ///< Denotes \b %Jump.
67 };
68
69
70 #if ALIB_DEBUG
71 /// Provides additional debug information for a command.
72 /// Available only with debug-builds of the library.
73 /// Used with \alib{expressions::detail;VirtualMachine::DbgList}
75 {
76 /// The plug-in that provided the callback or constant.
78
79 /// The native C++ name of the callback function.
80 const char* Callback;
81 };
82 #endif
83
84 /// A union of different parameter types for the commands.
86 {
87 PC Distance; ///< A distance to jump
88 CallbackDecl Callback; ///< A C++ callback function to invoke.
89 Program* NestedProgram; ///< The nested virtual machine program to invoke.
90
91 /// Default constructor leaving this instance uninitialized.
93
94 /// Union constructor.
95 /// @param distance Stored in #Distance.
96 OperationParam( integer distance ) : Distance(distance) {}
97
98 /// Union constructor.
99 /// @param callback Stored in #Callback.
100 OperationParam( CallbackDecl callback ) : Callback(callback) {}
101
102 /// Union constructor.
103 /// @param program Stored in #NestedProgram.
104 OperationParam ( Program* program) : NestedProgram(program) {}
105 };
106
107 protected:
108 /// Operation code of this command.
109 int16_t bits;
110
111 /// The number of function args.
112 /// If negative, this indicates that the function name was given as an 'identifier',
113 /// what means that no brackets '()' had been added. This piece of information (namely
114 /// having a signed integer here which allows differentiating between \c 0 and a negative
115 /// number of arguments) is used when decompiling a program back to an expression
116 /// string. Hence, this piece of it logically belongs to #ListingTypes.
117 uint16_t qtyArgs;
118
119 public:
120 /// The parameter of the operation.
122
123 /// With every command, this box contains the result type.
124 /// For constants, also the commands' value is contained.
126
127 /// This encodes both, the position in the original and in the normalized expression
128 /// string that resulted in this command.
129 /// Used for generation of exception information and debug listings.
131
132
133 /// The operator symbol or function name used with de-compilation to recreate an
134 /// expression string.
136
137
138 #if ALIB_DEBUG
139 /// Operation code of this command. Available only with debug-builds.
141 #endif
142
143 /// Constructor creating a constant.
144 /// @param value The constant to add.
145 /// @param isOptimization Denotes if the constant results from an optimization or
146 /// from a literal of the expression string.
147 /// @param idxOriginal Expression string index that imposed command.
148 /// @param idxNormalized Normalized expression string index that imposed command.
149 Command( const Box& value, bool isOptimization,
150 integer idxOriginal, integer idxNormalized )
151 : bits ( int16_t(OpCodes::Constant)
152 | ( isOptimization ? int16_t(ListingTypes::OptimizationConstant)
153 : int16_t(ListingTypes::LiteralConstant ) ) )
154 , ResultType(value)
155 , ExpressionPositions( (uinteger(idxNormalized) << (bitsof(integer)/2) )
156 + uinteger(idxOriginal ) )
157 {}
158
159
160 /// Constructor creating a native function call exposed from an identifier, function
161 /// or operator.
162 /// @param callback The callback function.
163 /// @param isIdentifier If no parentheses were given, this has to be \c true.
164 /// Otherwise it is a function call.
165 /// @param qtyFunctionArgs The number of arguments that the callback function expects.
166 /// @param resultType The result type of the function.
167 /// @param functionOrOp The identifier, function or operator name/symbol.
168 /// This is used for de-compilation of programs.
169 /// @param isOperator If \c true an unary operator was compiled, a binary operator
170 /// otherwise.
171 /// @param idxOriginal Expression string index that imposed command.
172 /// @param idxNormalized Normalized expression string index that imposed command.
173 Command( CallbackDecl callback, bool isIdentifier, int qtyFunctionArgs,
174 const Box& resultType,
175 const String& functionOrOp, bool isOperator,
176 integer idxOriginal, integer idxNormalized )
177 : bits ( int16_t(OpCodes::Function)
178 | ( isOperator ? ( qtyFunctionArgs == 1 ? int16_t(ListingTypes::UnaryOp )
179 : int16_t(ListingTypes::BinaryOp) )
180 : ( isIdentifier ? int16_t(ListingTypes::Identifier )
181 : int16_t(ListingTypes::FunctionCall) ) ) )
182 , qtyArgs (uint16_t(qtyFunctionArgs) )
183 , Parameter (callback )
184 , ResultType (resultType )
185 , ExpressionPositions( (uinteger(idxNormalized) << (bitsof(integer)/2) )
186 + uinteger(idxOriginal ) )
187 , DecompileSymbol (functionOrOp )
188 {}
189
190 /// Constructor creating a subroutine call.
191 /// @param program The program to call.
192 /// @param resultType The result type of the program.
193 /// @param functionOrOp The function or operator that created the nested call.
194 /// @param idxOriginal Expression string index that imposed command.
195 /// @param idxNormalized Normalized expression string index that imposed command.
197 Command( Program* program, const Box& resultType, const String& functionOrOp,
198 integer idxOriginal, integer idxNormalized );
199
200 /// Constructor creating a jump. Note, the address is usually not known yet, hence not
201 /// provided.
202 /// @param jumpType The type of jump.
203 /// @param idxOriginal Expression string index that imposed command.
204 /// @param idxNormalized Normalized expression string index that imposed command.
205 Command( integer idxOriginal, integer idxNormalized, JumpType jumpType )
206 : bits (int16_t(jumpType == JumpType::Conditional ? OpCodes::JumpIfFalse : OpCodes::Jump ))
207 , Parameter (-1)
208 , ResultType(nullptr)
209 , ExpressionPositions( (uinteger(idxNormalized) << (bitsof(integer)/2) )
210 | uinteger(idxOriginal ) )
211 {}
212
213
214 /// Returns the opcode of this command.
215 /// @return The masked command part of the opcode.
216 constexpr OpCodes OpCode() const { return OpCodes(bits & Bits::CMD_MASK); }
217
218 /// Returns the decompile type of this command.
219 /// @return The masked command part of the opcode.
221
222 /// Returns \c true if the command represents a constant value, but is not the end
223 /// of a conditional jump.
224 /// @return \c true if the command represents a constant value, \c false otherwise.
227
228 /// Returns \c true if the command represents a conditional or unconditional jump.
229 /// @return \c true if the command represents a jump, \c false otherwise.
230 bool IsJump() const { return (bits & 4) == 4; }
231
232 /// Marks the command as the end of a conditional term.
234
235 /// @return \c true if the function has arguments, \c false otherwise.
236 bool HasArgs() const { return qtyArgs <= 0; }
237
238 /// @return \c true if the function has arguments, \c false otherwise.
239 bool IsIdentifier() const { return qtyArgs <= 0; }
240
241 /// @return The number of arguments of a function call.
242 int QtyArgs() const { return int(qtyArgs); }
243 }; // inner struct Command
244
245 //==============================================================================================
246 /// Static method that runs an expression program.
247 /// @param program The program to run.
248 /// @param scope The scope to use.
249 /// @return The result value of the expression program.
250 //==============================================================================================
251 ALIB_DLL static
252 alib::Box Run( Program& program, Scope& scope );
253
254 //==============================================================================================
255 /// Static method that decompiles a program into an abstract syntax tree.
256 /// Used to generate optimized, normalized, parsable expression strings.
257 /// @param program The program to decompile.
258 /// @param allocator Allocator for AST objects (and their data).
259 /// @return The abstract syntax tree as a result of de-compilation.
260 //==============================================================================================
261 ALIB_DLL static
262 AST* Decompile( Program& program, MonoAllocator& allocator );
263
264
265 #if ALIB_DEBUG
266 //==========================================================================================
267 /// Lists a virtual machine program.
268 ///
269 /// Note: This method is available only with debug-builds of the library.
270 /// @param program The program to list.
271 /// @return The program listing.
272 //==========================================================================================
273 ALIB_DLL static
274 AString DbgList( Program& program );
275
276 #endif
277
278 //==============================================================================================
279 /// The implementation of #Run, which itself is just initialization code.
280 /// @param program The program to run.
281 /// @param scope The scope to use.
282 //==============================================================================================
283 ALIB_DLL static
284 void run( Program& program, Scope& scope );
285
286}; // struct VirtualMachine
287
288} // namespace [alib::expressions::detail]
289
291#if ALIB_DEBUG
293#endif
294
JumpType
Denotes the two different jump types (used only as parameter, not stored.)
void SetEndOfConditionalFlag()
Marks the command as the end of a conditional term.
ListingTypes
Denotes the type of parsing de-compilation information attached to the command.
@ Identifier
Command results from a function call with no parenthesis given.
@ LiteralConstant
Command results from a literal constant.
@ FunctionCall
Command results from a function call.
@ BinaryOp
Command results from a binary operator.
@ UnaryOp
Command results from an unary operator.
@ AutoCast
Command results from an automatically inserted cast.
@ NestedExpression
Command results from a nested expression.
@ OptimizationConstant
Command results from a constant resulting from an optimization.
DbgInformation DbgInfo
Operation code of this command. Available only with debug-builds.
Command(CallbackDecl callback, bool isIdentifier, int qtyFunctionArgs, const Box &resultType, const String &functionOrOp, bool isOperator, integer idxOriginal, integer idxNormalized)
Command(integer idxOriginal, integer idxNormalized, JumpType jumpType)
OperationParam Parameter
The parameter of the operation.
@ JumpIfFalse
Jumps if top of the stack indicates false.
Command(const Box &value, bool isOptimization, integer idxOriginal, integer idxNormalized)
int16_t bits
Operation code of this command.
Bits
Some meanings and masks of field bits.
@ FlagEOC
Flags a command to be the last of a conditional.
@ CMD_MASK
Used to mask the command out of an opcode.
#define bitsof(type)
Definition alib.inl:1418
#define ALIB_DLL
Definition alib.inl:496
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
#define ALIB_BOXING_VTABLE_DECLARE(TMapped, Identifier)
#define ALIB_EXPORT
Definition alib.inl:488
Box(*)(Scope &scope, ArgIterator argsBegin, ArgIterator argsEnd) CallbackDecl
strings::TAString< character, lang::HeapAllocator > AString
Type alias in namespace alib.
lang::integer integer
Type alias in namespace alib.
Definition integers.inl:149
monomem::TMonoAllocator< lang::HeapAllocator > MonoAllocator
boxing::Box Box
Type alias in namespace alib.
Definition box.inl:1216
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2381
lang::uinteger uinteger
Type alias in namespace alib.
Definition integers.inl:152
Base class exported by the main module ALib.Expressions.H for technical reasons.
Definition compiler.inl:559
CompilerPlugin * Plugin
The plug-in that provided the callback or constant.
const char * Callback
The native C++ name of the callback function.
static ALIB_DLL AST * Decompile(Program &program, MonoAllocator &allocator)
static ALIB_DLL alib::Box Run(Program &program, Scope &scope)
static ALIB_DLL void run(Program &program, Scope &scope)
static ALIB_DLL AString DbgList(Program &program)
integer PC
Type definition for a program counter.
A union of different parameter types for the commands.
CallbackDecl Callback
A C++ callback function to invoke.
OperationParam()
Default constructor leaving this instance uninitialized.
Program * NestedProgram
The nested virtual machine program to invoke.