1use dada_util::{FromImpls, SalsaSerialize};
2use salsa::Update;
3use serde::Serialize;
4
5use crate::span::{Span, Spanned};
6
7use super::{AstGenericTerm, AstPath, AstTy, DeferredParse, SpanVec, SpannedIdentifier};
8
9#[derive(SalsaSerialize)]
10#[salsa::tracked(debug)]
11pub struct AstBlock<'db> {
12 #[return_ref]
13 pub statements: SpanVec<'db, AstStatement<'db>>,
14}
15
16#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, FromImpls, Serialize)]
17pub enum AstStatement<'db> {
18 Let(AstLetStatement<'db>),
19 Expr(AstExpr<'db>),
20}
21
22impl<'db> Spanned<'db> for AstStatement<'db> {
23 fn span(&self, db: &'db dyn crate::Db) -> Span<'db> {
24 match self {
25 AstStatement::Let(s) => s.span(db),
26 AstStatement::Expr(e) => e.span,
27 }
28 }
29}
30
31#[derive(SalsaSerialize)]
33#[salsa::tracked(debug)]
34pub struct AstLetStatement<'db> {
35 pub span: Span<'db>,
36 pub mutable: Option<Span<'db>>,
37 pub name: SpannedIdentifier<'db>,
38 pub ty: Option<AstTy<'db>>,
39 pub initializer: Option<AstExpr<'db>>,
40}
41
42#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
43pub struct AstExpr<'db> {
44 pub span: Span<'db>,
45 pub kind: Box<AstExprKind<'db>>,
46}
47
48impl<'db> AstExpr<'db> {
49 pub fn new(span: Span<'db>, kind: AstExprKind<'db>) -> Self {
50 Self {
51 span,
52 kind: Box::new(kind),
53 }
54 }
55}
56
57#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
58pub enum AstExprKind<'db> {
59 Block(AstBlock<'db>),
61
62 Literal(Literal<'db>),
64
65 Id(SpannedIdentifier<'db>),
67
68 DotId(AstExpr<'db>, SpannedIdentifier<'db>),
73
74 SquareBracketOp(AstExpr<'db>, SquareBracketArgs<'db>),
79
80 ParenthesisOp(AstExpr<'db>, SpanVec<'db, AstExpr<'db>>),
86
87 Tuple(SpanVec<'db, AstExpr<'db>>),
91
92 Constructor(AstPath<'db>, SpanVec<'db, AstConstructorField<'db>>),
94
95 Return(Option<AstExpr<'db>>),
97
98 Await {
100 future: AstExpr<'db>,
101 await_keyword: Span<'db>,
102 },
103
104 PermissionOp {
106 value: AstExpr<'db>,
107 op: PermissionOp,
108 },
109
110 BinaryOp(SpannedBinaryOp<'db>, AstExpr<'db>, AstExpr<'db>),
112
113 UnaryOp(SpannedUnaryOp<'db>, AstExpr<'db>),
115
116 If(Vec<IfArm<'db>>),
118}
119
120#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
121pub enum PermissionOp {
122 Mutate,
123 Reference,
124 Give,
125 Share,
126}
127
128#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
129pub struct IfArm<'db> {
130 pub condition: Option<AstExpr<'db>>,
132
133 pub result: AstBlock<'db>,
135}
136
137#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
138pub struct SpannedBinaryOp<'db> {
139 pub span: Span<'db>,
140 pub op: AstBinaryOp,
141}
142
143#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
144pub enum AstBinaryOp {
145 Add,
146 Sub,
147 Mul,
148 Div,
149 AndAnd,
150 OrOr,
151 GreaterThan,
152 LessThan,
153 GreaterEqual,
154 LessEqual,
155 EqualEqual,
156 Assign,
157}
158
159impl std::fmt::Display for AstBinaryOp {
160 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
161 match self {
162 AstBinaryOp::Add => write!(f, "+"),
163 AstBinaryOp::Sub => write!(f, "-"),
164 AstBinaryOp::Mul => write!(f, "*"),
165 AstBinaryOp::Div => write!(f, "/"),
166 AstBinaryOp::AndAnd => write!(f, "&&"),
167 AstBinaryOp::OrOr => write!(f, "||"),
168 AstBinaryOp::GreaterThan => write!(f, ">"),
169 AstBinaryOp::LessThan => write!(f, "<"),
170 AstBinaryOp::GreaterEqual => write!(f, ">="),
171 AstBinaryOp::LessEqual => write!(f, "<="),
172 AstBinaryOp::EqualEqual => write!(f, "=="),
173 AstBinaryOp::Assign => write!(f, "="),
174 }
175 }
176}
177
178#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
179pub struct SpannedUnaryOp<'db> {
180 pub span: Span<'db>,
181 pub op: UnaryOp,
182}
183
184#[derive(Copy, Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
185pub enum UnaryOp {
186 Not,
187 Negate,
188}
189
190#[derive(SalsaSerialize)]
194#[salsa::tracked(debug)]
195pub struct SquareBracketArgs<'db> {
196 #[return_ref]
197 pub deferred: DeferredParse<'db>,
198}
199
200#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
201pub struct AstConstructorField<'db> {
202 pub name: SpannedIdentifier<'db>,
203 pub value: AstExpr<'db>,
204}
205
206#[derive(SalsaSerialize)]
207#[salsa::interned(debug)]
208pub struct Literal<'db> {
209 pub kind: LiteralKind,
210 #[return_ref]
211 pub text: String,
212}
213
214#[derive(Clone, Copy, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
215pub enum LiteralKind {
216 Boolean,
217 Integer,
218 String,
219}
220
221#[derive(Clone, PartialEq, Eq, PartialOrd, Ord, Hash, Update, Debug, Serialize)]
222pub struct AstParenExpr<'db> {
223 pub callee: AstExpr<'db>,
224 pub generic_args: Option<SpanVec<'db, AstGenericTerm<'db>>>,
225 pub args: SpanVec<'db, AstExpr<'db>>,
226}