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}
233
234#[derive(Clone, Debug, PartialEq)]
235pub enum StrSegment {
236 Lit(String),
237 Expr(Expr),
238}
239
240#[derive(Clone, Debug, PartialEq)]
241pub struct Field {
242 pub name: Ident,
243 pub value: Expr,
244}
245
246#[derive(Clone, Debug, PartialEq)]
247pub struct Arg {
248 pub name: Option<Ident>,
249 pub value: Expr,
250}
251
252#[derive(Clone, Debug, PartialEq)]
254pub struct ChanceArm {
255 pub weight: Option<Expr>,
256 pub body: Stmt,
257 pub span: Span,
258}
259
260#[derive(Clone, Debug, PartialEq)]
261pub struct MatchArm {
262 pub pattern: Pattern,
263 pub guard: Option<Expr>,
264 pub body: Stmt,
265 pub span: Span,
266}
267
268#[derive(Clone, Copy, Debug, PartialEq, Eq)]
269pub enum UnOp {
270 Neg,
271 Not,
272 Typeof,
273}
274
275#[derive(Clone, Copy, Debug, PartialEq, Eq)]
276pub enum BinOp {
277 Or,
278 And,
279 Eq,
280 Ne,
281 Lt,
282 Le,
283 Gt,
284 Ge,
285 In,
286 NotIn,
287 Range,
289 RangeExcl,
291 To,
293 Add,
294 Sub,
295 Mul,
296 Div,
297 IntDiv,
298 Mod,
299 Pow,
300}
301
302impl BinOp {
303 pub fn symbol(self) -> &'static str {
304 match self {
305 BinOp::Or => "or",
306 BinOp::And => "and",
307 BinOp::Eq => "==",
308 BinOp::Ne => "!=",
309 BinOp::Lt => "<",
310 BinOp::Le => "<=",
311 BinOp::Gt => ">",
312 BinOp::Ge => ">=",
313 BinOp::In => "in",
314 BinOp::NotIn => "not in",
315 BinOp::Range => "..",
316 BinOp::RangeExcl => "..<",
317 BinOp::To => "to",
318 BinOp::Add => "+",
319 BinOp::Sub => "-",
320 BinOp::Mul => "*",
321 BinOp::Div => "/",
322 BinOp::IntDiv => "div",
323 BinOp::Mod => "mod",
324 BinOp::Pow => "^",
325 }
326 }
327}
328
329#[derive(Clone, Debug, PartialEq)]
330pub struct Pattern {
331 pub kind: PatternKind,
332 pub span: Span,
333}
334
335#[derive(Clone, Debug, PartialEq)]
336pub enum PatternKind {
337 Wildcard,
338 Name(String),
340 Literal(Expr),
341 List(Vec<Pattern>),
342 Or(Vec<Pattern>),
343}