Skip to main content

yog_script_analyze/ast/
expr.rs

1//! Statements, expressions, patterns and types (`ys-grammar.md` §3, §4).
2
3use super::{Name, VersionCond};
4use crate::source::token::Span;
5
6#[derive(Debug, Clone, PartialEq)]
7pub struct Block {
8    pub stmts: Vec<Stmt>,
9    pub span: Span,
10}
11
12#[derive(Debug, Clone, PartialEq)]
13pub enum Stmt {
14    Let {
15        pattern: Pattern,
16        ty: Option<Type>,
17        value: Expr,
18    },
19    Var {
20        name: Name,
21        ty: Option<Type>,
22        value: Option<Expr>,
23    },
24    /// `place op value`; `op` None for `=`.
25    Assign {
26        place: Expr,
27        op: Option<BinOp>,
28        value: Expr,
29    },
30    For {
31        pattern: Pattern,
32        iter: Expr,
33        body: Block,
34    },
35    While {
36        cond: Cond,
37        body: Block,
38    },
39    Loop(Block),
40    Break(Span),
41    Continue(Span),
42    Return(Option<Expr>, Span),
43    /// `skip value` in a patch's `before`: the method ends with it.
44    Skip(Option<Expr>, Span),
45    Expr(Expr),
46}
47
48#[derive(Debug, Clone, PartialEq)]
49pub struct Expr {
50    pub kind: ExprKind,
51    pub span: Span,
52}
53
54#[derive(Debug, Clone, PartialEq)]
55pub enum ExprKind {
56    Int(i64),
57    Float(f64),
58    Unit {
59        value: String,
60        unit: String,
61    },
62    Str(Vec<StrSeg>),
63    RawStr(String),
64    Text(String),
65    Content {
66        kind: String,
67        id: String,
68    },
69    Tag(String),
70    Bool(bool),
71    None,
72    Ident(String),
73    SelfValue,
74    It,
75    /// `mc >= 1.21`: the running game's version.
76    Mc(VersionCond),
77    Tuple(Vec<Expr>),
78    List(Vec<Expr>),
79    Map(Vec<(Expr, Expr)>),
80    Lambda {
81        params: Vec<Name>,
82        body: Vec<Stmt>,
83    },
84    Unary {
85        op: UnOp,
86        expr: Box<Expr>,
87    },
88    Binary {
89        op: BinOp,
90        left: Box<Expr>,
91        right: Box<Expr>,
92    },
93    Range {
94        from: Box<Expr>,
95        to: Box<Expr>,
96        inclusive: bool,
97    },
98    /// `x is T`, `x is T name`, `x !is T`.
99    Is {
100        expr: Box<Expr>,
101        ty: Type,
102        bind: Option<Name>,
103        negated: bool,
104    },
105    /// `x as T`, `x as? T`.
106    As {
107        expr: Box<Expr>,
108        ty: Type,
109        checked: bool,
110    },
111    Call {
112        callee: Box<Expr>,
113        args: Vec<Arg>,
114    },
115    Index {
116        expr: Box<Expr>,
117        index: Box<Expr>,
118    },
119    /// `f<T, U>` before a call: the type arguments.
120    TypeArgs {
121        expr: Box<Expr>,
122        args: Vec<Type>,
123    },
124    /// `x.name`, `x?.name`.
125    Member {
126        expr: Box<Expr>,
127        name: Name,
128        safe: bool,
129    },
130    If {
131        cond: Box<Cond>,
132        then: Block,
133        otherwise: Option<Box<Expr>>,
134    },
135    Match {
136        expr: Box<Expr>,
137        arms: Vec<Arm>,
138    },
139    Block(Block),
140    /// What couldn't be parsed (reported already).
141    Error,
142}
143
144/// A piece of a string: text, or an interpolated `{expr}`.
145#[derive(Debug, Clone, PartialEq)]
146pub enum StrSeg {
147    Text(String),
148    Expr(Expr),
149}
150
151/// `if expr` or `if let pattern = expr`.
152#[derive(Debug, Clone, PartialEq)]
153pub enum Cond {
154    Expr(Expr),
155    Let { pattern: Box<Pattern>, value: Expr },
156}
157
158#[derive(Debug, Clone, PartialEq)]
159pub struct Arg {
160    pub name: Option<Name>,
161    pub value: Expr,
162}
163
164#[derive(Debug, Clone, PartialEq)]
165pub struct Arm {
166    pub pattern: Pattern,
167    pub guard: Option<Expr>,
168    pub body: Expr,
169}
170
171#[derive(Debug, Clone, Copy, PartialEq, Eq)]
172pub enum UnOp {
173    Neg,
174    Not,
175    Try,
176}
177
178#[derive(Debug, Clone, Copy, PartialEq, Eq)]
179pub enum BinOp {
180    Coalesce,
181    Or,
182    And,
183    Eq,
184    NotEq,
185    Lt,
186    LtEq,
187    Gt,
188    GtEq,
189    In,
190    NotIn,
191    Add,
192    Sub,
193    Mul,
194    Div,
195    Rem,
196}
197
198#[derive(Debug, Clone, PartialEq)]
199pub enum Pattern {
200    Wild(Span),
201    /// A literal or a path to a value (`0`, `energy.max`); a single name
202    /// binds or names a case: the resolver tells which.
203    Value(Expr),
204    Range {
205        from: Expr,
206        to: Expr,
207    },
208    Is {
209        ty: Type,
210        bind: Option<Name>,
211    },
212    Variant {
213        path: Vec<Name>,
214        args: Vec<Pattern>,
215    },
216    Tuple(Vec<Pattern>),
217    Or(Vec<Pattern>),
218    Else(Span),
219}
220
221#[derive(Debug, Clone, PartialEq)]
222pub struct Type {
223    pub kind: TypeKind,
224    pub span: Span,
225}
226
227#[derive(Debug, Clone, PartialEq)]
228pub enum TypeKind {
229    Path {
230        path: Vec<Name>,
231        args: Vec<Type>,
232    },
233    /// `Int in 0..100`.
234    Bounded {
235        base: Box<Type>,
236        range: Box<Expr>,
237    },
238    Tuple(Vec<Type>),
239    Fn {
240        params: Vec<Type>,
241        ret: Box<Type>,
242    },
243    Optional(Box<Type>),
244}