yog-script-analyze 0.2.2

Yog Script (.ys, .yns) analyzed: its lexer, parser and syntax tree, names resolved, the class index model — what the build and the editors read a source with.
Documentation
//! Expressions (`ys-grammar.md` §3.2–3.4).

use super::{Name, Pattern, Stmt, Type, VersionCond};
use crate::source::token::Span;

#[derive(Debug, Clone, PartialEq)]
pub struct Expr {
    pub kind: ExprKind,
    pub span: Span,
}

#[derive(Debug, Clone, PartialEq)]
pub enum ExprKind {
    Int(i64),
    Float(f64),
    Unit {
        value: String,
        unit: String,
    },
    Str(Vec<StrSeg>),
    RawStr(String),
    Char(char),
    Text(String),
    Content {
        kind: String,
        id: String,
    },
    Tag(String),
    Bool(bool),
    Null,
    Ident(String),
    This,
    /// `base`: `this` as its base class (`base.Tick()`).
    Base,
    It,
    /// `out let x`, `out i32 x`: a local declared where a method gives it.
    Declare {
        ty: Option<Type>,
        name: Name,
        mutable: bool,
    },
    /// `typeof(T)`: its `System.Type`.
    TypeOf(Type),
    /// `nameof(x.Y)`: its last name, as a string.
    NameOf(Box<Expr>),
    /// `default`, `default(T)`: the type's zero value.
    Default(Option<Type>),
    /// `mc >= 1.21`: the running game's version.
    Mc(VersionCond),
    Tuple(Vec<Expr>),
    /// `[a, b]`, `[k => v]`, `[..xs]`: a list, a set or a map by its target.
    Collection(Vec<Element>),
    /// `new Pos(1, 2, 3)`, `new(4)`, `new Battery { Count = 2 }`.
    New {
        ty: Option<Type>,
        args: Option<Vec<Arg>>,
        init: Vec<(Name, Expr)>,
    },
    /// `x => …`, `(a, b) => …`, `{ … }` after a call (`it` its parameter).
    Lambda {
        params: Vec<LambdaParam>,
        body: LambdaBody,
    },
    Unary {
        op: UnOp,
        expr: Box<Expr>,
    },
    /// `(i32)x`.
    Cast {
        ty: Type,
        expr: Box<Expr>,
    },
    Binary {
        op: BinOp,
        left: Box<Expr>,
        right: Box<Expr>,
    },
    Range {
        from: Box<Expr>,
        to: Box<Expr>,
        inclusive: bool,
    },
    /// `x is Monster m`, `x is not null`.
    Is {
        expr: Box<Expr>,
        pattern: Box<Pattern>,
    },
    /// `x as T`: `null` when it isn't one.
    As {
        expr: Box<Expr>,
        ty: Type,
    },
    /// `x has Charge`.
    Has {
        expr: Box<Expr>,
        ty: Type,
    },
    /// `c ? a : b`.
    Conditional {
        cond: Box<Expr>,
        then: Box<Expr>,
        otherwise: Box<Expr>,
    },
    /// `x switch { … }`.
    Switch {
        expr: Box<Expr>,
        arms: Vec<Arm>,
    },
    Call {
        callee: Box<Expr>,
        args: Vec<Arg>,
    },
    Index {
        expr: Box<Expr>,
        index: Box<Expr>,
    },
    /// `f<T, U>` before a call: the type arguments.
    TypeArgs {
        expr: Box<Expr>,
        args: Vec<Type>,
    },
    /// `x.Name`, `x?.Name`.
    Member {
        expr: Box<Expr>,
        name: Name,
        safe: bool,
    },
    /// `panic!(…)`: a built-in macro's call (a declared macro's is
    /// expanded before the parser sees it).
    Macro {
        name: Name,
        args: Vec<Expr>,
    },
    /// `move x`: `x` handed on, gone after.
    Move(Box<Expr>),
    /// `x!`: asserted not null.
    NotNull(Box<Expr>),
    /// What couldn't be parsed (reported already).
    Error,
}

/// A piece of a string: text, or an interpolated `{expr}`.
#[derive(Debug, Clone, PartialEq)]
pub enum StrSeg {
    Text(String),
    Expr(Expr),
}

/// An element of a collection expression.
#[derive(Debug, Clone, PartialEq)]
pub enum Element {
    Item(Expr),
    Entry(Expr, Expr),
    Spread(Expr),
}

/// A lambda's parameter: typed or not.
#[derive(Debug, Clone, PartialEq)]
pub struct LambdaParam {
    pub ty: Option<Type>,
    pub name: Name,
}

#[derive(Debug, Clone, PartialEq)]
pub enum LambdaBody {
    Expr(Box<Expr>),
    Block(Vec<Stmt>),
}

/// `value` or `name: value`.
#[derive(Debug, Clone, PartialEq)]
pub struct Arg {
    pub name: Option<Name>,
    pub pass: Option<super::Pass>,
    pub value: Expr,
}

/// `pattern when guard => value`.
#[derive(Debug, Clone, PartialEq)]
pub struct Arm {
    pub pattern: Pattern,
    pub guard: Option<Expr>,
    pub value: Expr,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum UnOp {
    Neg,
    Not,
    Try,
    Await,
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum BinOp {
    Coalesce,
    Or,
    And,
    Eq,
    NotEq,
    Lt,
    LtEq,
    Gt,
    GtEq,
    In,
    Add,
    Sub,
    Mul,
    Div,
    Rem,
}