1 /** Copyright (C) 2006, Ian Paul Larsen. 2 ** 3 ** This program is free software; you can redistribute it and/or modify 4 ** it under the terms of the GNU General Public License as published by 5 ** the Free Software Foundation; either version 2 of the License, or 6 ** (at your option) any later version. 7 ** 8 ** This program is distributed in the hope that it will be useful, 9 ** but WITHOUT ANY WARRANTY; without even the implied warranty of 10 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 11 ** GNU General Public License for more details. 12 ** 13 ** You should have received a copy of the GNU General Public License along 14 ** with this program; if not, write to the Free Software Foundation, Inc., 15 ** 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. 16 **/ 17 18 #ifndef __INTERPRETER_H 19 #define __INTERPRETER_H 20 21 #include <QPixmap> 22 #include <QImage> 23 #include <QThread> 24 #include <QFile> 25 #include <QDir> 26 #include <QTime> 27 #include <stdio.h> 28 #include <cmath> 29 #include <dirent.h> 30 #include "BasicGraph.h" 31 #include "Constants.h" 32 #include "DataElement.h" 33 #include "Error.h" 34 #include "Convert.h" 35 #include "Stack.h" 36 #include "Variables.h" 37 #include "Sound.h" 38 #include "Sleeper.h" 39 #include "BasicDownloader.h" 40 41 #include <QElapsedTimer> 42 #include <QDebug> 43 #include <QProcess> 44 45 46 #include <QtPrintSupport/QPrinter> 47 #include <QtPrintSupport/QPrinterInfo> 48 49 #include <QtSql/QSqlDatabase> 50 #include <QtSql/QSqlQuery> 51 #include <QtSql/QSqlRecord> 52 #include <QtSql/QSqlError> 53 54 #ifndef ANDROID 55 // includes for all ports EXCEPT android 56 #include <QSerialPort> 57 #endif 58 59 enum run_status {R_STOPPED, R_RUNNING, R_INPUT, R_STOPING}; 60 61 #define NUMFILES 8 62 #define NUMSOCKETS 8 63 #define NUMDBCONN 8 64 #define NUMDBSET 8 65 66 #define STRINGMAXLEN 16777216 67 68 #define FILEWRITETIMEOUT 1 // on a file/serial write wait up to MS for the write to complete 69 #define FILEREADTIMEOUT 1 // on a file/serial read wait up to MS for data to be there 70 #define SERIALREADBUFFERSIZE 1024 // size of openserial read buffer 71 72 #define FORFRAMETYPE_INT 0 73 #define FORFRAMETYPE_FLOAT 1 74 #define FORFRAMETYPE_FOREACH_ARRAY 2 75 #define FORFRAMETYPE_FOREACH_MAP 3 76 77 78 struct byteCodeData 79 { 80 unsigned int size; 81 void *data; 82 }; 83 84 // used by function calls, subroutine calls, and gosubs for return location 85 // used also by onerror 86 // used to track nested on-error and try/catch definitions 87 class addrStack { 88 public: addrStack()89 addrStack(){ 90 size=0; 91 pointer=0; 92 stack.reserve(512); 93 }; ~addrStack()94 ~addrStack(){}; push(int * address)95 void push(int* address){ 96 if(pointer>=size) grow(); 97 stack[pointer]=address; 98 pointer++; 99 }; pop()100 int* pop(){ 101 if(pointer==0) return NULL; 102 pointer--; 103 return stack[pointer]; 104 }; peek()105 int* peek(){ 106 if(pointer==0) return NULL; 107 return stack[pointer-1]; 108 }; drop()109 void drop(){ 110 if(pointer>0) pointer--; 111 }; count()112 int count(){ 113 return pointer; 114 }; 115 private: 116 int size; 117 int pointer; 118 std::vector<int*> stack; grow()119 void grow(){ 120 size=size+50; 121 stack.resize(size); 122 }; 123 }; 124 125 struct trycatchframe { 126 trycatchframe *next; 127 int *catchAddr; 128 int recurseLevel; 129 int stackSize; 130 }; 131 132 // structure for the nested for statements 133 // if useInt then make loop integer safe 134 struct forframe { 135 forframe *next; 136 int *forAddr; //FOR address 137 int *nextAddr; //NEXT address 138 int type; //0=integer, 1=float, 2=foreache if - 139 int for_varnum; 140 int for_val_varnum; // -1 if not used (used to get map value in for each) 141 double floatStart; 142 double floatEnd; 143 double floatStep; 144 long intStart; 145 long intEnd; 146 long intStep; 147 DataElement *iter_d; // hold array or map pointer - delete on end of loop 148 std::vector<DataElement>::iterator arrayIter; 149 std::vector<DataElement>::iterator arrayIterEnd; 150 std::map<QString, DataElement>::iterator mapIter; 151 std::map<QString, DataElement>::iterator mapIterEnd; 152 }; 153 154 typedef struct { 155 bool visible; 156 double x; 157 double y; 158 double r; // rotate 159 double s; // scale 160 double o; // opacity 161 QImage *image; 162 QImage *transformed_image; 163 QRect position; 164 bool changed; 165 bool was_printed; 166 QRect last_position; 167 } sprite; 168 169 class Interpreter : public QThread 170 { 171 Q_OBJECT; 172 public: 173 Interpreter(QLocale*); 174 ~Interpreter(); 175 int compileProgram(char *); 176 void initialize(); 177 bool isRunning(); 178 bool isStopped(); 179 bool isStopping(); 180 void setStatus(run_status); 181 bool isAwaitingInput(); 182 void setInputString(QString); 183 void cleanup(); 184 void run(); 185 int debugMode; // 0=normal run, 1=step execution, 2=run to breakpoint 186 QList<int> *debugBreakPoints; // map of line numbers where break points ( pointer to breakpoint list in basicedit) 187 QString returnString; // return value from runcontroller emit 188 int returnInt; // return value from runcontroller emit 189 QImage returnImage; // return value from runcontroller emit 190 int settingsAllowPort; 191 int settingsAllowSystem; 192 193 public slots: 194 int execByteCode(); 195 void runHalted(); 196 197 signals: 198 void debugNextStep(); 199 void fastGraphics(); 200 //void stopRun(); 201 void stopRunFinalized(bool); 202 void goutputReady(); 203 void outputReady(QString); 204 void outputError(QString); 205 void getInput(); 206 void outputClear(); 207 void getKey(); 208 void playSounds(int, int*); 209 void setVolume(int); 210 void speakWords(QString); 211 void goToLine(int); 212 void seekLine(int); 213 void varWinAssign(Variables**, int, int); 214 void varWinAssign(Variables**, int, int, int, int); 215 void varWinDropLevel(int); 216 void varWinDimArray(Variables**, int, int, int); 217 void resizeGraphWindow(int, int, qreal); 218 void mainWindowsVisible(int, bool); 219 void dialogAlert(QString); 220 void dialogConfirm(QString, int); 221 void dialogPrompt(QString, QString); 222 void dialogOpenFileDialog(QString, QString, QString); 223 void dialogSaveFileDialog(QString, QString, QString); 224 void dialogAllowPortInOut(QString); 225 void dialogAllowSystem(QString); 226 void playSound(QString, bool); 227 void playSound(std::vector<std::vector<double>>, bool); 228 void loadSoundFromArray(QString, QByteArray*); 229 void soundStop(int); 230 void soundPlay(int); 231 void soundFade(int, double, int, int); 232 void soundVolume(int, double); 233 //void soundExit(); 234 void soundPlayerOff(int); 235 void soundSystem(int); 236 void getClipboardImage(); 237 void getClipboardString(); 238 void setClipboardImage(QImage); 239 void setClipboardString(QString); 240 241 242 private: 243 QLocale *locale; 244 Sleeper *sleeper; 245 BasicDownloader *downloader; 246 //int optype(int op); 247 QString opname(int); 248 void waitForGraphics(); 249 void printError(); 250 int netSockClose(int); 251 void netSockCloseAll(); 252 Variables *variables; 253 Stack *stack; 254 Stack *savestack; 255 bool isError; //flag set if program stops because of an error 256 Convert *convert; 257 QIODevice **filehandle; 258 int *filehandletype; // 0=QFile (normal), 1=QFile (binary), 2=QSerialPort 259 int *op; 260 addrStack *callstack; 261 addrStack *onerrorstack; 262 trycatchframe *trycatchstack; // used to track nested try/catch definitions 263 void decreaserecurse(); 264 forframe *forstack; // stack FOR/NEXT for current recurse level 265 std::vector <forframe*> forstacklevel; // stack FOR/NEXT for each recurse level 266 int forstacklevelsize; // size for forstacklevel stack 267 run_status status; 268 bool fastgraphics; 269 QString inputString; // input string from user 270 int inputType; // data type to convert the input into 271 double double_random_max; 272 int currentLine; 273 void clearsprites(); 274 void update_sprite_screen(); 275 void sprite_prepare_for_new_content(int); 276 void force_redraw_all_sprites_next_time(); 277 bool sprite_collide(int, int, bool); 278 sprite *sprites; 279 int nsprites; 280 void closeDatabase(int); 281 int arraybase; // 0 for 0..n-1, 1 for 1 to n array indexing 282 // watch... functions trigger the variablewatch window to display 283 void watchvariable(bool, int); 284 void watchvariable(bool, int, int, int); 285 void watchdecurse(bool); 286 287 int listensockfd; // temp socket used in netlisten 288 int netsockfd[NUMSOCKETS]; 289 290 DIR *directorypointer; // used by DIR function 291 QTime runtimer; // used by MSEC function 292 //SoundSystem *sound; 293 int includeFileNumber; 294 bool regexMinimal; // flag to tell QRegExp to be greedy (false) or minimal (true) 295 296 bool printing; 297 QPrinter *printdocument; 298 299 QPainter *painter; 300 bool painter_pen_need_update; 301 bool painter_brush_need_update; 302 bool painter_last_compositionModeClear; 303 unsigned long painter_brush_color; //last color value for comparison 304 unsigned long painter_pen_color; //last color value for comparison 305 void setGraph(QString id); 306 QString drawto; 307 bool setPainterTo(QPaintDevice *destination); 308 QPen drawingpen; 309 QBrush drawingbrush; 310 int CompositionModeClear; 311 int PenColorIsClear; 312 bool drawingOnScreen; 313 314 QFont font; 315 QString defaultfontfamily; 316 int defaultfontpointsize; 317 int defaultfontweight; 318 bool defaultfontitalic; 319 320 bool painter_font_need_update; 321 bool painter_custom_font_flag; 322 323 324 325 QSqlQuery *dbSet[NUMDBCONN][NUMDBSET]; // allow NUMDBSET number of sets on a database connection 326 327 int mediaplayer_id_legacy; 328 329 QMap <QString, QImage*> images; 330 int lastImageId; 331 bool imageSmooth; 332 333 int settingsDebugSpeed; 334 bool settingsAllowSetting; 335 int settingsSettingsAccess; 336 int settingsSettingsMax; 337 QString programName; 338 int settingsPrinterResolution; 339 int settingsPrinterPrinter; 340 int settingsPrinterPaper; 341 QString settingsPrinterPdfFile; 342 int settingsPrinterOrient; 343 QMap<QString, QMap<QString, QString>> fakeSettings; 344 QProcess *sys; 345 346 }; 347 348 349 #endif 350