File indexing completed on 2025-01-19 06:38:35
0001 /* 0002 SPDX-FileCopyrightText: 2003-2006 Cies Breijs <cies AT kde DOT nl> 0003 0004 SPDX-License-Identifier: GPL-2.0-or-later 0005 */ 0006 0007 #ifndef _EXECUTER_H_ 0008 #define _EXECUTER_H_ 0009 0010 #include <QHash> 0011 #include <QObject> 0012 #include <QStack> 0013 0014 0015 #include "errormsg.h" 0016 #include "token.h" 0017 #include "treenode.h" 0018 0019 0020 0021 // some typedefs and a struct for the template classes used: 0022 0023 typedef QHash<QString, Value> VariableTable; 0024 typedef QHash<QString, TreeNode*> FunctionTable; 0025 typedef struct { 0026 TreeNode* function; // pointer to the node of the function caller 0027 VariableTable* variableTable; // pointer to the variable table of the function 0028 } CalledFunction; 0029 typedef QStack<CalledFunction> FunctionStack; 0030 0031 0032 0033 /** 0034 * @short Step-wise execution of a node tree, collecting errors in the ErrorList. 0035 * 0036 * The Executer 'executes' the node tree, as yielded by the Parser, step by step. 0037 * When errors occur they are put in the ErrorList as supplied to the constructor. 0038 * 0039 * The Executer has a globalVariableTable where is stores the content of variables, 0040 * and a functionTable that contains pointer to the 'learned' functions. 0041 * When running into a function a local variable table and a pointer to the 0042 * functionCallNode are put onto the functionStack. 0043 * 0044 * Executer inherits from QObject for the SIGNALS/SLOTS mechanism. 0045 * Signals are emitted for all external things the Executer has to trigger (like 0046 * drawing). 0047 * 0048 * A large part of the code of this class is generated code. 0049 * 0050 * @author Cies Breijs 0051 */ 0052 class Executer : public QObject 0053 { 0054 Q_OBJECT 0055 0056 public: 0057 /** 0058 * @short Constructor. Initialses the Executer. 0059 * does nothing special. @see initialize(). 0060 */ 0061 explicit Executer(bool testing = false) : m_testing(testing) {} 0062 /** 0063 * @short Destructor. Does nothing at special. 0064 */ 0065 ~Executer() override {} 0066 0067 0068 /** 0069 * @short Initialses (resets) the Executer. 0070 * @param tree pointer to the base node of the tree as provided 0071 * by the Parser 0072 * @param errorList pointer to a QList for ErrorMessage objects, when 0073 * error occur they will be stored here 0074 */ 0075 void initialize(TreeNode* tree, ErrorList* _errorList); 0076 0077 /** 0078 * @short Executes one 'step' (usually a TreeNode). 0079 * This methods scans over the node tree to find the next TreeNode to 0080 * execute, and executes it. It starts by the leafs, and works it way to 0081 * the root. @see isFinished 0082 */ 0083 void execute(); 0084 0085 /** 0086 * @short Reflects if the Executer has finished executing the node tree. 0087 * @return TRUE when execution has finished, otherwise FALSE. 0088 */ 0089 bool isFinished() const { return finished; } 0090 0091 0092 private Q_SLOTS: 0093 /// Used by the singleshot wait timer. 0094 void stopWaiting() { waiting = false; } 0095 0096 0097 private: 0098 /// Executes a single TreeNode, mainly a switch to the individual executer* functions. 0099 void execute(TreeNode* node); 0100 0101 /// Adds an error to the error list. 0102 void addError(const QString& s, const Token& t, int code); 0103 0104 /// Checks the parameter quantity of @p n matches @p quantity, if not it adds an error with @p errorCode 0105 bool checkParameterQuantity(TreeNode* n, uint quantity, int errorCode); 0106 0107 /// Checks the types of @p n 's parameters match the type @p valueType, if not it adds an error with @p errorCode 0108 bool checkParameterType(TreeNode* n, int valueType, int errorCode); 0109 0110 /// @returns the variable table of the current function, or the globalVariableTable if not running in a function 0111 VariableTable* currentVariableTable(); 0112 0113 0114 0115 /// QHash containing pointers to the 'learned' functions 0116 FunctionTable functionTable; 0117 0118 /// QHash containing the global variables 0119 VariableTable globalVariableTable; 0120 0121 /// Stores both pointers to functionNodes and accompanying local variable table using the predefined struct. 0122 FunctionStack functionStack; 0123 0124 /// Pointer to the error list as supplied to the constructor 0125 ErrorList *errorList; 0126 0127 0128 0129 /// Pointer to the root node of the tree 0130 TreeNode* rootNode; 0131 0132 /// This points to a scope node when we have to get into a new scope, otherwise it should be zero 0133 TreeNode* newScope; 0134 0135 /// This point to the current node in the tree 0136 TreeNode* currentNode; 0137 0138 /// Zero except when returning from a function 0139 Value* returnValue; 0140 0141 /// TRUE when execution has finished 0142 bool finished; 0143 0144 /// TRUE when execution is waiting 0145 bool waiting; 0146 0147 /// TRUE when breaking from a loop 0148 bool breaking; 0149 0150 /// TRUE when returning from a function 0151 bool returning; 0152 0153 /// TRUE when the next call of execute() should straight execute the current node (not walk the tree first) 0154 bool executeCurrent; 0155 0156 bool m_testing; 0157 0158 0159 0160 // Next you find individual execute functions as generated: 0161 0162 //BEGIN GENERATED executer_h CODE 0163 0164 /* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED" 0165 * is generated by "generate.rb" according to the definitions specified in 0166 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all 0167 * all change you make here will be overwritten the next time "generate.rb" is run. 0168 * Thanks for looking at the code! 0169 */ 0170 0171 void executeRoot(TreeNode* node); 0172 void executeScope(TreeNode* node); 0173 void executeVariable(TreeNode* node); 0174 void executeFunctionCall(TreeNode* node); 0175 void executeExit(TreeNode* node); 0176 void executeIf(TreeNode* node); 0177 void executeElse(TreeNode* node); 0178 void executeRepeat(TreeNode* node); 0179 void executeWhile(TreeNode* node); 0180 void executeFor(TreeNode* node); 0181 void executeForTo(TreeNode* node); 0182 void executeBreak(TreeNode* node); 0183 void executeReturn(TreeNode* node); 0184 void executeWait(TreeNode* node); 0185 void executeAssert(TreeNode* node); 0186 void executeAnd(TreeNode* node); 0187 void executeOr(TreeNode* node); 0188 void executeNot(TreeNode* node); 0189 void executeEquals(TreeNode* node); 0190 void executeNotEquals(TreeNode* node); 0191 void executeGreaterThan(TreeNode* node); 0192 void executeLessThan(TreeNode* node); 0193 void executeGreaterOrEquals(TreeNode* node); 0194 void executeLessOrEquals(TreeNode* node); 0195 void executeAddition(TreeNode* node); 0196 void executeSubtraction(TreeNode* node); 0197 void executeMultiplication(TreeNode* node); 0198 void executeDivision(TreeNode* node); 0199 void executePower(TreeNode* node); 0200 void executeAssign(TreeNode* node); 0201 void executeLearn(TreeNode* node); 0202 void executeArgumentList(TreeNode* node); 0203 void executeReset(TreeNode* node); 0204 void executeClear(TreeNode* node); 0205 void executeCenter(TreeNode* node); 0206 void executeGo(TreeNode* node); 0207 void executeGoX(TreeNode* node); 0208 void executeGoY(TreeNode* node); 0209 void executeForward(TreeNode* node); 0210 void executeBackward(TreeNode* node); 0211 void executeDirection(TreeNode* node); 0212 void executeTurnLeft(TreeNode* node); 0213 void executeTurnRight(TreeNode* node); 0214 void executePenWidth(TreeNode* node); 0215 void executePenUp(TreeNode* node); 0216 void executePenDown(TreeNode* node); 0217 void executePenColor(TreeNode* node); 0218 void executeCanvasColor(TreeNode* node); 0219 void executeCanvasSize(TreeNode* node); 0220 void executeSpriteShow(TreeNode* node); 0221 void executeSpriteHide(TreeNode* node); 0222 void executePrint(TreeNode* node); 0223 void executeFontSize(TreeNode* node); 0224 void executeRandom(TreeNode* node); 0225 void executeGetX(TreeNode* node); 0226 void executeGetY(TreeNode* node); 0227 void executeMessage(TreeNode* node); 0228 void executeAsk(TreeNode* node); 0229 void executePi(TreeNode* node); 0230 void executeTan(TreeNode* node); 0231 void executeSin(TreeNode* node); 0232 void executeCos(TreeNode* node); 0233 void executeArcTan(TreeNode* node); 0234 void executeArcSin(TreeNode* node); 0235 void executeArcCos(TreeNode* node); 0236 void executeSqrt(TreeNode* node); 0237 void executeRound(TreeNode* node); 0238 void executeGetDirection(TreeNode* node); 0239 void executeMod(TreeNode* node); 0240 0241 //END GENERATED executer_h CODE 0242 0243 TreeNode* getParentOfTokenTypes(TreeNode* child, QList<int>* types); 0244 inline void printExe(); 0245 0246 0247 0248 Q_SIGNALS: 0249 void currentlyExecuting(TreeNode* node); 0250 void variableTableUpdated(const QString& name, const Value& value); 0251 void functionTableUpdated(const QString& name, const QStringList& parameters); 0252 0253 void getX(double&); 0254 void getY(double&); 0255 void ask(QString& value); 0256 void message(const QString& text); 0257 void getDirection(double&); 0258 0259 // next you find generated signals that can be emitted: 0260 0261 //BEGIN GENERATED executer_emits_h CODE 0262 0263 /* The code between the line that start with "//BEGIN GENERATED" and "//END GENERATED" 0264 * is generated by "generate.rb" according to the definitions specified in 0265 * "definitions.rb". Please make all changes in the "definitions.rb" file, since all 0266 * all change you make here will be overwritten the next time "generate.rb" is run. 0267 * Thanks for looking at the code! 0268 */ 0269 0270 void reset(); 0271 void clear(); 0272 void center(); 0273 void go(double, double); 0274 void goX(double); 0275 void goY(double); 0276 void forward(double); 0277 void backward(double); 0278 void direction(double); 0279 void turnLeft(double); 0280 void turnRight(double); 0281 void penWidth(double); 0282 void penUp(); 0283 void penDown(); 0284 void penColor(double, double, double); 0285 void canvasColor(double, double, double); 0286 void canvasSize(double, double); 0287 void spriteShow(); 0288 void spriteHide(); 0289 void print(const QString&); 0290 void fontSize(double); 0291 0292 //END GENERATED executer_emits_h CODE 0293 0294 }; 0295 0296 #endif // _EXECUTER_H_