1use std::collections::HashMap;
2
3use bitflags::bitflags;
4use vec1::Vec1;
5
6use super::interner::{NameSymbol, StringSymbol};
7use crate::ir_common::*;
8use crate::Span;
9
10#[cfg(feature = "serialize")]
11use serde::Serialize;
12
13pub mod lower;
14
15#[cfg_attr(feature = "serialize", derive(Serialize))]
16#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
17#[derive(Debug, Clone, PartialEq)]
18pub enum TopLevelDefinitionKind {
19 Class(ClassDefinition),
20 Struct(StructDefinition),
21 MixinClass(MixinClassDefinition),
22 Enum(EnumDefinition),
23 Const(ConstDefinition),
24}
25#[cfg_attr(feature = "serialize", derive(Serialize))]
26#[derive(Debug, Clone, PartialEq)]
27pub struct TopLevelDefinition {
28 pub span: Span,
29 pub archive_num: usize,
30 #[cfg_attr(feature = "serialize", serde(flatten))]
31 pub kind: TopLevelDefinitionKind,
32}
33
34impl TopLevelDefinition {
35 pub fn name(&self) -> &Identifier {
36 match &self.kind {
37 TopLevelDefinitionKind::Class(c) => &c.name,
38 TopLevelDefinitionKind::Struct(s) => &s.name,
39 TopLevelDefinitionKind::MixinClass(m) => &m.name,
40 TopLevelDefinitionKind::Enum(e) => &e.name,
41 TopLevelDefinitionKind::Const(c) => &c.name,
42 }
43 }
44}
45
46#[cfg_attr(feature = "serialize", derive(Serialize))]
47#[derive(Debug, Clone, PartialEq)]
48pub struct TopLevel {
49 pub definitions: HashMap<NameSymbol, Vec1<TopLevelDefinition>>,
50}
51
52bitflags! {
53 #[cfg_attr(feature = "serialize", derive(Serialize))]
54 pub struct ClassDefinitionFlags: u8 {
55 const ABSTRACT = 1 << 0;
56 const NATIVE = 1 << 1;
57 const UI = 1 << 2;
58 const PLAY = 1 << 3;
59 }
60}
61
62#[cfg_attr(feature = "serialize", derive(Serialize))]
63#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
64#[derive(Debug, Clone, PartialEq)]
65pub enum ClassInnerKind {
66 FunctionDeclaration(FunctionDeclaration),
67 MemberDeclaration(MemberDeclaration),
68 Enum(EnumDefinition),
69 Struct(StructDefinition),
70 Const(ConstDefinition),
71 Property(PropertyDefinition),
72 Flag(FlagDefinition),
73 StaticConstArray(StaticConstArray),
74}
75#[cfg_attr(feature = "serialize", derive(Serialize))]
76#[derive(Debug, Clone, PartialEq)]
77pub struct ClassInner {
78 pub span: Span,
79 #[cfg_attr(feature = "serialize", serde(flatten))]
80 pub kind: ClassInnerKind,
81}
82
83impl ClassInner {
84 pub fn name(&self) -> &Identifier {
85 match &self.kind {
86 ClassInnerKind::FunctionDeclaration(x) => &x.name,
87 ClassInnerKind::MemberDeclaration(x) => &x.name,
88 ClassInnerKind::Enum(x) => &x.name,
89 ClassInnerKind::Struct(x) => &x.name,
90 ClassInnerKind::Const(x) => &x.name,
91 ClassInnerKind::Property(x) => &x.name,
92 ClassInnerKind::StaticConstArray(x) => &x.name,
93 ClassInnerKind::Flag(x) => &x.flag_name,
94 }
95 }
96}
97
98#[cfg_attr(feature = "serialize", derive(Serialize))]
99#[derive(Debug, Clone, PartialEq)]
100pub struct ClassDefinition {
101 pub doc_comment: Option<StringSymbol>,
102 pub span: Span,
103 pub name: Identifier,
104 pub ancestor: Option<Identifier>,
105 pub flags: ClassDefinitionFlags,
106 pub states: Vec<StatesItem>,
107 pub defaults: Vec<DefaultStatement>,
108 pub version: Option<VersionInfo>,
109 pub replaces: Option<DottableId>,
110 pub inners: HashMap<NameSymbol, Vec1<ClassInner>>,
111}
112
113#[cfg_attr(feature = "serialize", derive(Serialize))]
114#[derive(Debug, Clone, PartialEq)]
115pub struct MixinClassDefinition {
116 pub doc_comment: Option<StringSymbol>,
117 pub span: Span,
118 pub name: Identifier,
119 pub states: Vec<StatesItem>,
120 pub defaults: Vec<DefaultStatement>,
121 pub inners: HashMap<NameSymbol, Vec1<ClassInner>>,
122}
123
124bitflags! {
125 #[cfg_attr(feature = "serialize", derive(Serialize))]
126 pub struct StructDefinitionFlags: u8 {
127 const CLEAR_SCOPE = 1 << 0;
128 const ABSTRACT = 1 << 1;
129 const NATIVE = 1 << 2;
130 const UI = 1 << 3;
131 const PLAY = 1 << 4;
132 }
133}
134
135#[cfg_attr(feature = "serialize", derive(Serialize))]
136#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
137#[derive(Debug, Clone, PartialEq)]
138pub enum StructInnerKind {
139 FunctionDeclaration(FunctionDeclaration),
140 MemberDeclaration(MemberDeclaration),
141 Enum(EnumDefinition),
142 Const(ConstDefinition),
143 StaticConstArray(StaticConstArray),
144}
145#[cfg_attr(feature = "serialize", derive(Serialize))]
146#[derive(Debug, Clone, PartialEq)]
147pub struct StructInner {
148 pub span: Span,
149 #[cfg_attr(feature = "serialize", serde(flatten))]
150 pub kind: StructInnerKind,
151}
152
153impl StructInner {
154 pub fn name(&self) -> &Identifier {
155 match &self.kind {
156 StructInnerKind::FunctionDeclaration(x) => &x.name,
157 StructInnerKind::MemberDeclaration(x) => &x.name,
158 StructInnerKind::Enum(x) => &x.name,
159 StructInnerKind::Const(x) => &x.name,
160 StructInnerKind::StaticConstArray(x) => &x.name,
161 }
162 }
163}
164
165#[cfg_attr(feature = "serialize", derive(Serialize))]
166#[derive(Debug, Clone, PartialEq)]
167pub struct StructDefinition {
168 pub doc_comment: Option<StringSymbol>,
169 pub span: Span,
170 pub name: Identifier,
171 pub flags: StructDefinitionFlags,
172 pub version: Option<VersionInfo>,
173 pub inners: HashMap<NameSymbol, Vec1<StructInner>>,
174}
175
176#[cfg_attr(feature = "serialize", derive(Serialize))]
177#[derive(Debug, Clone, PartialEq)]
178pub struct StaticConstArray {
179 pub doc_comment: Option<StringSymbol>,
180 pub span: Span,
181 pub arr_type: Type,
182 pub name: Identifier,
183 pub exprs: ExprList,
184}
185
186bitflags! {
187 #[cfg_attr(feature = "serialize", derive(Serialize))]
188 pub struct FunctionFlags: u16 {
189 const NATIVE = 1 << 0;
190 const STATIC = 1 << 1;
191 const PRIVATE = 1 << 2;
192 const PROTECTED = 1 << 3;
193 const FINAL = 1 << 4;
194 const TRANSIENT = 1 << 5;
195 const VIRTUAL = 1 << 6;
196 const OVERRIDE = 1 << 7;
197 const ABSTRACT = 1 << 8;
198 const VAR_ARG = 1 << 9;
199 const UI = 1 << 10;
200 const PLAY = 1 << 11;
201 const CLEAR_SCOPE = 1 << 12;
202 const VIRTUAL_SCOPE = 1 << 13;
203 }
204}
205
206#[cfg_attr(feature = "serialize", derive(Serialize))]
207#[derive(Debug, Clone, Copy, PartialEq)]
208pub struct Deprecated {
209 pub version: VersionInfo,
210 pub message: Option<StringConst>,
211}
212
213bitflags! {
214 #[cfg_attr(feature = "serialize", derive(Serialize))]
215 pub struct ActionFlags: u8 {
216 const ACTOR = 1 << 0;
217 const OVERLAY = 1 << 1;
218 const WEAPON = 1 << 2;
219 const ITEM = 1 << 3;
220 }
221}
222
223#[cfg_attr(feature = "serialize", derive(Serialize))]
224#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
225#[derive(Debug, Clone, PartialEq)]
226pub enum Type {
227 SingleUserType(Identifier),
228 DottedUserType(DottableId),
229 NativeType(Identifier),
230 ReadonlyType(Identifier),
231 ReadonlyNativeType(Identifier),
232 Class(Option<DottableId>),
233 Map(Box<(Type, Type)>),
234 Array(Box<Type>, Option<Expression>),
235 DynArray(Box<Type>),
236 Let,
237
238 Error,
239}
240
241#[cfg_attr(feature = "serialize", derive(Serialize))]
242#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
243#[derive(Debug, Clone, PartialEq)]
244pub enum TypeListOrVoidKind {
245 TypeList(Vec1<Type>),
246 Void,
247}
248#[cfg_attr(feature = "serialize", derive(Serialize))]
249#[derive(Debug, Clone, PartialEq)]
250pub struct TypeListOrVoid {
251 pub span: Span,
252 #[cfg_attr(feature = "serialize", serde(flatten))]
253 pub kind: TypeListOrVoidKind,
254}
255
256bitflags! {
257 #[cfg_attr(feature = "serialize", derive(Serialize))]
258 pub struct FuncParamFlags: u8 {
259 const IN = 1 << 0;
260 const OUT = 1 << 1;
261 const OPTIONAL = 1 << 2;
262 }
263}
264
265#[cfg_attr(feature = "serialize", derive(Serialize))]
266#[derive(Debug, Clone, PartialEq)]
267pub struct FuncParam {
268 pub span: Span,
269 pub flags: FuncParamFlags,
270 pub param_type: Type,
271 pub name: Identifier,
272 pub init: Option<Expression>,
273}
274
275#[cfg_attr(feature = "serialize", derive(Serialize))]
276#[derive(Debug, Clone, PartialEq)]
277pub struct FuncParams {
278 pub span: Span,
279 pub args: Vec<FuncParam>,
280 pub variadic: bool,
281}
282
283#[cfg_attr(feature = "serialize", derive(Serialize))]
284#[derive(Debug, Clone, PartialEq)]
285pub struct FunctionDeclaration {
286 pub doc_comment: Option<StringSymbol>,
287 pub span: Span,
288 pub name: Identifier,
289 pub constant: bool,
290 pub flags: FunctionFlags,
291 pub deprecated: Option<Deprecated>,
292 pub version: VersionInfo,
293 pub action: Option<ActionFlags>,
294 pub return_types: TypeListOrVoid,
295 pub params: FuncParams,
296 pub body: Option<CompoundStatement>,
297}
298
299bitflags! {
300 #[cfg_attr(feature = "serialize", derive(Serialize))]
301 pub struct MemberFlags: u16 {
302 const NATIVE = 1 << 0;
303 const PRIVATE = 1 << 1;
304 const PROTECTED = 1 << 2;
305 const TRANSIENT = 1 << 3;
306 const READ_ONLY = 1 << 4;
307 const INTERNAL = 1 << 5;
308 const VAR_ARG = 1 << 6;
309 const UI = 1 << 7;
310 const PLAY = 1 << 8;
311
312 const META = 1 << 9;
314
315 const CLEAR_SCOPE = 1 << 10;
317 }
318}
319
320#[cfg_attr(feature = "serialize", derive(Serialize))]
321#[derive(Debug, Clone, PartialEq)]
322pub struct MemberDeclaration {
323 pub doc_comment: Option<StringSymbol>,
324 pub span: Span,
325 pub flags: MemberFlags,
326 pub deprecated: Option<Deprecated>,
327 pub version: VersionInfo,
328 pub member_type: Type,
329 pub name: Identifier,
330}
331
332#[cfg_attr(feature = "serialize", derive(Serialize))]
333#[derive(Debug, Clone, PartialEq)]
334pub struct CompoundStatement {
335 pub span: Option<Span>,
336 pub statements: Vec<Statement>,
337}
338
339#[cfg_attr(feature = "serialize", derive(Serialize))]
340#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
341#[derive(Debug, Clone, PartialEq)]
342pub enum StatementKind {
343 Labeled(LabeledStatement),
344 Compound(CompoundStatement),
345 Expression(Expression),
346 If {
347 cond: Expression,
348 body: CompoundStatement,
349 else_body: Option<CompoundStatement>,
350 },
351 Switch {
352 val: Expression,
353 body: CompoundStatement,
354 },
355 Loop(CompoundStatement),
356 Break,
357 Continue,
358 Return(Option<ExprList>),
359 LocalVariableDefinition(LocalVariableDefinition),
360 MultiAssign {
361 assignees: ExprList,
362 rhs: Expression,
363 },
364 StaticConstArray(StaticConstArray),
365}
366#[cfg_attr(feature = "serialize", derive(Serialize))]
367#[derive(Debug, Clone, PartialEq)]
368pub struct Statement {
369 pub span: Option<Span>,
370 #[cfg_attr(feature = "serialize", serde(flatten))]
371 pub kind: StatementKind,
372}
373
374#[cfg_attr(feature = "serialize", derive(Serialize))]
375#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
376#[derive(Debug, Clone, PartialEq)]
377pub enum VarInit {
378 Single(Expression),
379 Compound(ExprList),
380}
381
382#[cfg_attr(feature = "serialize", derive(Serialize))]
383#[derive(Debug, Clone, PartialEq)]
384pub struct LocalVariableDefinition {
385 pub span: Span,
386 pub var_type: Type,
387 pub name: Identifier,
388 pub init: Option<VarInit>,
389}
390
391#[cfg_attr(feature = "serialize", derive(Serialize))]
392#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
393#[derive(Debug, Clone, PartialEq)]
394pub enum StateLineActionKind {
395 Call {
396 func: Identifier,
397 args: Option<Vec<FunctionCallArg>>,
398 },
399 Anonymous(CompoundStatement),
400}
401#[cfg_attr(feature = "serialize", derive(Serialize))]
402#[derive(Debug, Clone, PartialEq)]
403pub struct StateLineAction {
404 pub span: Span,
405 #[cfg_attr(feature = "serialize", serde(flatten))]
406 pub kind: StateLineActionKind,
407}
408
409bitflags! {
410 #[cfg_attr(feature = "serialize", derive(Serialize))]
411 pub struct StateLineFlags: u8 {
412 const BRIGHT = 1 << 1;
413 const FAST = 1 << 2;
414 const SLOW = 1 << 3;
415 const NO_DELAY = 1 << 4;
416 const CAN_RAISE = 1 << 5;
417 }
418}
419
420#[cfg_attr(feature = "serialize", derive(Serialize))]
421#[derive(Debug, Clone, PartialEq)]
422pub struct StateLine {
423 pub span: Span,
424 pub sprite: NonWhitespace,
425 pub frames: NonWhitespace,
426 pub duration: Expression,
427 pub flags: StateLineFlags,
428 pub action_flags: Option<ActionFlags>,
429 pub offset: Option<(Expression, Expression)>,
430 pub light: Option<Vec1<StringConst>>,
431 pub action: Option<StateLineAction>,
432}
433
434#[cfg_attr(feature = "serialize", derive(Serialize))]
435#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
436#[derive(Debug, Clone, PartialEq)]
437pub enum StateGotoTargetKind {
438 Unscoped(DottableId),
439 Scoped(Identifier, DottableId),
440 Super(DottableId),
441}
442#[cfg_attr(feature = "serialize", derive(Serialize))]
443#[derive(Debug, Clone, PartialEq)]
444pub struct StateGotoTarget {
445 pub span: Span,
446 #[cfg_attr(feature = "serialize", serde(flatten))]
447 pub kind: StateGotoTargetKind,
448}
449
450#[cfg_attr(feature = "serialize", derive(Serialize))]
451#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
452#[derive(Debug, Clone, PartialEq)]
453pub enum StatesItemKind {
454 Label(NonWhitespace),
455 Line(Box<StateLine>),
456 Stop,
457 Wait,
458 Fail,
459 Loop,
460 Goto {
461 target: StateGotoTarget,
462 offset: Option<Expression>,
463 },
464}
465#[cfg_attr(feature = "serialize", derive(Serialize))]
466#[derive(Debug, Clone, PartialEq)]
467pub struct StatesItem {
468 pub span: Span,
469 #[cfg_attr(feature = "serialize", serde(flatten))]
470 pub kind: StatesItemKind,
471}