1use crate::types::semantic::{ExtendedExpression, SemanticContextInstruction};
7use nom_locate::LocatedSpan;
8#[cfg(feature = "codec")]
9use serde::{
10 de::{self, Deserializer, MapAccess, Visitor},
11 ser::{SerializeStruct, Serializer},
12 Deserialize, Serialize,
13};
14use std::convert::Infallible;
15use std::marker::PhantomData;
16
17pub const MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS: u8 = 9;
19
20#[derive(Clone, Debug, Copy, PartialEq, Eq)]
22pub struct Ident<'a>(LocatedSpan<&'a str>);
23
24impl<'a> Ident<'a> {
26 #[must_use]
27 pub fn new(ident: &'a str) -> Self {
28 Self(LocatedSpan::new(ident))
29 }
30
31 #[must_use]
32 pub fn fragment(&self) -> &'a str {
33 self.0.fragment()
34 }
35
36 #[must_use]
37 pub fn location_line(&self) -> u32 {
38 self.0.location_line()
39 }
40
41 #[must_use]
42 pub fn location_offset(&self) -> usize {
43 self.0.location_offset()
44 }
45}
46
47impl std::fmt::Display for Ident<'_> {
48 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
49 write!(f, "{}", self.fragment())
50 }
51}
52
53impl<'a> From<&'a str> for Ident<'a> {
54 fn from(value: &'a str) -> Self {
55 Ident::new(value)
56 }
57}
58
59#[cfg(feature = "codec")]
61impl Serialize for Ident<'_> {
62 fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
63 where
64 S: Serializer,
65 {
66 let fragment = self.0.into_fragment_and_extra();
67 let mut state = serializer.serialize_struct("Ident", 4)?;
68 state.serialize_field("offset", &self.0.location_offset())?;
69 state.serialize_field("line", &self.0.location_line())?;
70 state.serialize_field("fragment", &fragment.0)?;
71 state.serialize_field("extra", &fragment.1)?;
72 state.end()
73 }
74}
75
76#[cfg(feature = "codec")]
78impl<'de: 'a, 'a> Deserialize<'de> for Ident<'a> {
79 fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
80 where
81 D: Deserializer<'de>,
82 {
83 struct IdentVisitor<'a> {
85 marker: PhantomData<fn() -> Ident<'a>>,
86 }
87
88 impl<'de: 'a, 'a> Visitor<'de> for IdentVisitor<'a> {
89 type Value = Ident<'de>;
90
91 fn expecting(&self, formatter: &mut std::fmt::Formatter) -> std::fmt::Result {
92 formatter.write_str("struct Ident")
93 }
94
95 fn visit_map<V>(self, mut map: V) -> Result<Ident<'de>, V::Error>
96 where
97 V: MapAccess<'de>,
98 {
99 let mut offset = None;
100 let mut line = None;
101 let mut fragment = None;
102 let mut extra = None;
103 while let Some(key) = map.next_key::<String>()? {
104 match key.as_str() {
105 "offset" => {
106 if offset.is_some() {
107 return Err(de::Error::duplicate_field("offset"));
108 }
109 offset = Some(map.next_value()?);
110 }
111 "line" => {
112 if line.is_some() {
113 return Err(de::Error::duplicate_field("line"));
114 }
115 line = Some(map.next_value()?);
116 }
117 "fragment" => {
118 if fragment.is_some() {
119 return Err(de::Error::duplicate_field("fragment"));
120 }
121 fragment = Some(map.next_value()?);
122 }
123 "extra" => {
124 if extra.is_some() {
125 return Err(de::Error::duplicate_field("extra"));
126 }
127 extra = Some(map.next_value()?);
128 }
129 _ => return Err(de::Error::unknown_field(&key, FIELDS)),
130 }
131 }
132 let offset = offset.ok_or_else(|| de::Error::missing_field("offset"))?;
133 let line = line.ok_or_else(|| de::Error::missing_field("line"))?;
134 let fragment = fragment.ok_or_else(|| de::Error::missing_field("fragment"))?;
135 #[allow(clippy::let_unit_value)]
136 let extra = extra.ok_or_else(|| de::Error::missing_field("extra"))?;
137 let located =
138 unsafe { LocatedSpan::new_from_raw_offset(offset, line, fragment, extra) };
139 Ok(Ident(located))
140 }
141 }
143
144 const FIELDS: &[&str] = &["offset", "line", "fragment", "extra"];
145 deserializer.deserialize_struct(
146 "Ident",
147 FIELDS,
148 IdentVisitor {
149 marker: PhantomData,
150 },
151 )
152 }
153}
154
155pub trait GetName {
157 fn name(&self) -> String;
158}
159
160pub trait GetLocation {
163 fn location(&self) -> CodeLocation;
164}
165
166#[derive(Debug, Clone, PartialEq, Eq)]
168#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
169pub struct ImportName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
170
171impl GetName for ImportName<'_> {
172 fn name(&self) -> String {
173 (*self.0.fragment()).to_string()
174 }
175}
176
177impl<'a> ImportName<'a> {
178 #[must_use]
179 pub const fn new(ident: Ident<'a>) -> Self {
180 Self(ident)
181 }
182}
183
184pub type ImportPath<'a> = Vec<ImportName<'a>>;
186
187#[derive(Debug, Clone, PartialEq, Eq)]
189#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
190pub struct ConstantName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
191
192impl<'a> ConstantName<'a> {
193 #[must_use]
195 pub const fn new(name: Ident<'a>) -> Self {
196 Self(name)
197 }
198}
199
200impl GetLocation for ConstantName<'_> {
201 fn location(&self) -> CodeLocation {
202 CodeLocation::new(self.0.location_line(), self.0.location_offset())
203 }
204}
205
206impl GetName for ConstantName<'_> {
207 fn name(&self) -> String {
208 (*self.0.fragment()).to_string()
209 }
210}
211
212#[derive(Debug, Clone, PartialEq, Eq)]
214#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
215pub struct FunctionName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
216
217impl<'a> FunctionName<'a> {
218 #[must_use]
219 pub const fn new(name: Ident<'a>) -> Self {
220 Self(name)
221 }
222}
223
224impl GetLocation for FunctionName<'_> {
225 fn location(&self) -> CodeLocation {
226 CodeLocation::new(self.0.location_line(), self.0.location_offset())
227 }
228}
229
230impl std::fmt::Display for FunctionName<'_> {
231 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
232 write!(f, "{}", self.0.fragment())
233 }
234}
235
236#[derive(Debug, Clone, PartialEq, Eq)]
239#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
240pub struct ParameterName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
241
242impl<'a> ParameterName<'a> {
243 #[must_use]
244 pub const fn new(name: Ident<'a>) -> Self {
245 Self(name)
246 }
247}
248
249impl std::fmt::Display for ParameterName<'_> {
250 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
251 write!(f, "{}", self.0.fragment())
252 }
253}
254
255#[derive(Debug, Clone, PartialEq, Eq)]
261#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
262pub struct ValueName<'a>(#[cfg_attr(feature = "codec", serde(borrow))] Ident<'a>);
263
264impl<'a> ValueName<'a> {
265 #[must_use]
266 pub const fn new(name: Ident<'a>) -> Self {
267 Self(name)
268 }
269}
270
271impl GetLocation for ValueName<'_> {
272 fn location(&self) -> CodeLocation {
273 CodeLocation::new(self.0.location_line(), self.0.location_offset())
274 }
275}
276
277impl GetName for ValueName<'_> {
278 fn name(&self) -> String {
279 (*self.0.fragment()).to_string()
280 }
281}
282
283#[derive(Debug, Clone, PartialEq, Eq)]
286#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
287pub struct CodeLocation(u32, usize);
288
289impl CodeLocation {
290 #[must_use]
294 pub const fn new(location: u32, offset: usize) -> Self {
295 Self(location, offset)
296 }
297
298 #[must_use]
300 pub const fn line(&self) -> u32 {
301 self.0
302 }
303
304 #[must_use]
306 pub const fn offset(&self) -> usize {
307 self.1
308 }
309}
310
311#[derive(Debug, Clone, PartialEq, Eq)]
314#[cfg_attr(
315 feature = "codec",
316 derive(Serialize, Deserialize),
317 serde(tag = "type", content = "content")
318)]
319pub enum PrimitiveTypes {
320 U8,
321 U16,
322 U32,
323 U64,
324 I8,
325 I16,
326 I32,
327 I64,
328 F32,
329 F64,
330 Bool,
331 Char,
332 Ptr,
333 None,
334}
335
336impl GetName for PrimitiveTypes {
337 fn name(&self) -> String {
338 match self {
339 Self::U8 => "u8".to_string(),
340 Self::U16 => "u16".to_string(),
341 Self::U32 => "u32".to_string(),
342 Self::U64 => "u64".to_string(),
343 Self::I8 => "i8".to_string(),
344 Self::I16 => "i16".to_string(),
345 Self::I32 => "i32".to_string(),
346 Self::I64 => "i64".to_string(),
347 Self::F32 => "f32".to_string(),
348 Self::F64 => "f64".to_string(),
349 Self::Bool => "bool".to_string(),
350 Self::Char => "char".to_string(),
351 Self::Ptr => "ptr".to_string(),
352 Self::None => "()".to_string(),
353 }
354 }
355}
356
357#[derive(Debug, Clone, PartialEq, Eq)]
362#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
363pub struct ExpressionStructValue<'a> {
364 #[cfg_attr(feature = "codec", serde(borrow))]
366 pub name: ValueName<'a>,
367 pub attribute: ValueName<'a>,
369}
370
371#[derive(Debug, Clone, PartialEq)]
376#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
377pub struct StructType<'a> {
378 #[cfg_attr(feature = "codec", serde(borrow))]
380 pub attr_name: Ident<'a>,
381 pub attr_type: Type<'a>,
383}
384
385impl GetName for StructType<'_> {
386 fn name(&self) -> String {
387 (*self.attr_name.fragment()).to_string()
388 }
389}
390
391#[derive(Debug, Clone, PartialEq)]
394#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
395pub struct StructTypes<'a> {
396 #[cfg_attr(feature = "codec", serde(borrow))]
398 pub name: Ident<'a>,
399 pub attributes: Vec<StructType<'a>>,
401}
402
403impl GetLocation for StructTypes<'_> {
404 fn location(&self) -> CodeLocation {
405 CodeLocation::new(self.name.location_line(), self.name.location_offset())
406 }
407}
408
409impl GetName for StructTypes<'_> {
410 fn name(&self) -> String {
411 (*self.name.fragment()).to_string()
412 }
413}
414
415#[derive(Debug, Clone, PartialEq)]
421#[cfg_attr(
422 feature = "codec",
423 derive(Serialize, Deserialize),
424 serde(tag = "type", content = "content")
425)]
426pub enum Type<'a> {
427 Primitive(PrimitiveTypes),
428 #[cfg_attr(feature = "codec", serde(borrow))]
429 Struct(StructTypes<'a>),
430 Array(Box<Self>, u32),
431}
432
433impl GetName for Type<'_> {
434 fn name(&self) -> String {
435 match self {
436 Self::Primitive(primitive) => primitive.name(),
437 Self::Struct(struct_type) => (*struct_type.name.fragment()).to_string(),
438 Self::Array(array_type, size) => {
439 format!("[{:?};{:?}]", array_type.name(), size)
440 }
441 }
442 }
443}
444
445#[derive(Debug, Clone, PartialEq)]
450#[cfg_attr(
451 feature = "codec",
452 derive(Serialize, Deserialize),
453 serde(tag = "type", content = "content")
454)]
455pub enum ConstantValue<'a> {
456 #[cfg_attr(feature = "codec", serde(borrow))]
457 Constant(ConstantName<'a>),
458 Value(PrimitiveValue),
459}
460
461#[derive(Debug, Clone, PartialEq)]
468#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
469pub struct ConstantExpression<'a> {
470 #[cfg_attr(feature = "codec", serde(borrow))]
472 pub value: ConstantValue<'a>,
473 pub operation: Option<(ExpressionOperations, Box<ConstantExpression<'a>>)>,
475}
476
477#[derive(Debug, Clone, PartialEq)]
483#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
484pub struct Constant<'a> {
485 #[cfg_attr(feature = "codec", serde(borrow))]
487 pub name: ConstantName<'a>,
488 pub constant_type: Type<'a>,
490 pub constant_value: ConstantExpression<'a>,
492}
493
494impl GetLocation for Constant<'_> {
495 fn location(&self) -> CodeLocation {
496 self.name.location()
497 }
498}
499
500impl GetName for Constant<'_> {
501 fn name(&self) -> String {
502 (*self.name.0.fragment()).to_string()
503 }
504}
505
506#[derive(Debug, Clone, PartialEq)]
509#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
510pub struct FunctionParameter<'a> {
511 #[cfg_attr(feature = "codec", serde(borrow))]
513 pub name: ParameterName<'a>,
514 pub parameter_type: Type<'a>,
516}
517
518#[derive(Debug, Clone, PartialEq)]
522#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
523pub struct FunctionStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
524 #[cfg_attr(feature = "codec", serde(borrow))]
526 pub name: FunctionName<'a>,
527 pub parameters: Vec<FunctionParameter<'a>>,
529 pub result_type: Type<'a>,
531 pub body: Vec<BodyStatement<'a, I, E>>,
533 _marker: PhantomData<I>,
534}
535
536impl<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> FunctionStatement<'a, I, E> {
537 #[must_use]
538 pub const fn new(
539 name: FunctionName<'a>,
540 parameters: Vec<FunctionParameter<'a>>,
541 result_type: Type<'a>,
542 body: Vec<BodyStatement<'a, I, E>>,
543 ) -> Self {
544 Self {
545 name,
546 parameters,
547 result_type,
548 body,
549 _marker: PhantomData,
550 }
551 }
552}
553
554impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
555 for FunctionStatement<'_, I, E>
556{
557 fn location(&self) -> CodeLocation {
558 self.name.location()
559 }
560}
561
562impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName
563 for FunctionStatement<'_, I, E>
564{
565 fn name(&self) -> String {
566 (*self.name.0.fragment()).to_string()
567 }
568}
569
570#[derive(Debug, Clone, PartialEq)]
574#[cfg_attr(
575 feature = "codec",
576 derive(Serialize, Deserialize),
577 serde(tag = "type", content = "content")
578)]
579pub enum PrimitiveValue {
580 U8(u8),
581 U16(u16),
582 U32(u32),
583 U64(u64),
584 I8(i8),
585 I16(i16),
586 I32(i32),
587 I64(i64),
588 F32(f32),
589 F64(f64),
590 Bool(bool),
591 Char(char),
592 Ptr,
593 None,
594}
595
596impl PrimitiveValue {
597 #[must_use]
598 pub const fn get_type(&self) -> Type<'_> {
599 match self {
600 Self::U8(_) => Type::Primitive(PrimitiveTypes::U8),
601 Self::U16(_) => Type::Primitive(PrimitiveTypes::U16),
602 Self::U32(_) => Type::Primitive(PrimitiveTypes::U32),
603 Self::U64(_) => Type::Primitive(PrimitiveTypes::U64),
604 Self::I8(_) => Type::Primitive(PrimitiveTypes::I8),
605 Self::I16(_) => Type::Primitive(PrimitiveTypes::I16),
606 Self::I32(_) => Type::Primitive(PrimitiveTypes::I32),
607 Self::I64(_) => Type::Primitive(PrimitiveTypes::I64),
608 Self::F32(_) => Type::Primitive(PrimitiveTypes::F32),
609 Self::F64(_) => Type::Primitive(PrimitiveTypes::F64),
610 Self::Char(_) => Type::Primitive(PrimitiveTypes::Char),
611 Self::Bool(_) => Type::Primitive(PrimitiveTypes::Bool),
612 Self::Ptr => Type::Primitive(PrimitiveTypes::Ptr),
613 Self::None => Type::Primitive(PrimitiveTypes::None),
614 }
615 }
616}
617
618#[derive(Debug, Clone, PartialEq)]
628#[cfg_attr(
629 feature = "codec",
630 derive(Serialize, Deserialize),
631 serde(tag = "type", content = "content")
632)]
633pub enum ExpressionValue<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
634 #[cfg_attr(feature = "codec", serde(borrow))]
636 ValueName(ValueName<'a>),
637 PrimitiveValue(PrimitiveValue),
639 FunctionCall(FunctionCall<'a, I, E>),
641 StructValue(ExpressionStructValue<'a>),
643 Expression(Box<Expression<'a, I, E>>),
645 ExtendedExpression(Box<E>),
647 #[cfg_attr(feature = "codec", serde(skip))]
648 #[allow(non_camel_case_types)]
649 _marker(Infallible, PhantomData<I>),
650}
651
652#[derive(Debug, Clone, PartialEq, Eq)]
657#[cfg_attr(
658 feature = "codec",
659 derive(Serialize, Deserialize),
660 serde(tag = "type", content = "content")
661)]
662pub enum ExpressionOperations {
663 Plus,
664 Minus,
665 Multiply,
666 Divide,
667 ShiftLeft,
668 ShiftRight,
669 And,
670 Or,
671 Xor,
672 Eq,
673 NotEq,
674 Great,
675 Less,
676 GreatEq,
677 LessEq,
678}
679
680impl ExpressionOperations {
681 #[must_use]
683 pub const fn priority(&self) -> u8 {
684 match self {
685 Self::Plus => 5,
686 Self::Minus => 4,
687 Self::Divide => 8,
688 Self::Multiply | Self::ShiftLeft | Self::ShiftRight => {
689 MAX_PRIORITY_LEVEL_FOR_EXPRESSIONS
690 }
691 Self::Or | Self::Xor => 6,
692 Self::And
693 | Self::Eq
694 | Self::NotEq
695 | Self::Great
696 | Self::Less
697 | Self::GreatEq
698 | Self::LessEq => 7,
699 }
700 }
701}
702
703#[derive(Debug, Clone, PartialEq)]
708#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
709pub struct Expression<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
710 #[cfg_attr(feature = "codec", serde(borrow))]
712 pub expression_value: ExpressionValue<'a, I, E>,
713 pub operation: Option<(ExpressionOperations, Box<Expression<'a, I, E>>)>,
715}
716
717impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for Expression<'_, I, E> {
718 fn location(&self) -> CodeLocation {
719 CodeLocation::new(1, 0)
721 }
722}
723
724#[derive(Debug, Clone, PartialEq)]
727#[cfg_attr(feature = "codec", derive(Serialize, Deserialize), serde(tag = "type"))]
728pub struct LetBinding<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
729 #[cfg_attr(feature = "codec", serde(borrow))]
731 pub name: ValueName<'a>,
732 pub mutable: bool,
734 pub value_type: Option<Type<'a>>,
736 pub value: Box<Expression<'a, I, E>>,
738}
739
740impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for LetBinding<'_, I, E> {
741 fn location(&self) -> CodeLocation {
742 self.name.location()
743 }
744}
745
746impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for LetBinding<'_, I, E> {
747 fn name(&self) -> String {
748 self.name.0.to_string()
749 }
750}
751
752#[derive(Debug, Clone, PartialEq)]
756#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
757pub struct Binding<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
758 #[cfg_attr(feature = "codec", serde(borrow))]
760 pub name: ValueName<'a>,
761 pub value: Box<Expression<'a, I, E>>,
763}
764
765impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation for Binding<'_, I, E> {
766 fn location(&self) -> CodeLocation {
767 self.name.location()
768 }
769}
770
771impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for Binding<'_, I, E> {
772 fn name(&self) -> String {
773 self.name.0.to_string()
774 }
775}
776
777#[derive(Debug, Clone, PartialEq)]
780#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
781pub struct FunctionCall<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
782 #[cfg_attr(feature = "codec", serde(borrow))]
784 pub name: FunctionName<'a>,
785 pub parameters: Vec<Expression<'a, I, E>>,
787}
788
789impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
790 for FunctionCall<'_, I, E>
791{
792 fn location(&self) -> CodeLocation {
793 self.name.location()
794 }
795}
796
797impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetName for FunctionCall<'_, I, E> {
798 fn name(&self) -> String {
799 (*self.name.0.fragment()).to_string()
800 }
801}
802
803#[derive(Debug, Clone, PartialEq, Eq)]
807#[cfg_attr(
808 feature = "codec",
809 derive(Serialize, Deserialize),
810 serde(tag = "type", content = "content")
811)]
812pub enum Condition {
813 Great,
814 Less,
815 Eq,
816 GreatEq,
817 LessEq,
818 NotEq,
819}
820
821#[derive(Debug, Clone, PartialEq, Eq)]
824#[cfg_attr(
825 feature = "codec",
826 derive(Serialize, Deserialize),
827 serde(tag = "type", content = "content")
828)]
829pub enum LogicCondition {
830 And,
831 Or,
832}
833
834#[derive(Debug, Clone, PartialEq)]
838#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
839pub struct ExpressionCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
840 #[cfg_attr(feature = "codec", serde(borrow))]
842 pub left: Expression<'a, I, E>,
843 pub condition: Condition,
845 pub right: Expression<'a, I, E>,
847}
848
849#[derive(Debug, Clone, PartialEq)]
857#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
858pub struct ExpressionLogicCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
859 #[cfg_attr(feature = "codec", serde(borrow))]
861 pub left: ExpressionCondition<'a, I, E>,
862 pub right: Option<(LogicCondition, Box<ExpressionLogicCondition<'a, I, E>>)>,
864}
865
866#[derive(Debug, Clone, PartialEq)]
871#[cfg_attr(
872 feature = "codec",
873 derive(Serialize, Deserialize),
874 serde(tag = "type", content = "content")
875)]
876pub enum IfCondition<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
877 #[cfg_attr(feature = "codec", serde(borrow))]
879 Single(Expression<'a, I, E>),
880 Logic(ExpressionLogicCondition<'a, I, E>),
882}
883
884#[derive(Debug, Clone, PartialEq)]
891#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
892pub struct IfStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
893 #[cfg_attr(feature = "codec", serde(borrow))]
895 pub condition: IfCondition<'a, I, E>,
896 pub body: IfBodyStatements<'a, I, E>,
898 pub else_statement: Option<IfBodyStatements<'a, I, E>>,
900 pub else_if_statement: Option<Box<IfStatement<'a, I, E>>>,
902}
903
904impl<I: SemanticContextInstruction, E: ExtendedExpression<I>> GetLocation
905 for IfStatement<'_, I, E>
906{
907 fn location(&self) -> CodeLocation {
908 CodeLocation::new(1, 0)
910 }
911}
912
913#[derive(Debug, Clone, PartialEq)]
916#[cfg_attr(
917 feature = "codec",
918 derive(Serialize, Deserialize),
919 serde(tag = "type", content = "content")
920)]
921pub enum BodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
922 #[cfg_attr(feature = "codec", serde(borrow))]
924 LetBinding(LetBinding<'a, I, E>),
925 Binding(Binding<'a, I, E>),
927 FunctionCall(FunctionCall<'a, I, E>),
929 If(IfStatement<'a, I, E>),
931 Loop(Vec<LoopBodyStatement<'a, I, E>>),
933 Expression(Expression<'a, I, E>),
935 Return(Expression<'a, I, E>),
937}
938
939#[derive(Debug, Clone, PartialEq)]
942#[cfg_attr(
943 feature = "codec",
944 derive(Serialize, Deserialize),
945 serde(tag = "type", content = "content")
946)]
947pub enum IfBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
948 #[cfg_attr(feature = "codec", serde(borrow))]
949 LetBinding(LetBinding<'a, I, E>),
950 Binding(Binding<'a, I, E>),
951 FunctionCall(FunctionCall<'a, I, E>),
952 If(IfStatement<'a, I, E>),
953 Loop(Vec<LoopBodyStatement<'a, I, E>>),
954 Return(Expression<'a, I, E>),
955}
956
957#[derive(Debug, Clone, PartialEq)]
960#[cfg_attr(feature = "codec", derive(Serialize, Deserialize))]
961#[cfg_attr(feature = "codec", serde(tag = "type", content = "content"))]
962pub enum IfLoopBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
963 #[cfg_attr(feature = "codec", serde(borrow))]
964 LetBinding(LetBinding<'a, I, E>),
965 Binding(Binding<'a, I, E>),
966 FunctionCall(FunctionCall<'a, I, E>),
967 If(IfStatement<'a, I, E>),
968 Loop(Vec<LoopBodyStatement<'a, I, E>>),
969 Return(Expression<'a, I, E>),
970 Break,
971 Continue,
972}
973
974#[derive(Debug, Clone, PartialEq)]
977#[cfg_attr(
978 feature = "codec",
979 derive(Serialize, Deserialize),
980 serde(tag = "type", content = "content")
981)]
982pub enum IfBodyStatements<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
983 #[cfg_attr(feature = "codec", serde(borrow))]
984 If(Vec<IfBodyStatement<'a, I, E>>),
985 Loop(Vec<IfLoopBodyStatement<'a, I, E>>),
986}
987
988#[derive(Debug, Clone, PartialEq)]
991#[cfg_attr(
992 feature = "codec",
993 derive(Serialize, Deserialize),
994 serde(tag = "type", content = "content")
995)]
996pub enum LoopBodyStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
997 #[cfg_attr(feature = "codec", serde(borrow))]
998 LetBinding(LetBinding<'a, I, E>),
999 Binding(Binding<'a, I, E>),
1000 FunctionCall(FunctionCall<'a, I, E>),
1001 If(IfStatement<'a, I, E>),
1002 Loop(Vec<LoopBodyStatement<'a, I, E>>),
1003 Return(Expression<'a, I, E>),
1004 Break,
1005 Continue,
1006}
1007
1008#[derive(Debug, Clone, PartialEq)]
1010#[cfg_attr(
1011 feature = "codec",
1012 derive(Serialize, Deserialize),
1013 serde(tag = "type", content = "content")
1014)]
1015pub enum MainStatement<'a, I: SemanticContextInstruction, E: ExtendedExpression<I>> {
1016 #[cfg_attr(feature = "codec", serde(borrow))]
1018 Import(ImportPath<'a>),
1019 Constant(Constant<'a>),
1021 Types(StructTypes<'a>),
1023 Function(FunctionStatement<'a, I, E>),
1025}
1026
1027pub type Main<'a, I, E> = Vec<MainStatement<'a, I, E>>;