blob: 47ea941020c3a06da9bad9766ee8a023e003264d [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
swissChili682e7bc2021-12-07 09:04:54 -080062class Evaluator {
63public:
swissChili323883d2022-02-20 16:35:23 -080064 Evaluator();
swissChili07d325f2021-12-08 20:02:05 -080065
66 void addFunction(Function func);
67 void clearFunction(QString name);
swissChilid85daa92022-02-24 15:29:02 -080068 RuntimeResult evaluate(AstNode node, VarContext ctx, int recursionDepth = 0);
69 RuntimeResult callFunction(QString name, QList<Token> args, int recursionDepth);
70
71 // Throws an EvalQuitException
72 void quit();
swissChili07d325f2021-12-08 20:02:05 -080073
74private:
75 QMap<QString, Function> _functions;
swissChili918557c2022-02-20 20:16:34 -080076 QMap<QString, QStack<QList<Token>>> _vars;
swissChilid85daa92022-02-24 15:29:02 -080077 bool _shouldContinue = true;
78 int _recursionLimit = 1024;
swissChili918557c2022-02-20 20:16:34 -080079
80protected:
81 QList<Token> dig(QString name);
82 QList<Token> copy(QString name);
83 void bury(QString name, QList<Token> expression);
swissChili682e7bc2021-12-07 09:04:54 -080084};
swissChili918557c2022-02-20 20:16:34 -080085
86void rtError(QString brief, QString details);