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