spwn/
ast.rs

1//! Abstract Syntax Tree (AST) type definitions
2
3use internment::Intern;
4
5use crate::compiler_types::ImportType;
6use crate::fmt::SpwnFmt;
7use crate::parser::FileRange;
8use crate::value_storage::StoredValue;
9#[derive(Clone, PartialEq, Debug)]
10pub enum DictDef {
11    Def((Intern<String>, Expression)),
12    Extract(Expression),
13}
14
15//pub type Comment = (Option<String>, Option<String>);
16
17#[derive(Clone, PartialEq, Debug)]
18pub struct Statement {
19    pub body: StatementBody,
20    pub arrow: bool, /*context changing */
21    pub pos: FileRange,
22    //pub comment: Comment,
23}
24
25#[derive(Clone, PartialEq, Debug)]
26pub enum StatementBody {
27    //Definition(Definition),
28    Call(Call),
29    Expr(Expression),
30
31    TypeDef(String),
32
33    Return(Option<Expression>),
34    Impl(Implementation),
35    If(If),
36    For(For),
37    While(While),
38    Error(Error),
39    Extract(Expression),
40
41    Break,
42    Continue,
43    //EOI,
44}
45#[derive(Clone, PartialEq, Debug)]
46pub struct ValueLiteral {
47    pub body: ValueBody,
48    //pub comment: Comment,
49}
50
51impl ValueLiteral {
52    pub fn new(body: ValueBody) -> Self {
53        ValueLiteral {
54            body,
55            //comment: (None, None),
56        }
57    }
58}
59
60#[derive(Clone, PartialEq, Debug)]
61pub enum ValueBody {
62    Id(Id),
63    Number(f64),
64    CmpStmt(CompoundStatement),
65    Dictionary(Vec<DictDef>),
66    Symbol(Intern<String>),
67    Bool(bool),
68    Expression(Expression),
69    Str(StrInner),
70    Import(ImportType, bool),
71    Switch(Expression, Vec<Case>),
72    Array(Vec<Expression>),
73    ListComp(Comprehension),
74    Obj(ObjectLiteral),
75    Macro(Macro),
76    Resolved(StoredValue),
77    TypeIndicator(String),
78    SelfVal,
79    Ternary(Ternary),
80    Null,
81}
82
83impl ValueBody {
84    pub fn to_variable(&self, pos: FileRange) -> Variable {
85        Variable {
86            value: ValueLiteral { body: self.clone() },
87            operator: None,
88            pos,
89            //comment: (None, None),
90            path: Vec::new(),
91            tag: Attribute::new(),
92        }
93    }
94}
95
96#[derive(Clone, PartialEq, Debug, Copy)]
97pub enum ObjectMode {
98    Object,
99    Trigger,
100}
101
102#[derive(Clone, PartialEq, Debug)]
103pub struct ObjectLiteral {
104    pub props: Vec<(Expression, Expression)>,
105    pub mode: ObjectMode,
106}
107
108#[derive(Clone, PartialEq, Debug)]
109pub struct StrInner {
110    pub inner: String,
111    pub flags: Option<StringFlags>,
112}
113
114#[derive(Clone, PartialEq, Debug)]
115pub enum StringFlags {
116    Raw,
117}
118
119#[derive(Clone, Copy, PartialEq, Debug)]
120pub enum Operator {
121    Or,
122    And,
123    Equal,
124    NotEqual,
125    Range,
126    MoreOrEqual,
127    LessOrEqual,
128    More,
129    Less,
130    Slash,
131    IntDividedBy,
132    Star,
133    Power,
134    Plus,
135    Minus,
136    Modulo,
137
138    Either,
139
140    Assign,
141    Add,
142    Subtract,
143    Multiply,
144    Divide,
145    IntDivide,
146    As,
147    Has,
148
149    Exponate,
150    Modulate,
151    Swap,
152}
153
154#[derive(Clone, PartialEq, Debug)]
155pub enum UnaryOperator {
156    Not,
157    Minus,
158    Range,
159    Let,
160    Increment,
161    Decrement,
162}
163
164#[derive(Clone, PartialEq, Debug)]
165pub enum IdClass {
166    Group,
167    Color,
168    Item,
169    Block,
170}
171
172#[derive(Clone, PartialEq, Debug)]
173pub struct Attribute {
174    pub tags: Vec<(String, Vec<Argument>)>,
175}
176
177impl Attribute {
178    pub fn new() -> Self {
179        Attribute { tags: Vec::new() }
180    }
181    pub fn get(&self, t: &str) -> Option<Vec<Argument>> {
182        for (key, args) in &self.tags {
183            if t == key {
184                return Some(args.clone());
185            }
186        }
187        None
188    }
189
190    pub fn get_desc(&self) -> Option<String> {
191        match self.get("desc") {
192            Some(args) => {
193                if args.is_empty() {
194                    None
195                } else {
196                    match &args[0].value.values[0].value.body {
197                        ValueBody::Str(s) => Some(s.inner.clone()),
198                        a => Some(a.fmt(0)),
199                    }
200                }
201            }
202
203            None => None,
204        }
205    }
206
207    pub fn get_example(&self) -> Option<String> {
208        if let Some(args) = self.get("example") {
209            if args.is_empty() {
210                None
211            } else {
212                match &args[0].value.values[0].value.body {
213                    ValueBody::Str(s) => Some(s.inner.trim().to_string()),
214                    val => Some(val.fmt(0)),
215                }
216            }
217        } else {
218            None
219        }
220    }
221}
222
223#[derive(Clone, PartialEq, Debug)]
224pub enum Path {
225    Member(Intern<String>),
226    Associated(Intern<String>),
227    Index(Expression),
228    NSlice(Vec<Slice>),
229    Call(Vec<Argument>),
230    Constructor(Vec<DictDef>),
231    Increment,
232    Decrement,
233}
234
235#[derive(Clone, PartialEq, Debug)]
236pub struct Definition {
237    pub symbol: Intern<String>,
238    pub value: Expression,
239    //pub mutable: bool,
240}
241
242#[derive(Clone, PartialEq, Debug)]
243pub struct Argument {
244    pub symbol: Option<Intern<String>>,
245    pub value: Expression,
246    pub pos: FileRange,
247}
248
249#[derive(Clone, PartialEq, Debug)]
250pub struct Slice {
251    pub left: Option<Expression>,
252    pub right: Option<Expression>,
253    pub step: Option<Expression>,
254}
255
256impl Argument {
257    pub fn from(val: StoredValue, pos: FileRange) -> Self {
258        Argument {
259            symbol: None,
260            value: Expression {
261                values: vec![Variable {
262                    value: ValueLiteral::new(ValueBody::Resolved(val)),
263                    path: Vec::new(),
264                    operator: None,
265                    pos,
266                    //comment: (None, None),
267                    tag: Attribute::new(),
268                }],
269                operators: Vec::new(),
270            },
271            pos,
272        }
273    }
274}
275
276/*#[derive(Clone, PartialEq, Debug)]
277pub struct Event {
278    pub symbol: String,
279    pub args: Vec<Expression>,
280    pub func: Variable,
281}*/
282
283#[derive(Clone, PartialEq, Debug)]
284pub struct Call {
285    pub function: Variable,
286}
287
288/*#[derive(Clone, PartialEq, Debug)]
289pub struct Native {
290    pub function: Variable,
291    pub args: Vec<Argument>,
292}*/
293//     name     def value     props     type ind.     location in file     is reference
294pub type ArgDef = (
295    Intern<String>,
296    Option<Expression>,
297    Attribute,
298    Option<Expression>,
299    FileRange,
300    bool,
301);
302#[derive(Clone, PartialEq, Debug)]
303pub struct Macro {
304    pub args: Vec<ArgDef>,
305    pub body: CompoundStatement,
306    pub properties: Attribute,
307    pub arg_pos: FileRange,
308}
309
310#[derive(Clone, PartialEq, Debug)]
311pub struct For {
312    pub symbol: Intern<String>,
313    pub array: Expression,
314    pub body: Vec<Statement>,
315}
316
317#[derive(Clone, PartialEq, Debug)]
318pub struct While {
319    pub condition: Expression,
320    pub body: Vec<Statement>,
321}
322
323#[derive(Clone, PartialEq, Debug)]
324pub enum CaseType {
325    Value(Expression),
326    Pattern(Expression),
327    Default,
328}
329
330#[derive(Clone, PartialEq, Debug)]
331pub struct Case {
332    pub typ: CaseType,
333    pub body: Expression,
334}
335
336#[derive(Clone, PartialEq, Debug)]
337pub struct Switch {
338    pub value: Expression,
339    pub cases: Vec<Case>,
340}
341
342#[derive(Clone, PartialEq, Debug)]
343pub struct Error {
344    pub message: Expression,
345}
346
347#[derive(Clone, PartialEq, Debug)]
348pub struct Variable {
349    pub operator: Option<UnaryOperator>,
350    pub value: ValueLiteral,
351    pub path: Vec<Path>,
352    pub pos: FileRange,
353    pub tag: Attribute,
354}
355
356impl Variable {
357    pub fn to_expression(&self) -> Expression {
358        if let ValueBody::Expression(e) = &self.value.body {
359            if self.path.is_empty() {
360                return e.to_owned();
361            }
362        }
363        Expression {
364            values: vec![self.clone()],
365            operators: Vec::new(),
366        }
367    }
368}
369
370#[derive(Clone, PartialEq, Debug)]
371pub struct Expression {
372    pub values: Vec<Variable>,
373    pub operators: Vec<Operator>,
374}
375
376#[derive(Clone, PartialEq, Debug)]
377pub struct Ternary {
378    pub condition: Expression,
379    pub if_expr: Expression,
380    pub else_expr: Expression,
381}
382
383#[derive(Clone, PartialEq, Debug)]
384pub struct Comprehension {
385    pub symbol: Intern<String>,
386    pub iterator: Expression,
387    pub condition: Option<Expression>,
388    pub body: Expression,
389}
390
391impl Expression {
392    pub fn to_variable(&self) -> Variable {
393        Variable {
394            operator: None,
395            value: ValueLiteral::new(ValueBody::Expression(self.clone())),
396            pos: self.get_pos(),
397            path: Vec::new(),
398            //comment: (None, None),
399            tag: Attribute::new(),
400        }
401    }
402
403    pub fn get_pos(&self) -> FileRange {
404        let start = self.values.first().unwrap().pos.0;
405        let end = self.values.last().unwrap().pos.1;
406        (start, end)
407    }
408}
409
410#[derive(Clone, PartialEq, Debug)]
411pub struct CompoundStatement {
412    pub statements: Vec<Statement>,
413}
414
415#[derive(Clone, PartialEq, Debug)]
416pub struct Implementation {
417    pub symbol: Variable,
418    pub members: Vec<DictDef>,
419}
420
421#[derive(Clone, PartialEq, Debug)]
422pub struct If {
423    pub condition: Expression,
424    pub if_body: Vec<Statement>,
425    pub else_body: Option<Vec<Statement>>,
426}
427
428#[derive(Clone, PartialEq, Debug)]
429pub struct Id {
430    pub number: u16,
431    pub unspecified: bool,
432    pub class_name: IdClass,
433}