zscript_parser/ir_common/
mod.rs

1use vec1::Vec1;
2
3use crate::interner::{NameSymbol, StringSymbol};
4use crate::Span;
5
6#[cfg(feature = "serialize")]
7use serde::Serialize;
8
9#[cfg_attr(feature = "serialize", derive(Serialize))]
10#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
11pub struct Identifier {
12    pub span: Span,
13    pub symbol: NameSymbol,
14}
15impl From<Identifier> for NameSymbol {
16    fn from(item: Identifier) -> Self {
17        item.symbol
18    }
19}
20impl From<&Identifier> for NameSymbol {
21    fn from(item: &Identifier) -> Self {
22        item.symbol
23    }
24}
25#[cfg_attr(feature = "serialize", derive(Serialize))]
26#[derive(Debug, Clone, PartialEq)]
27pub struct DottableId {
28    pub span: Span,
29    pub ids: Vec1<Identifier>,
30}
31
32#[cfg_attr(feature = "serialize", derive(Serialize))]
33#[derive(Debug, Clone, Copy, PartialEq)]
34pub struct StringConst {
35    pub span: Span,
36    pub symbol: StringSymbol,
37}
38#[cfg_attr(feature = "serialize", derive(Serialize))]
39#[derive(Debug, Clone, Copy, PartialEq)]
40pub struct NameConst {
41    pub span: Span,
42    pub symbol: NameSymbol,
43}
44#[cfg_attr(feature = "serialize", derive(Serialize))]
45#[derive(Debug, Clone, Copy, PartialEq)]
46pub struct IntConst {
47    pub span: Span,
48    pub val: u64,
49    pub long: bool,
50    pub unsigned: bool,
51}
52#[cfg_attr(feature = "serialize", derive(Serialize))]
53#[derive(Debug, Clone, Copy, PartialEq)]
54pub struct FloatConst {
55    pub span: Span,
56    pub val: f64,
57    pub double: bool,
58}
59#[cfg_attr(feature = "serialize", derive(Serialize))]
60#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
61#[derive(Debug, Clone, Copy, PartialEq)]
62pub enum ConstKind {
63    String(StringConst),
64    Name(NameConst),
65    Int(IntConst),
66    Float(FloatConst),
67    Bool(bool),
68    Null,
69}
70#[cfg_attr(feature = "serialize", derive(Serialize))]
71#[derive(Debug, Clone, Copy, PartialEq)]
72pub struct Const {
73    pub span: Span,
74    #[cfg_attr(feature = "serialize", serde(flatten))]
75    pub kind: ConstKind,
76}
77
78#[cfg_attr(feature = "serialize", derive(Serialize))]
79#[derive(Debug, Clone, Copy, PartialEq)]
80pub struct VersionInfo {
81    pub major: u16,
82    pub minor: u16,
83    pub revision: u16,
84}
85
86impl VersionInfo {
87    pub const fn new(major: u16, minor: u16, revision: u16) -> Self {
88        Self {
89            major,
90            minor,
91            revision,
92        }
93    }
94}
95
96pub(crate) fn parse_lump_version(s: &str) -> Option<VersionInfo> {
97    fn split_once_inclusive(s: &str, p: impl Fn(char) -> bool) -> (&str, &str) {
98        let mut splitter = s.splitn(2, p);
99        let first = splitter.next().unwrap();
100        let second = &s[first.len()..];
101        (first, second)
102    }
103
104    let mut s = s;
105
106    s = split_once_inclusive(s, |c| ![' ', '\n', '\t', '\r'].contains(&c)).1;
107    let (s0, s1) = split_once_inclusive(s, |c| !('0'..'9').contains(&c));
108    s = s1;
109    let major = s0.parse::<u16>().ok()?;
110    if !s.starts_with('.') {
111        return None;
112    }
113    s = &s[1..];
114
115    s = split_once_inclusive(s, |c| ![' ', '\n', '\t', '\r'].contains(&c)).1;
116    let (s0, s1) = split_once_inclusive(s, |c| !('0'..'9').contains(&c));
117    s = s1;
118    let minor = s0.parse::<u16>().ok()?;
119
120    let revision = if s.starts_with('.') {
121        s = &s[1..];
122        s = split_once_inclusive(s, |c| ![' ', '\n', '\t', '\r'].contains(&c)).1;
123        let (s0, s1) = split_once_inclusive(s, |c| !('0'..'9').contains(&c));
124        s = s1;
125        s0.parse::<u16>().ok()?
126    } else {
127        0
128    };
129
130    if s.chars().next() != None {
131        return None;
132    }
133
134    Some(VersionInfo::new(major, minor, revision))
135}
136
137#[cfg_attr(feature = "serialize", derive(Serialize))]
138#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
139#[derive(Debug, Clone, PartialEq)]
140pub enum ExpressionKind {
141    Ident(Identifier),
142    Const(Const),
143    Binary {
144        op: BinaryOp,
145        exprs: Box<BinaryOpExprs>,
146    },
147    Prefix {
148        op: PrefixOp,
149        expr: Box<Expression>,
150    },
151    Postfix {
152        op: PostfixOp,
153        expr: Box<Expression>,
154    },
155    Ternary(Box<TernaryOpExprs>),
156    ArrayIndex(Box<ArrayIndexExprs>),
157    FunctionCall {
158        lhs: Box<Expression>,
159        exprs: Vec<FunctionCallArg>,
160    },
161    Vector2(Box<(Expression, Expression)>),
162    Vector3(Box<(Expression, Expression, Expression)>),
163    ClassCast(Identifier, Vec<FunctionCallArg>),
164    Super,
165
166    Unknown,
167}
168
169#[cfg_attr(feature = "serialize", derive(Serialize))]
170#[derive(Debug, Clone, PartialEq)]
171pub struct Expression {
172    pub span: Option<Span>,
173    #[cfg_attr(feature = "serialize", serde(flatten))]
174    pub kind: ExpressionKind,
175}
176
177#[cfg_attr(feature = "serialize", derive(Serialize))]
178#[derive(Debug, Clone, Copy, PartialEq)]
179pub enum BinaryOp {
180    Add,
181    Subtract,
182    Times,
183    Divide,
184    Modulo,
185    Raise,
186
187    LeftShift,
188    RightShift,
189    UnsignedRightShift,
190
191    CrossProd,
192    DotProd,
193    Concat,
194
195    LessThan,
196    LessThanEquals,
197    GreaterThan,
198    GreaterThanEquals,
199    Equals,
200    NotEquals,
201    ApproxEquals,
202    ThreeWayComp,
203
204    LogicalAnd,
205    BitwiseAnd,
206    LogicalOr,
207    BitwiseOr,
208    BitwiseXor,
209
210    Is,
211    Scope,
212    MemberAccess,
213
214    Assign,
215    PlusAssign,
216    MinusAssign,
217    TimesAssign,
218    DivideAssign,
219    ModuloAssign,
220    LeftShiftAssign,
221    RightShiftAssign,
222    UnsignedRightShiftAssign,
223    BitwiseOrAssign,
224    BitwiseAndAssign,
225    BitwiseXorAssign,
226}
227
228#[cfg_attr(feature = "serialize", derive(Serialize))]
229#[derive(Debug, Clone, Copy, PartialEq)]
230pub enum PrefixOp {
231    Plus,
232    Minus,
233    Increment,
234    Decrement,
235    LogicalNot,
236    BitwiseNot,
237    SizeOf,
238    AlignOf,
239}
240
241#[cfg_attr(feature = "serialize", derive(Serialize))]
242#[derive(Debug, Clone, Copy, PartialEq)]
243pub enum PostfixOp {
244    Increment,
245    Decrement,
246}
247
248#[cfg_attr(feature = "serialize", derive(Serialize))]
249#[derive(Debug, Clone, PartialEq)]
250pub enum LabeledStatement {
251    Default,
252    Case(Box<Expression>),
253}
254
255#[cfg_attr(feature = "serialize", derive(Serialize))]
256#[derive(Debug, Clone, PartialEq)]
257pub struct ExprList {
258    pub span: Span,
259    pub list: Vec1<Expression>,
260}
261
262#[cfg_attr(feature = "serialize", derive(Serialize))]
263#[derive(Debug, Clone, PartialEq)]
264pub struct ArraySizes {
265    pub span: Span,
266    pub list: Vec1<Option<Expression>>,
267}
268
269#[cfg_attr(feature = "serialize", derive(Serialize))]
270#[derive(Debug, Clone, PartialEq)]
271pub struct BinaryOpExprs {
272    pub lhs: Expression,
273    pub rhs: Expression,
274}
275
276#[cfg_attr(feature = "serialize", derive(Serialize))]
277#[derive(Debug, Clone, PartialEq)]
278pub struct TernaryOpExprs {
279    pub cond: Expression,
280    pub if_true: Expression,
281    pub if_false: Expression,
282}
283
284#[cfg_attr(feature = "serialize", derive(Serialize))]
285#[derive(Debug, Clone, PartialEq)]
286pub struct ArrayIndexExprs {
287    pub lhs: Expression,
288    pub index: Expression,
289}
290
291#[cfg_attr(feature = "serialize", derive(Serialize))]
292#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
293#[derive(Debug, Clone, PartialEq)]
294pub enum FunctionCallArgKind {
295    Unnamed(Expression),
296    Named(Identifier, Expression),
297}
298#[cfg_attr(feature = "serialize", derive(Serialize))]
299#[derive(Debug, Clone, PartialEq)]
300pub struct FunctionCallArg {
301    pub span: Span,
302    #[cfg_attr(feature = "serialize", serde(flatten))]
303    pub kind: FunctionCallArgKind,
304}
305
306#[cfg_attr(feature = "serialize", derive(Serialize))]
307#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
308#[derive(Debug, Clone, PartialEq)]
309pub enum IntTypeKind {
310    SByte,
311    Byte,
312    Short,
313    UShort,
314    Int,
315    UInt,
316}
317#[cfg_attr(feature = "serialize", derive(Serialize))]
318#[derive(Debug, Clone, PartialEq)]
319pub struct IntType {
320    pub span: Span,
321    #[cfg_attr(feature = "serialize", serde(flatten))]
322    pub kind: IntTypeKind,
323}
324
325#[cfg_attr(feature = "serialize", derive(Serialize))]
326#[derive(Debug, Clone, PartialEq)]
327pub struct EnumVariant {
328    pub doc_comment: Option<StringSymbol>,
329    pub span: Span,
330    pub name: Identifier,
331    pub init: Option<Expression>,
332}
333
334#[cfg_attr(feature = "serialize", derive(Serialize))]
335#[derive(Debug, Clone, PartialEq)]
336pub struct EnumDefinition {
337    pub doc_comment: Option<StringSymbol>,
338    pub span: Span,
339    pub name: Identifier,
340    pub enum_type: Option<IntType>,
341    pub variants: Vec<EnumVariant>,
342}
343
344#[cfg_attr(feature = "serialize", derive(Serialize))]
345#[derive(Debug, Clone, PartialEq)]
346pub struct ConstDefinition {
347    pub doc_comment: Option<StringSymbol>,
348    pub span: Span,
349    pub name: Identifier,
350    pub expr: Expression,
351}
352
353#[cfg_attr(feature = "serialize", derive(Serialize))]
354#[derive(Debug, Clone, PartialEq)]
355pub struct FlagDefinition {
356    pub doc_comment: Option<StringSymbol>,
357    pub span: Span,
358    pub flag_name: Identifier,
359    pub var_name: Identifier,
360    pub shift: IntConst,
361}
362
363#[cfg_attr(feature = "serialize", derive(Serialize))]
364#[derive(Debug, Clone, PartialEq)]
365pub struct PropertyDefinition {
366    pub doc_comment: Option<StringSymbol>,
367    pub span: Span,
368    pub name: Identifier,
369    pub vars: Vec1<Identifier>,
370}
371
372#[cfg_attr(feature = "serialize", derive(Serialize))]
373#[cfg_attr(feature = "serialize", serde(tag = "kind", content = "data"))]
374#[derive(Debug, Clone, PartialEq)]
375pub enum DefaultStatementKind {
376    Property {
377        prop: DottableId,
378        vals: Option<ExprList>,
379    },
380    AddFlag(DottableId),
381    RemoveFlag(DottableId),
382}
383#[cfg_attr(feature = "serialize", derive(Serialize))]
384#[derive(Debug, Clone, PartialEq)]
385pub struct DefaultStatement {
386    pub span: Span,
387    #[cfg_attr(feature = "serialize", serde(flatten))]
388    pub kind: DefaultStatementKind,
389}
390
391#[cfg_attr(feature = "serialize", derive(Serialize))]
392#[derive(Debug, Clone, PartialEq)]
393pub struct DefaultDefinition {
394    pub span: Span,
395    pub statements: Vec<DefaultStatement>,
396}
397
398#[cfg_attr(feature = "serialize", derive(Serialize))]
399#[derive(Debug, Clone, PartialEq)]
400pub struct NonWhitespace {
401    pub span: Span,
402    pub symbol: NameSymbol,
403}