1use core::fmt;
4
5pub use self::{
6 expr::{Expr, ExprType, SpannedExpr},
7 lvalue::{
8 Destructure, DestructureRest, Lvalue, LvalueLen, LvalueType, ObjectDestructure,
9 ObjectDestructureField, SpannedLvalue,
10 },
11};
12use crate::{
13 alloc::{vec, Box, Vec},
14 grammars::Grammar,
15 spans::Spanned,
16};
17
18mod expr;
19mod lvalue;
20
21#[derive(Debug)]
23#[non_exhaustive]
24pub struct ObjectExpr<'a, T: Grammar> {
25 pub fields: Vec<(Spanned<'a>, Option<SpannedExpr<'a, T>>)>,
28}
29
30impl<T: Grammar> Clone for ObjectExpr<'_, T> {
31 fn clone(&self) -> Self {
32 Self {
33 fields: self.fields.clone(),
34 }
35 }
36}
37
38impl<T: Grammar> PartialEq for ObjectExpr<'_, T> {
39 fn eq(&self, other: &Self) -> bool {
40 self.fields == other.fields
41 }
42}
43
44#[derive(Debug)]
46#[non_exhaustive]
47pub enum Statement<'a, T: Grammar> {
48 Expr(SpannedExpr<'a, T>),
50 Assignment {
52 lhs: SpannedLvalue<'a, T::Type<'a>>,
54 rhs: Box<SpannedExpr<'a, T>>,
56 },
57}
58
59impl<T: Grammar> Statement<'_, T> {
60 pub fn ty(&self) -> StatementType {
62 match self {
63 Self::Expr(_) => StatementType::Expr,
64 Self::Assignment { .. } => StatementType::Assignment,
65 }
66 }
67}
68
69impl<T: Grammar> Clone for Statement<'_, T> {
70 fn clone(&self) -> Self {
71 match self {
72 Self::Expr(expr) => Self::Expr(expr.clone()),
73 Self::Assignment { lhs, rhs } => Self::Assignment {
74 lhs: lhs.clone(),
75 rhs: rhs.clone(),
76 },
77 }
78 }
79}
80
81impl<'a, T> PartialEq for Statement<'a, T>
82where
83 T: Grammar,
84 T::Lit: PartialEq,
85 T::Type<'a>: PartialEq,
86{
87 fn eq(&self, other: &Self) -> bool {
88 match (self, other) {
89 (Self::Expr(this), Self::Expr(that)) => this == that,
90
91 (
92 Self::Assignment { lhs, rhs },
93 Self::Assignment {
94 lhs: that_lhs,
95 rhs: that_rhs,
96 },
97 ) => lhs == that_lhs && rhs == that_rhs,
98
99 _ => false,
100 }
101 }
102}
103
104pub type SpannedStatement<'a, T> = Spanned<'a, Statement<'a, T>>;
106
107#[derive(Debug, Clone, Copy, PartialEq, Eq, Hash)]
109#[non_exhaustive]
110pub enum StatementType {
111 Expr,
113 Assignment,
115}
116
117impl fmt::Display for StatementType {
118 fn fmt(&self, formatter: &mut fmt::Formatter<'_>) -> fmt::Result {
119 formatter.write_str(match self {
120 Self::Expr => "expression",
121 Self::Assignment => "variable assignment",
122 })
123 }
124}
125
126#[derive(Debug)]
130#[non_exhaustive]
131pub struct Block<'a, T: Grammar> {
132 pub statements: Vec<SpannedStatement<'a, T>>,
134 pub return_value: Option<Box<SpannedExpr<'a, T>>>,
136}
137
138impl<T: Grammar> Clone for Block<'_, T> {
139 fn clone(&self) -> Self {
140 Self {
141 statements: self.statements.clone(),
142 return_value: self.return_value.clone(),
143 }
144 }
145}
146
147impl<'a, T> PartialEq for Block<'a, T>
148where
149 T: Grammar,
150 T::Lit: PartialEq,
151 T::Type<'a>: PartialEq,
152{
153 fn eq(&self, other: &Self) -> bool {
154 self.return_value == other.return_value && self.statements == other.statements
155 }
156}
157
158impl<T: Grammar> Block<'_, T> {
159 pub fn empty() -> Self {
161 Self {
162 statements: vec![],
163 return_value: None,
164 }
165 }
166}
167
168#[derive(Debug)]
172#[non_exhaustive]
173pub struct FnDefinition<'a, T: Grammar> {
174 pub args: Spanned<'a, Destructure<'a, T::Type<'a>>>,
176 pub body: Block<'a, T>,
178}
179
180impl<T: Grammar> Clone for FnDefinition<'_, T> {
181 fn clone(&self) -> Self {
182 Self {
183 args: self.args.clone(),
184 body: self.body.clone(),
185 }
186 }
187}
188
189impl<'a, T> PartialEq for FnDefinition<'a, T>
190where
191 T: Grammar,
192 T::Lit: PartialEq,
193 T::Type<'a>: PartialEq,
194{
195 fn eq(&self, other: &Self) -> bool {
196 self.args == other.args && self.body == other.body
197 }
198}