1use 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#[derive(Clone, PartialEq, Debug)]
18pub struct Statement {
19 pub body: StatementBody,
20 pub arrow: bool, pub pos: FileRange,
22 }
24
25#[derive(Clone, PartialEq, Debug)]
26pub enum StatementBody {
27 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 }
45#[derive(Clone, PartialEq, Debug)]
46pub struct ValueLiteral {
47 pub body: ValueBody,
48 }
50
51impl ValueLiteral {
52 pub fn new(body: ValueBody) -> Self {
53 ValueLiteral {
54 body,
55 }
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 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 }
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 tag: Attribute::new(),
268 }],
269 operators: Vec::new(),
270 },
271 pos,
272 }
273 }
274}
275
276#[derive(Clone, PartialEq, Debug)]
284pub struct Call {
285 pub function: Variable,
286}
287
288pub 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 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}