1use crate::span::Span;
4
5#[derive(Clone, Debug, PartialEq)]
6pub struct Ident {
7 pub name: String,
8 pub span: Span,
9}
10
11#[derive(Clone, Debug, PartialEq)]
12pub struct Program {
13 pub pragmas: Vec<Pragma>,
14 pub items: Vec<Item>,
15}
16
17#[derive(Clone, Debug, PartialEq)]
19pub struct Pragma {
20 pub name: Ident,
21 pub arg: Option<Expr>,
22 pub span: Span,
23}
24
25#[derive(Clone, Debug, PartialEq)]
26pub enum Item {
27 Fn(FnDecl),
28 Type(TypeDecl),
29 Enum(EnumDecl),
30 Import(Import),
31 Stmt(Stmt),
32}
33
34#[derive(Clone, Debug, PartialEq)]
35pub struct FnDecl {
36 pub name: Ident,
37 pub params: Vec<Param>,
38 pub ret: Option<TypeExpr>,
39 pub body: Block,
40 pub span: Span,
41}
42
43#[derive(Clone, Debug, PartialEq)]
44pub struct Param {
45 pub name: Ident,
46 pub ty: Option<TypeExpr>,
47}
48
49#[derive(Clone, Debug, PartialEq)]
50pub struct TypeDecl {
51 pub name: Ident,
52 pub ty: TypeExpr,
53 pub span: Span,
54}
55
56#[derive(Clone, Debug, PartialEq)]
57pub struct EnumDecl {
58 pub name: Ident,
59 pub variants: Vec<Ident>,
60 pub span: Span,
61}
62
63#[derive(Clone, Debug, PartialEq)]
64pub struct Import {
65 pub path: String,
66 pub span: Span,
67}
68
69#[derive(Clone, Debug, PartialEq)]
70pub enum TypeExpr {
71 Named { name: Ident, args: Vec<TypeExpr> },
73 Record { fields: Vec<(Ident, TypeExpr)>, span: Span },
75}
76
77#[derive(Clone, Debug, PartialEq)]
78pub struct Block {
79 pub stmts: Vec<Stmt>,
80 pub span: Span,
81}
82
83#[derive(Clone, Debug, PartialEq)]
84pub struct Stmt {
85 pub kind: StmtKind,
86 pub span: Span,
87}
88
89#[derive(Clone, Copy, Debug, PartialEq, Eq)]
91pub enum BindOp {
92 Assign,
93 Draw,
94}
95
96#[derive(Clone, Copy, Debug, PartialEq, Eq)]
97pub enum AssignOp {
98 Set,
99 Draw,
100 Add,
101 Sub,
102 Mul,
103 Div,
104}
105
106#[derive(Clone, Debug, PartialEq)]
107pub enum StmtKind {
108 Let {
110 mutable: bool,
111 pattern: Pattern,
112 ty: Option<TypeExpr>,
113 op: BindOp,
114 value: Expr,
115 },
116 Assign {
117 target: Expr,
118 op: AssignOp,
119 value: Expr,
120 },
121 For {
122 pattern: Pattern,
123 iter: Expr,
124 body: Block,
125 },
126 While {
127 cond: Expr,
128 body: Block,
129 },
130 Repeat {
131 count: Expr,
132 body: Block,
133 },
134 Loop {
135 body: Block,
136 },
137 Break,
138 Continue,
139 Return(Option<Expr>),
140 Observe {
141 value: Expr,
142 from: Option<Expr>,
143 },
144 Score(Expr),
146 Report {
147 value: Expr,
148 by: Option<Expr>,
149 label: Option<(String, Span)>,
150 },
151 Expr(Expr),
152}
153
154#[derive(Clone, Debug, PartialEq)]
155pub struct Expr {
156 pub kind: ExprKind,
157 pub span: Span,
158}
159
160#[derive(Clone, Debug, PartialEq)]
161pub enum ExprKind {
162 Int(probl_number::Integer),
163 Float(f64),
164 Percent(f64),
166 Dice {
167 count: u32,
168 sides: u32,
169 },
170 Str(Vec<StrSegment>),
171 Bool(bool),
172 Name(String),
173 List(Vec<Expr>),
174 Map(Vec<(Expr, Expr)>),
175 Record {
177 name: Option<Ident>,
178 fields: Vec<Field>,
179 },
180 Unary {
181 op: UnOp,
182 expr: Box<Expr>,
183 },
184 Draw(Box<Expr>),
186 Binary {
187 op: BinOp,
188 lhs: Box<Expr>,
189 rhs: Box<Expr>,
190 },
191 Call {
192 callee: Box<Expr>,
193 args: Vec<Arg>,
194 },
195 Method {
197 receiver: Box<Expr>,
198 name: Ident,
199 args: Vec<Arg>,
200 },
201 Field {
202 expr: Box<Expr>,
203 name: Ident,
204 },
205 Index {
206 expr: Box<Expr>,
207 index: Box<Expr>,
208 },
209 With {
211 expr: Box<Expr>,
212 fields: Vec<Field>,
213 },
214 Lambda {
215 params: Vec<Ident>,
216 body: Box<Expr>,
217 },
218 If {
219 cond: Box<Expr>,
220 then: Block,
221 otherwise: Option<Box<Expr>>,
222 },
223 Chance {
224 arms: Vec<ChanceArm>,
225 },
226 Match {
227 scrutinee: Box<Expr>,
228 arms: Vec<MatchArm>,
229 },
230 Simulate(Block),
231 Block(Block),
232 Try {
234 body: Block,
235 catches: Vec<Catch>,
236 },
237}
238
239#[derive(Clone, Debug, PartialEq)]
241pub struct Catch {
242 pub fault: Option<Ident>,
243 pub body: Block,
244 pub span: Span,
245}
246
247#[derive(Clone, Debug, PartialEq)]
248pub enum StrSegment {
249 Lit(String),
250 Expr(Expr),
251}
252
253#[derive(Clone, Debug, PartialEq)]
254pub struct Field {
255 pub name: Ident,
256 pub value: Expr,
257}
258
259#[derive(Clone, Debug, PartialEq)]
260pub struct Arg {
261 pub name: Option<Ident>,
262 pub value: Expr,
263}
264
265#[derive(Clone, Debug, PartialEq)]
267pub struct ChanceArm {
268 pub weight: Option<Expr>,
269 pub body: Stmt,
270 pub span: Span,
271}
272
273#[derive(Clone, Debug, PartialEq)]
274pub struct MatchArm {
275 pub pattern: Pattern,
276 pub guard: Option<Expr>,
277 pub body: Stmt,
278 pub span: Span,
279}
280
281#[derive(Clone, Copy, Debug, PartialEq, Eq)]
282pub enum UnOp {
283 Neg,
284 Not,
285 Typeof,
286}
287
288#[derive(Clone, Copy, Debug, PartialEq, Eq)]
289pub enum BinOp {
290 Or,
291 And,
292 Eq,
293 Ne,
294 Lt,
295 Le,
296 Gt,
297 Ge,
298 In,
299 NotIn,
300 Range,
302 RangeExcl,
304 To,
306 Add,
307 Sub,
308 Mul,
309 Div,
310 IntDiv,
311 Mod,
312 Pow,
313}
314
315impl BinOp {
316 pub fn symbol(self) -> &'static str {
317 match self {
318 BinOp::Or => "or",
319 BinOp::And => "and",
320 BinOp::Eq => "==",
321 BinOp::Ne => "!=",
322 BinOp::Lt => "<",
323 BinOp::Le => "<=",
324 BinOp::Gt => ">",
325 BinOp::Ge => ">=",
326 BinOp::In => "in",
327 BinOp::NotIn => "not in",
328 BinOp::Range => "..",
329 BinOp::RangeExcl => "..<",
330 BinOp::To => "to",
331 BinOp::Add => "+",
332 BinOp::Sub => "-",
333 BinOp::Mul => "*",
334 BinOp::Div => "/",
335 BinOp::IntDiv => "div",
336 BinOp::Mod => "mod",
337 BinOp::Pow => "^",
338 }
339 }
340}
341
342#[derive(Clone, Debug, PartialEq)]
343pub struct Pattern {
344 pub kind: PatternKind,
345 pub span: Span,
346}
347
348#[derive(Clone, Debug, PartialEq)]
349pub enum PatternKind {
350 Wildcard,
351 Name(String),
353 Literal(Expr),
354 List(Vec<Pattern>),
355 Or(Vec<Pattern>),
356}