// Abstract syntax tree for parsed templates.

///|
/// A parsed template expression.
pub(all) enum Expr {
  EInt(Int)
  EFloat(Double)
  EStr(String)
  EBool(Bool)
  /// Variable lookup by name.
  EVar(String)
  /// Member access `a.b`.
  EMember(Expr, String)
  /// Array or object index access: `items[0]` or `config["theme"]`.
  EIndex(Expr, Expr)
  /// Binary operation `op(left, right)`.
  EBinOp(String, Expr, Expr)
  /// Logical not.
  ENot(Expr)
  /// Filter application: `input | name(args)`.
  EFilter(Expr, String, Array[Expr])
  /// `is` test: `value is test_name`.
  EIs(Expr, String)
  /// `super()` — render the parent block's body (inside a `{% block %}`).
  ESuper
} derive(Debug)

///|
/// A node in a parsed template's syntax tree.
pub(all) enum Node {
  /// Literal text.
  Text(String)
  /// A `{{ expr }}` output.
  Output(Expr)
  /// `{% if cond %}then{% else %}else{% endif %}`.
  If(Expr, Array[Node], Array[Node])
  /// `{% for x in iter %}body{% else %}empty{% endfor %}`.
  For(String, Expr, Array[Node], Array[Node])
  /// `{% block name %}body{% endblock %}`.
  Block(String, Array[Node])
  /// `{% include "name" %}`.
  Include(String)
  /// `{% set name = expr %}`.
  Set(String, Expr)
} derive(Debug)

///|
/// Parse a raw expression string into an `Expr` (lexer + Pratt parser).
pub fn parse_expr(s : String) -> Expr {
  expr_parse(expr_lex(s))
}