ALib C++ Library
Library Version: 2511 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 /// Constructor creating a native function call exposed from an identifier, function
160 /// or operator.
161 /// @param callback The callback function.
162 /// @param isIdentifier If no parentheses were given, this has to be \c true.
163 /// Otherwise it is a function call.
164 /// @param qtyFunctionArgs The number of arguments that the callback function expects.
165 /// @param resultType The result type of the function.
166 /// @param functionOrOp The identifier, function or operator name/symbol.
167 /// This is used for de-compilation of programs.
168 /// @param isOperator If \c true an unary operator was compiled, a binary operator
169 /// otherwise.
170 /// @param idxOriginal Expression string index that imposed command.
171 /// @param idxNormalized Normalized expression string index that imposed command.
172 Command( CallbackDecl callback, bool isIdentifier, int qtyFunctionArgs,
173 const Box& resultType,
174 const String& functionOrOp, bool isOperator,
175 integer idxOriginal, integer idxNormalized )
176 : bits ( int16_t(OpCodes::Function)
177 | ( isOperator ? ( qtyFunctionArgs == 1 ? int16_t(ListingTypes::UnaryOp )
178 : int16_t(ListingTypes::BinaryOp) )
179 : ( isIdentifier ? int16_t(ListingTypes::Identifier )
180 : int16_t(ListingTypes::FunctionCall) ) ) )
181 , qtyArgs (uint16_t(qtyFunctionArgs) )
182 , Parameter (callback )
183 , ResultType (resultType )
184 , ExpressionPositions( (uinteger(idxNormalized) << (bitsof(integer)/2) )
185 + uinteger(idxOriginal ) )
186 , DecompileSymbol (functionOrOp ) {}
187
188 /// Constructor creating a subroutine call.
189 /// @param program The program to call.
190 /// @param resultType The result type of the program.
191 /// @param functionOrOp The function or operator that created the nested call.
192 /// @param idxOriginal Expression string index that imposed command.
193 /// @param idxNormalized Normalized expression string index that imposed command.
195 Command( Program* program, const Box& resultType, const String& functionOrOp,
196 integer idxOriginal, integer idxNormalized );
197
198 /// Constructor creating a jump. Note, the address is usually not known yet, hence not
199 /// provided.
200 /// @param jumpType The type of jump.
201 /// @param idxOriginal Expression string index that imposed command.
202 /// @param idxNormalized Normalized expression string index that imposed command.
203 Command( integer idxOriginal, integer idxNormalized, JumpType jumpType )
204 : bits (int16_t(jumpType == JumpType::Conditional ? OpCodes::JumpIfFalse : OpCodes::Jump ))
205 , Parameter (-1)
206 , ResultType(nullptr)
207 , ExpressionPositions( (uinteger(idxNormalized) << (bitsof(integer)/2) )
208 | uinteger(idxOriginal ) ) {}
209
210
211 /// Returns the opcode of this command.
212 /// @return The masked command part of the opcode.
213 constexpr OpCodes OpCode() const { return OpCodes(bits & Bits::CMD_MASK); }
214
215 /// Returns the decompile type of this command.
216 /// @return The masked command part of the opcode.
218
219 /// Returns \c true if the command represents a constant value, but is not the end
220 /// of a conditional jump.
221 /// @return \c true if the command represents a constant value, \c false otherwise.
224
225 /// Returns \c true if the command represents a conditional or unconditional jump.
226 /// @return \c true if the command represents a jump, \c false otherwise.
227 bool IsJump() const { return (bits & 4) == 4; }
228
229 /// Marks the command as the end of a conditional term.
231
232 /// @return \c true if the function has arguments, \c false otherwise.
233 bool HasArgs() const { return qtyArgs <= 0; }
234
235 /// @return \c true if the function has arguments, \c false otherwise.
236 bool IsIdentifier() const { return qtyArgs <= 0; }
237
238 /// @return The number of arguments of a function call.
239 int QtyArgs() const { return int(qtyArgs); }
240 }; // inner struct Command
241
242 /// Static method that runs an expression program.
243 /// @param program The program to run.
244 /// @param scope The scope to use.
245 /// @return The result value of the expression program.
246 ALIB_DLL static
247 alib::Box Run( Program& program, Scope& scope );
248
249 /// Static method that decompiles a program into an abstract syntax tree.
250 /// Used to generate optimized, normalized, parsable expression strings.
251 /// @param program The program to decompile.
252 /// @param allocator Allocator for AST objects (and their data).
253 /// @return The abstract syntax tree as a result of de-compilation.
254 ALIB_DLL static
255 AST* Decompile( Program& program, MonoAllocator& allocator );
256
257
258 #if ALIB_DEBUG
259 /// Lists a virtual machine program.
260 ///
261 /// Note: This method is available only with debug-builds of the library.
262 /// @param program The program to list.
263 /// @return The program listing.
264 ALIB_DLL static
265 AString DbgList( Program& program );
266
267 #endif
268
269 /// The implementation of #Run, which itself is just initialization code.
270 /// @param program The program to run.
271 /// @param scope The scope to use.
272 ALIB_DLL static
273 void run( Program& program, Scope& scope );
274
275}; // struct VirtualMachine
276
277} // namespace [alib::expressions::detail]
278
280#if ALIB_DEBUG
282#endif
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:1435
#define ALIB_DLL
Definition alib.inl:503
#define ALIB_ENUMS_ASSIGN_RECORD(TEnum, TRecord)
#define ALIB_BOXING_VTABLE_DECLARE(TMapped, Identifier)
#define ALIB_EXPORT
Definition alib.inl:497
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:1149
strings::TString< character > String
Type alias in namespace alib.
Definition string.inl:2189
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:525
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.