1use crate::span::Span;
4use crate::token::TokenKind;
5
6#[derive(Clone, Debug, Default, PartialEq)]
7pub struct File {
8 pub items: Vec<Item>,
9}
10
11#[derive(Clone, Debug, PartialEq)]
12pub enum Item {
13 State(StateDecl),
14 Struct(StructDecl),
15 Fn(FnDecl),
16 View(ViewDecl),
17 Named(NamedElement),
19 Stmt(Stmt),
21}
22
23#[derive(Clone, Debug, PartialEq)]
26pub struct NamedElement {
27 pub name: Ident,
28 pub call: Stmt,
29}
30
31#[derive(Clone, Debug, PartialEq)]
32pub struct Ident {
33 pub name: String,
34 pub span: Span,
35}
36
37#[derive(Clone, Debug, PartialEq)]
39pub struct TypedName {
40 pub name: Ident,
41 pub ty: TypeExpr,
42}
43
44#[derive(Clone, Debug, PartialEq)]
45pub struct StateDecl {
46 pub name: Ident,
47 pub ty: Option<TypeExpr>,
48 pub value: Expr,
49 pub span: Span,
50}
51
52#[derive(Clone, Debug, PartialEq)]
53pub struct StructDecl {
54 pub name: Ident,
55 pub fields: Vec<TypedName>,
56 pub span: Span,
57}
58
59#[derive(Clone, Debug, PartialEq)]
60pub struct FnDecl {
61 pub name: Ident,
62 pub params: Vec<TypedName>,
63 pub return_type: Option<TypeExpr>,
64 pub body: Block,
65 pub span: Span,
66}
67
68#[derive(Clone, Debug, PartialEq)]
69pub struct ViewDecl {
70 pub name: Ident,
71 pub params: Vec<TypedName>,
72 pub body: Block,
73 pub span: Span,
74}
75
76#[derive(Clone, Debug, PartialEq)]
77pub struct TypeExpr {
78 pub kind: TypeExprKind,
79 pub span: Span,
80}
81
82#[derive(Clone, Debug, PartialEq)]
83pub enum TypeExprKind {
84 Named(String),
85 List(Box<TypeExpr>),
86}
87
88#[derive(Clone, Debug, PartialEq)]
89pub struct Block {
90 pub stmts: Vec<Stmt>,
91 pub span: Span,
92}
93
94#[derive(Clone, Debug, PartialEq)]
95pub struct Stmt {
96 pub kind: StmtKind,
97 pub span: Span,
98}
99
100#[derive(Clone, Debug, PartialEq)]
101pub enum StmtKind {
102 Let {
103 name: Ident,
104 ty: Option<TypeExpr>,
105 value: Expr,
106 },
107 Assign {
108 target: Expr,
109 op: AssignOp,
110 value: Expr,
111 },
112 If(IfStmt),
113 For {
115 index: Option<Ident>,
116 item: Ident,
117 iterable: Iterable,
118 body: Block,
119 },
120 Return(Option<Expr>),
121 Expr(Expr),
122}
123
124#[derive(Clone, Debug, PartialEq)]
126pub enum Iterable {
127 List(Expr),
128 Range {
130 start: Expr,
131 end: Expr,
132 },
133}
134
135#[derive(Clone, Debug, PartialEq)]
136pub struct IfStmt {
137 pub condition: Expr,
138 pub then_block: Block,
139 pub else_branch: Option<ElseBranch>,
140}
141
142#[derive(Clone, Debug, PartialEq)]
143pub enum ElseBranch {
144 If(Box<IfStmt>),
145 Block(Block),
146}
147
148#[derive(Clone, Copy, Debug, PartialEq, Eq)]
149pub enum AssignOp {
150 Set,
151 Add,
152 Sub,
153 Mul,
154 Div,
155}
156
157#[derive(Clone, Debug, PartialEq)]
158pub struct Expr {
159 pub kind: ExprKind,
160 pub span: Span,
161}
162
163#[derive(Clone, Debug, PartialEq)]
164pub enum ExprKind {
165 Int(i64),
166 Float(f64),
167 Bool(bool),
168 String(Vec<StringPart>),
169 Name(String),
170 ImplicitMember(Ident),
172 List(Vec<Expr>),
173 Unary {
174 op: UnaryOp,
175 operand: Box<Expr>,
176 },
177 Binary {
178 op: BinaryOp,
179 lhs: Box<Expr>,
180 rhs: Box<Expr>,
181 },
182 Call {
183 callee: Box<Expr>,
184 args: Vec<Arg>,
185 trailing_block: Option<Block>,
186 },
187 Field {
188 base: Box<Expr>,
189 name: Ident,
190 },
191 Index {
192 base: Box<Expr>,
193 index: Box<Expr>,
194 },
195 Error,
197}
198
199#[derive(Clone, Debug, PartialEq)]
200pub enum StringPart {
201 Text(String),
202 Expr(Expr),
203}
204
205#[derive(Clone, Debug, PartialEq)]
206pub struct Arg {
207 pub label: Option<Ident>,
208 pub value: Expr,
209}
210
211#[derive(Clone, Copy, Debug, PartialEq, Eq)]
212pub enum UnaryOp {
213 Not,
214 Neg,
215 Bind,
217}
218
219#[derive(Clone, Copy, Debug, PartialEq, Eq)]
220pub enum BinaryOp {
221 Or,
222 And,
223 Eq,
224 NotEq,
225 Lt,
226 LtEq,
227 Gt,
228 GtEq,
229 Add,
230 Sub,
231 Mul,
232 Div,
233 Rem,
234}
235
236impl BinaryOp {
237 #[must_use]
238 pub fn is_comparison(self) -> bool {
239 matches!(
240 self,
241 Self::Eq | Self::NotEq | Self::Lt | Self::LtEq | Self::Gt | Self::GtEq
242 )
243 }
244
245 #[must_use]
247 pub const fn token(self) -> TokenKind {
248 match self {
249 Self::Or => TokenKind::OrOr,
250 Self::And => TokenKind::AndAnd,
251 Self::Eq => TokenKind::EqEq,
252 Self::NotEq => TokenKind::BangEq,
253 Self::Lt => TokenKind::Lt,
254 Self::LtEq => TokenKind::LtEq,
255 Self::Gt => TokenKind::Gt,
256 Self::GtEq => TokenKind::GtEq,
257 Self::Add => TokenKind::Plus,
258 Self::Sub => TokenKind::Minus,
259 Self::Mul => TokenKind::Star,
260 Self::Div => TokenKind::Slash,
261 Self::Rem => TokenKind::Percent,
262 }
263 }
264}