1use crate::error::SourceLocation;
2
3#[derive(Debug, Clone)]
5pub struct Program {
6 pub rules: Vec<Rule>,
7 pub functions: Vec<FunctionDef>,
8}
9
10impl Program {
11 pub fn new() -> Self {
12 Self {
13 rules: Vec::new(),
14 functions: Vec::new(),
15 }
16 }
17}
18
19impl Default for Program {
20 fn default() -> Self {
21 Self::new()
22 }
23}
24
25#[derive(Debug, Clone)]
27pub struct Rule {
28 pub pattern: Option<Pattern>,
29 pub action: Option<Block>,
30 pub location: SourceLocation,
31}
32
33#[derive(Debug, Clone)]
35pub enum Pattern {
36 Begin,
38 End,
40 BeginFile,
42 EndFile,
44 Expr(Expr),
46 Regex(String),
48 Range {
50 start: Box<Pattern>,
51 end: Box<Pattern>,
52 },
53 And(Box<Pattern>, Box<Pattern>),
55 Or(Box<Pattern>, Box<Pattern>),
56 Not(Box<Pattern>),
57}
58
59#[derive(Debug, Clone)]
61pub struct FunctionDef {
62 pub name: String,
63 pub params: Vec<String>,
64 pub body: Block,
65 pub location: SourceLocation,
66}
67
68#[derive(Debug, Clone)]
70pub struct Block {
71 pub statements: Vec<Stmt>,
72 pub location: SourceLocation,
73}
74
75impl Block {
76 pub fn new(statements: Vec<Stmt>, location: SourceLocation) -> Self {
77 Self {
78 statements,
79 location,
80 }
81 }
82
83 pub fn empty(location: SourceLocation) -> Self {
84 Self {
85 statements: Vec::new(),
86 location,
87 }
88 }
89}
90
91#[derive(Debug, Clone)]
93pub enum Stmt {
94 Expr(Expr),
96
97 Print {
99 args: Vec<Expr>,
100 output: Option<OutputRedirect>,
101 location: SourceLocation,
102 },
103
104 Printf {
106 format: Expr,
107 args: Vec<Expr>,
108 output: Option<OutputRedirect>,
109 location: SourceLocation,
110 },
111
112 If {
114 condition: Expr,
115 then_branch: Box<Stmt>,
116 else_branch: Option<Box<Stmt>>,
117 location: SourceLocation,
118 },
119
120 While {
122 condition: Expr,
123 body: Box<Stmt>,
124 location: SourceLocation,
125 },
126
127 DoWhile {
129 body: Box<Stmt>,
130 condition: Expr,
131 location: SourceLocation,
132 },
133
134 For {
136 init: Option<Box<Stmt>>,
137 condition: Option<Expr>,
138 update: Option<Expr>,
139 body: Box<Stmt>,
140 location: SourceLocation,
141 },
142
143 ForIn {
145 var: String,
146 array: String,
147 body: Box<Stmt>,
148 location: SourceLocation,
149 },
150
151 Block(Block),
153
154 Break { location: SourceLocation },
156
157 Continue { location: SourceLocation },
159
160 Next { location: SourceLocation },
162
163 Nextfile { location: SourceLocation },
165
166 Exit {
168 code: Option<Expr>,
169 location: SourceLocation,
170 },
171
172 Return {
174 value: Option<Expr>,
175 location: SourceLocation,
176 },
177
178 Delete {
180 array: String,
181 index: Vec<Expr>,
182 location: SourceLocation,
183 },
184
185 Getline {
187 var: Option<String>,
188 input: Option<GetlineInput>,
189 location: SourceLocation,
190 },
191
192 Empty,
194}
195
196#[derive(Debug, Clone)]
198pub enum OutputRedirect {
199 Truncate(Expr),
201 Append(Expr),
203 Pipe(Expr),
205}
206
207#[derive(Debug, Clone)]
209pub enum GetlineInput {
210 File(Box<Expr>),
212 Pipe(Box<Expr>),
214}
215
216#[derive(Debug, Clone)]
218pub enum Expr {
219 Number(f64, SourceLocation),
221
222 String(String, SourceLocation),
224
225 Regex(String, SourceLocation),
227
228 Var(String, SourceLocation),
230
231 Field(Box<Expr>, SourceLocation),
233
234 ArrayAccess {
236 array: String,
237 indices: Vec<Expr>,
238 location: SourceLocation,
239 },
240
241 Binary {
243 left: Box<Expr>,
244 op: BinaryOp,
245 right: Box<Expr>,
246 location: SourceLocation,
247 },
248
249 Unary {
251 op: UnaryOp,
252 operand: Box<Expr>,
253 location: SourceLocation,
254 },
255
256 Assign {
258 target: Box<Expr>,
259 op: AssignOp,
260 value: Box<Expr>,
261 location: SourceLocation,
262 },
263
264 PreIncrement(Box<Expr>, SourceLocation),
266
267 PreDecrement(Box<Expr>, SourceLocation),
269
270 PostIncrement(Box<Expr>, SourceLocation),
272
273 PostDecrement(Box<Expr>, SourceLocation),
275
276 Ternary {
278 condition: Box<Expr>,
279 then_expr: Box<Expr>,
280 else_expr: Box<Expr>,
281 location: SourceLocation,
282 },
283
284 Call {
286 name: String,
287 args: Vec<Expr>,
288 location: SourceLocation,
289 },
290
291 InArray {
293 key: Vec<Expr>,
294 array: String,
295 location: SourceLocation,
296 },
297
298 Match {
300 expr: Box<Expr>,
301 pattern: Box<Expr>,
302 negated: bool,
303 location: SourceLocation,
304 },
305
306 Concat(Vec<Expr>, SourceLocation),
308
309 Getline {
311 var: Option<String>,
312 input: Option<GetlineInput>,
313 location: SourceLocation,
314 },
315
316 Group(Box<Expr>, SourceLocation),
318}
319
320impl Expr {
321 pub fn location(&self) -> SourceLocation {
322 match self {
323 Expr::Number(_, loc)
324 | Expr::String(_, loc)
325 | Expr::Regex(_, loc)
326 | Expr::Var(_, loc)
327 | Expr::Field(_, loc)
328 | Expr::ArrayAccess { location: loc, .. }
329 | Expr::Binary { location: loc, .. }
330 | Expr::Unary { location: loc, .. }
331 | Expr::Assign { location: loc, .. }
332 | Expr::PreIncrement(_, loc)
333 | Expr::PreDecrement(_, loc)
334 | Expr::PostIncrement(_, loc)
335 | Expr::PostDecrement(_, loc)
336 | Expr::Ternary { location: loc, .. }
337 | Expr::Call { location: loc, .. }
338 | Expr::InArray { location: loc, .. }
339 | Expr::Match { location: loc, .. }
340 | Expr::Concat(_, loc)
341 | Expr::Getline { location: loc, .. }
342 | Expr::Group(_, loc) => *loc,
343 }
344 }
345}
346
347#[derive(Debug, Clone, Copy, PartialEq, Eq)]
349pub enum BinaryOp {
350 Add,
352 Sub,
353 Mul,
354 Div,
355 Mod,
356 Pow,
357
358 Lt,
360 Le,
361 Gt,
362 Ge,
363 Eq,
364 Ne,
365
366 And,
368 Or,
369
370 Concat,
372}
373
374#[derive(Debug, Clone, Copy, PartialEq, Eq)]
376pub enum UnaryOp {
377 Neg, Pos, Not, }
381
382#[derive(Debug, Clone, Copy, PartialEq, Eq)]
384pub enum AssignOp {
385 Assign, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, PowAssign, }