XPlor/libs/dsl/interpreter.h

94 lines
3.4 KiB
C
Raw Permalink Normal View History

2026-01-01 22:18:25 -05:00
#ifndef INTERPRETER_H
#define INTERPRETER_H
#include "ast.h"
#include <QDataStream>
#include <QVariantMap>
#include <QIODevice>
#include <functional>
2026-01-01 22:18:25 -05:00
struct Runtime {
QDataStream* in = nullptr;
Module* module = nullptr; // Non-const to allow modifying globals
ByteOrder order = ByteOrder::LE;
QVariantMap vars;
QString filePath;
// Error context tracking
QStringList typeStack; // Stack of types being parsed
QString currentType() const { return typeStack.isEmpty() ? QString() : typeStack.last(); }
void pushType(const QString& t) { typeStack.append(t); }
void popType() { if (!typeStack.isEmpty()) typeStack.removeLast(); }
QString typeStackString() const { return typeStack.join(" -> "); }
// Write-back journal tracking
int journalId = -1; // Current journal being built (-1 = disabled)
bool journalEnabled = true; // Can disable for criteria checks
2026-01-01 22:18:25 -05:00
};
using ProgressCallback = std::function<void(qint64 pos, qint64 size)>;
using StatusCallback = std::function<void(const QString& status)>;
2026-01-01 22:18:25 -05:00
class Interpreter {
public:
explicit Interpreter(Module mod);
// Parse a given type name from a device/stream
QVariantMap runType(const QString& typeName, QIODevice* dev, const QString& filePath = QString()) const;
// Run from existing QDataStream (for nested parse)
QVariantMap runType(const QString& typeName, QDataStream& stream, const QString &filePath = QString()) const;
// Check if the criteria for a certain filetype matches
bool checkCriteria(const QString& typeName, QIODevice* dev, const QString filePath) const;
QVariantMap runTypeInternal(const QString& typeName,
QDataStream& stream,
const QString& filePath,
std::optional<ByteOrder> inheritedOrder) const;
// Version that accepts a journal ID for nested parsing
QVariantMap runTypeInternalWithJournal(const QString& typeName,
QDataStream& stream,
const QString& filePath,
std::optional<ByteOrder> inheritedOrder,
int journalId) const;
2026-01-01 22:18:25 -05:00
static void seedFileVars(Runtime &rt, const QString &filePath);
// Progress reporting
void setProgressCallback(ProgressCallback cb);
void setStatusCallback(StatusCallback cb);
void setFileSize(qint64 size);
2026-01-01 22:18:25 -05:00
private:
QVariant evalExpr(Runtime& rt, const Expr& e) const;
QVariant evalCall(Runtime& rt, const Expr::Call& c) const;
QVariant evalPipe(Runtime& rt, const Expr::Pipe& p) const;
void execStmt(Runtime& rt, const Stmt& s) const;
void execBlock(Runtime& rt, const QVector<StmtPtr>& body) const;
// helpers
void applyByteOrder(Runtime& rt) const;
QVariant readScalar(Runtime& rt, ScalarType t) const;
QByteArray readBytes(Runtime& rt, qint64 n) const;
QByteArray readEOF(Runtime& rt) const;
qint64 toInt(const QVariant& v) const;
bool toBool(const QVariant& v) const;
void reportProgress(Runtime& rt) const;
void reportStatus(const QString& status) const;
2026-01-01 22:18:25 -05:00
private:
mutable Module m_mod;
mutable ProgressCallback m_progressCallback;
mutable StatusCallback m_statusCallback;
mutable qint64 m_fileSize = 0; // Mutable to allow modifying globals from const methods
2026-01-01 22:18:25 -05:00
};
#endif // INTERPRETER_H