blob: 35df4136dae418cff32619b3a86da82c03b4be4d [file] [log] [blame]
swissChilid85daa92022-02-24 15:29:02 -08001#include <QCoreApplication>
2
3#include "NbRuntime.h"
4#include "../Parser.h"
swissChili5d3e5562022-02-24 16:49:19 -08005#include "../StdLib.h"
swissChilid85daa92022-02-24 15:29:02 -08006
7NbRuntime::NbRuntime(QObject *parent)
8 : QThread(parent)
9{
swissChili5d3e5562022-02-24 16:49:19 -080010 StdLib().load(_eval);
swissChilid85daa92022-02-24 15:29:02 -080011}
12
13void NbRuntime::queueCell(Cell *cell)
14{
15 if (!_cells.contains(cell))
16 {
17 qInfo() << "Queueing cell";
18
19 _cells.append(cell);
20
21 emit cellWaiting(cell);
22
23 if (!_running)
24 evalRemaining();
25 }
26}
27
28void NbRuntime::unqueueCell(Cell *cell)
29{
30 if (cell == _running)
31 {
32 // Exception should propagate back up to evalRemaining()
33 _eval.quit();
34 }
35 else
36 {
37 _cells.removeOne(cell);
38 }
39}
40
41void NbRuntime::evalRemaining()
42{
43 qInfo() << "evalRemaining";
44
45 while (!_cells.empty())
46 {
47 QCoreApplication::processEvents();
48
49 Cell *cell = _cells.first();
50 _cells.removeFirst();
51
52 _running = cell;
53
54 Parser parser(cell->code());
55 RuntimeResult result;
56
57 emit cellRunning(cell);
58
59 try
60 {
61 // Allow this cell to be quit
62 QCoreApplication::processEvents();
63
64 while (true)
65 {
66 ParseResult ret;
67 Function func;
68 AstNode ast;
69
70 if ((ret = parser.parseFunctionDefinition(&func)))
71 {
72 _eval.addFunction(func);
73 }
74 else if (ret.status() == ParseResult::INCOMPLETE)
75 {
76 emit cellFailedToParse(cell, ret);
77 goto endOfCell; // JANK!
78 }
79 else if ((ret = parser.parseOne(&ast)))
80 {
81 RuntimeResult nodeRes = _eval.evaluate(ast, _ctx);
82 result += nodeRes;
83
84 if (!nodeRes.success())
85 {
86 break;
87 }
88 }
89 else if (ret.status() == ParseResult::INCOMPLETE)
90 {
91 emit cellFailedToParse(cell, ret);
92 break;
93 }
94 else
95 {
96 parser.skip();
97
98 if (!parser.atEnd())
99 {
100 emit cellFailedToParse(cell, ParseResult(ParseResult::NO_MATCH, "Garbage at end of input", parser.save()));
101 goto endOfCell;
102 }
103
104 break;
105 }
106 }
107
108 emit cellFinishedRunning(cell, result);
109
110 endOfCell:
111 _running = nullptr;
112 }
113 catch (EvalQuitException &ex)
114 {
115 _running = nullptr;
116 emit cellQuit(cell);
117 }
118 catch (StackOverflowException &ex)
119 {
120 _running = nullptr;
121 emit cellFinishedRunning(cell, RuntimeResult(ex));
122 }
swissChili5d3e5562022-02-24 16:49:19 -0800123 catch (AssertionException &ex)
124 {
125 _running = nullptr;
126 emit cellFinishedRunning(cell, RuntimeResult(ex));
127 }
swissChilid85daa92022-02-24 15:29:02 -0800128 }
129}