Skip to main content

yog_script_analyze/ast/
decl.rs

1//! Declarations (`ys-grammar.md` §2): the mod, types, members, content,
2//! components and systems, events.
3
4use super::{Block, Expr, Name, Patch, Type};
5use crate::source::token::Span;
6
7/// What a declaration is marked with.
8#[derive(Debug, Clone, Copy, PartialEq, Eq)]
9pub enum Modifier {
10    Public,
11    Private,
12    Internal,
13    Static,
14    Const,
15    Readonly,
16    Async,
17    Server,
18    Client,
19    Shared,
20    Saved,
21    Synced,
22    Tune,
23}
24
25/// `[Obsolete("…")]`.
26#[derive(Debug, Clone, PartialEq)]
27pub struct Attribute {
28    pub path: Vec<Name>,
29    pub args: Vec<super::Arg>,
30}
31
32/// A declaration, its attributes, documentation and modifiers.
33#[derive(Debug, Clone, PartialEq)]
34pub struct Decl {
35    pub attributes: Vec<Attribute>,
36    pub doc: Vec<String>,
37    pub modifiers: Vec<Modifier>,
38    pub kind: DeclKind,
39    pub span: Span,
40}
41
42impl Decl {
43    pub fn has(&self, m: Modifier) -> bool {
44        self.modifiers.contains(&m)
45    }
46}
47
48/// A type's name and what follows it: generics, its primary constructor,
49/// what it implements, the constraints, the components it has.
50#[derive(Debug, Clone, PartialEq, Default)]
51pub struct TypeHeader {
52    pub generics: Vec<Name>,
53    pub ctor: Option<Vec<Param>>,
54    pub bases: Vec<Type>,
55    pub constraints: Vec<(Name, Vec<Type>)>,
56    pub has: Vec<Expr>,
57}
58
59#[derive(Debug, Clone, PartialEq)]
60pub enum DeclKind {
61    /// `using Yog.Ui;`.
62    Using(Vec<Name>),
63    /// `using Grid = Dictionary<Pos, int>;`.
64    Alias {
65        name: Name,
66        ty: Type,
67    },
68    /// `mod Charge { Version = "1.0.0"; … }`.
69    Mod {
70        name: Name,
71        props: Vec<Prop>,
72    },
73    Method(Method),
74    Field(Field),
75    /// `Ticks Left { get; set; }`, `Energy Room => …;`.
76    Property {
77        ty: Type,
78        name: Name,
79        accessors: Vec<Accessor>,
80        value: Option<Expr>,
81    },
82    Ctor(Ctor),
83    /// `class`, `record`, `interface`: which is `word`.
84    Type {
85        word: Name,
86        name: Name,
87        header: TypeHeader,
88        body: Vec<Decl>,
89    },
90    Union {
91        name: Name,
92        generics: Vec<Name>,
93        variants: Vec<Variant>,
94        body: Vec<Decl>,
95    },
96    Enum {
97        name: Name,
98        cases: Vec<Name>,
99    },
100    /// `unit Energy;` / `unit FE = Energy * 1;`.
101    Unit {
102        name: Name,
103        value: Option<Expr>,
104    },
105    /// `block Charger has Charge(1000) { … }`, `recipe Battery : Shaped { … }`,
106    /// a mod's own kinds.
107    Content {
108        kind: Name,
109        name: Name,
110        header: TypeHeader,
111        body: Vec<Decl>,
112    },
113    Component {
114        name: Name,
115        header: TypeHeader,
116        body: Vec<Decl>,
117    },
118    /// `server system Solar(Charge charge, Block block) every 1t { … }`.
119    System {
120        name: Name,
121        params: Vec<Param>,
122        every: Option<Expr>,
123        body: Block,
124    },
125    Extend {
126        ty: Type,
127        header: TypeHeader,
128        body: Vec<Decl>,
129    },
130    /// `Hardness = 2.0f;` in a content or mod body.
131    Prop(Prop),
132    Screen {
133        name: Name,
134        header: TypeHeader,
135        ui: String,
136        body: Vec<Decl>,
137    },
138    Command {
139        name: String,
140        body: Vec<Decl>,
141    },
142    /// `on Player.Join(Player player) { … }`, `on Use(Player player) { … }`.
143    On {
144        event: Vec<Name>,
145        params: Vec<Param>,
146        body: Block,
147    },
148    Test {
149        name: String,
150        body: Block,
151    },
152    Version {
153        cond: VersionCond,
154        then: Vec<Decl>,
155        otherwise: Option<Vec<Decl>>,
156    },
157    Native {
158        library: String,
159        methods: Vec<Method>,
160    },
161    Patch(Patch),
162}
163
164/// `Name = value;`.
165#[derive(Debug, Clone, PartialEq)]
166pub struct Prop {
167    pub name: Name,
168    pub value: Expr,
169}
170
171/// `int Area(int w, int h) => w * h;`; `ret` None: `void`.
172#[derive(Debug, Clone, PartialEq)]
173pub struct Method {
174    pub ret: Option<Type>,
175    pub name: Name,
176    pub generics: Vec<Name>,
177    pub params: Vec<Param>,
178    pub constraints: Vec<(Name, Vec<Type>)>,
179    pub requires: Option<Expr>,
180    /// None: a signature only (`native`, an interface's).
181    pub body: Option<MethodBody>,
182}
183
184#[derive(Debug, Clone, PartialEq)]
185pub enum MethodBody {
186    Block(Block),
187    Expr(Expr),
188}
189
190/// `saved synced Energy Energy in 0..capacity = 0 was Power: int;`.
191#[derive(Debug, Clone, PartialEq)]
192pub struct Field {
193    pub ty: Type,
194    pub name: Name,
195    pub bound: Option<Expr>,
196    pub value: Option<Expr>,
197    /// What an old save calls it.
198    pub was: Option<(Name, Option<Type>)>,
199}
200
201/// `get;`, `set { … }`, `init;`.
202#[derive(Debug, Clone, PartialEq)]
203pub struct Accessor {
204    pub name: Name,
205    pub body: Option<MethodBody>,
206}
207
208/// `public Timer() : this(20t) { … }`.
209#[derive(Debug, Clone, PartialEq)]
210pub struct Ctor {
211    pub name: Name,
212    pub params: Vec<Param>,
213    pub this_args: Option<Vec<super::Arg>>,
214    pub body: Block,
215}
216
217/// `Player target = source.Player`.
218#[derive(Debug, Clone, PartialEq)]
219pub struct Param {
220    pub ty: Type,
221    pub name: Name,
222    pub default: Option<Expr>,
223}
224
225#[derive(Debug, Clone, PartialEq)]
226pub struct Variant {
227    pub name: Name,
228    pub fields: Vec<Param>,
229}
230
231/// `mc >= 1.21`, `mc 1.20.1..1.21.4`.
232#[derive(Debug, Clone, PartialEq)]
233pub enum VersionCond {
234    Compare { op: super::BinOp, version: String },
235    Range { from: String, to: String },
236}