File indexing completed on 2024-04-14 03:43:53

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_