blob: a88e8099ea3434893f08f3d8261bcc4095b74397 [file] [log] [blame]
#pragma once
#include <QMap>
#include <QStack>
#include <QException>
#include "Token.h"
#include "AstNode.h"
#include "Function.h"
#include "VarContext.h"
class RuntimeResult
{
public:
RuntimeResult(const RuntimeResult &other) = default;
RuntimeResult(QList<Token> result = {});
RuntimeResult(QString message);
RuntimeResult &operator =(const RuntimeResult &other);
RuntimeResult operator +(const RuntimeResult &other);
RuntimeResult &operator +=(const RuntimeResult &other);
bool success() const;
QString message() const;
QList<Token> result() const;
operator QString() const;
private:
bool _success = true;
QString _errorMessage;
QList<Token> _result;
};
class EvalQuitException : public QException
{
public:
EvalQuitException() = default;
EvalQuitException(const EvalQuitException &other) = default;
void raise() const override;
EvalQuitException *clone() const override;
};
class StackOverflowException : public QException
{
public:
StackOverflowException(AstNode failedAt = AstNode());
StackOverflowException(const StackOverflowException &other) = default;
AstNode failedAt() const;
void raise() const override;
StackOverflowException *clone() const override;
operator QString() const;
private:
AstNode _failedAt;
};
class AssertionException : public QException
{
public:
AssertionException(QString message = "");
AssertionException(const AssertionException &other) = default;
QString message() const;
void raise() const override;
AssertionException *clone() const override;
operator QString() const;
private:
QString _message;
};
class Evaluator {
public:
Evaluator();
void addFunction(Function func);
void clearFunction(QString name);
RuntimeResult evaluate(AstNode node, VarContext ctx, int recursionDepth = 0);
RuntimeResult callFunction(QString name, QList<Token> args, int recursionDepth);
// Throws an EvalQuitException
void quit();
void reset();
private:
QMap<QString, Function> _functions;
QMap<QString, QStack<QList<Token>>> _vars;
bool _shouldContinue = true;
int _recursionLimit = 1024;
protected:
QList<Token> dig(QString name);
QList<Token> copy(QString name);
void bury(QString name, QList<Token> expression);
};
void rtError(QString brief, QString details);