XPlor/libs/dsl/ast.h
njohnson d7285b5bbe Enhance DSL interpreter with new built-in functions
Add support for:
- basename() function for extracting filenames from paths
- cstring() function for reading null-terminated strings
- ascii() function for reading fixed-length ASCII strings
- Enhanced type registry with additional primitive types
- Improved parser with better error handling

These additions enable more flexible XScript definitions for
parsing binary file formats.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 16:35:35 -05:00

130 lines
2.8 KiB
C++

#ifndef AST_H
#define AST_H
#include <QString>
#include <QVector>
#include <QVariant>
#include <QHash>
#include <variant>
enum class ByteOrder { LE, BE };
enum class ScalarType { U8, I8, U16, I16, U32, I32, U64, I64, F32, F64, Bool};
struct Expr;
using ExprPtr = QSharedPointer<Expr>;
struct Stmt;
using StmtPtr = QSharedPointer<Stmt>;
struct UiFlags {
bool ui = false;
bool readOnly = false;
bool hidden = false;
QString display;
QString tableTitle;
QString columnsCsv;
QHash<QString, QString> formats;
bool visible() const { return ui && !hidden; }
bool isTable() const { return !tableTitle.isEmpty(); }
};
struct Expr {
struct Int { qint64 v; };
struct String { QString v; };
struct Var { QString name; };
struct Unary {
QString op;
ExprPtr rhs;
};
struct Binary {
QString op;
ExprPtr lhs;
ExprPtr rhs;
};
// call like read(x), pos(), size()
struct Call {
QString fn;
QVector<ExprPtr> args;
};
// pipeline: base | stage | stage
// stage is represented as Call(fn,args) but comes from "identifier" or "parse TypeName"
struct Pipe {
ExprPtr base;
QVector<Call> stages;
};
using Node = std::variant<Int, String, Var, Unary, Binary, Call, Pipe>;
Node node;
int line = 1;
int col = 1;
};
struct Stmt {
struct ReadScalar { ScalarType type; QString name; UiFlags ui; };
struct Skip { ExprPtr count; };
struct Align { ExprPtr n; };
struct Seek { ExprPtr pos; };
struct Assign { QString name; ExprPtr value; UiFlags ui; };
struct If {
ExprPtr cond;
QVector<StmtPtr> thenBody;
QVector<StmtPtr> elseBody;
};
struct While {
ExprPtr cond;
QVector<StmtPtr> body;
};
struct Repeat {
ExprPtr count;
QVector<StmtPtr> body;
};
// for i in 0..count { ... } (range is [start, end))
struct ForRange {
QString var;
ExprPtr start;
ExprPtr end;
QVector<StmtPtr> body;
};
struct Require { ExprPtr cond; };
struct SetByteOrder { ByteOrder order; };
struct CallStmt { ExprPtr call; }; // Function call as statement (result discarded)
struct Break {}; // break from while loop
using Node = std::variant<ReadScalar, Skip, Align, Seek, Assign, If, While, Repeat, ForRange, Require, SetByteOrder, CallStmt, Break>;
Node node;
int line = 1;
int col = 1;
};
struct TypeDef {
QString name;
QString display;
ByteOrder order = ByteOrder::LE;
bool hasExplicitByteOrder = false;
bool isRoot = false;
QVector<StmtPtr> criteria;
QVector<StmtPtr> body;
};
struct Module {
QHash<QString, TypeDef> types;
QVariantMap globals; // Global variables shared across all parse contexts
};
#endif // AST_H