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