blob: a88e8099ea3434893f08f3d8261bcc4095b74397 [file] [log] [blame]
swissChili682e7bc2021-12-07 09:04:54 -08001#pragma once
2
swissChili07d325f2021-12-08 20:02:05 -08003#include <QMap>
swissChili918557c2022-02-20 20:16:34 -08004#include <QStack>
swissChilid85daa92022-02-24 15:29:02 -08005#include <QException>
swissChili07d325f2021-12-08 20:02:05 -08006
7#include "Token.h"
8#include "AstNode.h"
9#include "Function.h"
10#include "VarContext.h"
11
12class RuntimeResult
13{
14public:
swissChilid85daa92022-02-24 15:29:02 -080015 RuntimeResult(const RuntimeResult &other) = default;
16 RuntimeResult(QList<Token> result = {});
swissChili07d325f2021-12-08 20:02:05 -080017 RuntimeResult(QString message);
18
swissChilid85daa92022-02-24 15:29:02 -080019 RuntimeResult &operator =(const RuntimeResult &other);
20 RuntimeResult operator +(const RuntimeResult &other);
21 RuntimeResult &operator +=(const RuntimeResult &other);
22
swissChili07d325f2021-12-08 20:02:05 -080023 bool success() const;
24 QString message() const;
25 QList<Token> result() const;
26
27 operator QString() const;
28
29private:
30 bool _success = true;
31 QString _errorMessage;
32 QList<Token> _result;
33};
34
swissChilid85daa92022-02-24 15:29:02 -080035class EvalQuitException : public QException
36{
37public:
38 EvalQuitException() = default;
39 EvalQuitException(const EvalQuitException &other) = default;
40
41 void raise() const override;
42 EvalQuitException *clone() const override;
43};
44
45class StackOverflowException : public QException
46{
47public:
48 StackOverflowException(AstNode failedAt = AstNode());
49 StackOverflowException(const StackOverflowException &other) = default;
50
51 AstNode failedAt() const;
52
53 void raise() const override;
54 StackOverflowException *clone() const override;
55
56 operator QString() const;
57
58private:
59 AstNode _failedAt;
60};
61
swissChili5d3e5562022-02-24 16:49:19 -080062class AssertionException : public QException
63{
64public:
65 AssertionException(QString message = "");
66 AssertionException(const AssertionException &other) = default;
67
68 QString message() const;
69
70 void raise() const override;
71 AssertionException *clone() const override;
72
73 operator QString() const;
74
75private:
76 QString _message;
77};
78
swissChili682e7bc2021-12-07 09:04:54 -080079class Evaluator {
80public:
swissChili323883d2022-02-20 16:35:23 -080081 Evaluator();
swissChili07d325f2021-12-08 20:02:05 -080082
83 void addFunction(Function func);
84 void clearFunction(QString name);
swissChilid85daa92022-02-24 15:29:02 -080085 RuntimeResult evaluate(AstNode node, VarContext ctx, int recursionDepth = 0);
86 RuntimeResult callFunction(QString name, QList<Token> args, int recursionDepth);
87
88 // Throws an EvalQuitException
89 void quit();
swissChili07d325f2021-12-08 20:02:05 -080090
swissChilia44bf722022-04-16 18:41:54 -070091 void reset();
92
swissChili07d325f2021-12-08 20:02:05 -080093private:
94 QMap<QString, Function> _functions;
swissChili918557c2022-02-20 20:16:34 -080095 QMap<QString, QStack<QList<Token>>> _vars;
swissChilid85daa92022-02-24 15:29:02 -080096 bool _shouldContinue = true;
97 int _recursionLimit = 1024;
swissChili918557c2022-02-20 20:16:34 -080098
99protected:
100 QList<Token> dig(QString name);
101 QList<Token> copy(QString name);
102 void bury(QString name, QList<Token> expression);
swissChili682e7bc2021-12-07 09:04:54 -0800103};
swissChili918557c2022-02-20 20:16:34 -0800104
105void rtError(QString brief, QString details);