#ifndef AST_H #define AST_H #include #include #include #include #include #include enum class ByteOrder { LE, BE }; enum class ScalarType { U8, I8, U16, I16, U32, I32, U64, I64, F32, F64, Bool}; struct Expr; using ExprPtr = QSharedPointer; struct Stmt; using StmtPtr = QSharedPointer; struct UiFlags { bool ui = false; bool readOnly = false; bool hidden = false; QString display; QString tableTitle; QString columnsCsv; QHash 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 args; }; // member access: object.field struct Member { ExprPtr object; QString field; }; // pipeline: base | stage | stage // stage is represented as Call(fn,args) but comes from "identifier" or "parse TypeName" struct Pipe { ExprPtr base; QVector stages; }; using Node = std::variant; 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 thenBody; QVector elseBody; }; struct While { ExprPtr cond; QVector body; }; struct Repeat { ExprPtr count; QVector body; }; // for i in 0..count { ... } (range is [start, end)) struct ForRange { QString var; ExprPtr start; ExprPtr end; QVector 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 // inline cstring name @ name_ptr; // inline typename name @ ptr_field [ui="Display", set_name]; struct Inline { QString typeName; // "cstring", "material", etc. QString varName; // variable to store result QString ptrField; // pointer field to check (== -1 means inline) UiFlags ui; bool setName = false; // call set_name() with result }; // array[count] items: typename @ ptr; struct ArrayDecl { ExprPtr count; QString varName; QString elementType; QString ptrField; // optional - if present, only parse when ptr == -1 UiFlags ui; }; // const NAME = value; struct Const { QString name; ExprPtr value; }; // match(expr) { pattern => result, ... } struct Match { ExprPtr expr; QVector, QVector>> arms; // patterns -> body QVector defaultBody; }; using Node = std::variant; 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 criteria; QVector body; }; struct Module { QHash types; QVariantMap globals; // Global variables shared across all parse contexts }; #endif // AST_H