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