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 Empty,
187}
188
189#[derive(Debug, Clone)]
191pub enum OutputRedirect {
192 Truncate(Expr),
194 Append(Expr),
196 Pipe(Expr),
198}
199
200#[derive(Debug, Clone)]
202pub enum GetlineInput {
203 File(Box<Expr>),
205 Pipe(Box<Expr>),
207}
208
209#[derive(Debug, Clone)]
211pub enum Expr {
212 Number(f64, SourceLocation),
214
215 String(String, SourceLocation),
217
218 Regex(String, SourceLocation),
220
221 Var(String, SourceLocation),
223
224 Field(Box<Expr>, SourceLocation),
226
227 ArrayAccess {
229 array: String,
230 indices: Vec<Expr>,
231 location: SourceLocation,
232 },
233
234 Binary {
236 left: Box<Expr>,
237 op: BinaryOp,
238 right: Box<Expr>,
239 location: SourceLocation,
240 },
241
242 Unary {
244 op: UnaryOp,
245 operand: Box<Expr>,
246 location: SourceLocation,
247 },
248
249 Assign {
251 target: Box<Expr>,
252 op: AssignOp,
253 value: Box<Expr>,
254 location: SourceLocation,
255 },
256
257 PreIncrement(Box<Expr>, SourceLocation),
259
260 PreDecrement(Box<Expr>, SourceLocation),
262
263 PostIncrement(Box<Expr>, SourceLocation),
265
266 PostDecrement(Box<Expr>, SourceLocation),
268
269 Ternary {
271 condition: Box<Expr>,
272 then_expr: Box<Expr>,
273 else_expr: Box<Expr>,
274 location: SourceLocation,
275 },
276
277 Call {
279 name: String,
280 args: Vec<Expr>,
281 location: SourceLocation,
282 },
283
284 InArray {
286 key: Vec<Expr>,
287 array: String,
288 location: SourceLocation,
289 },
290
291 Match {
293 expr: Box<Expr>,
294 pattern: Box<Expr>,
295 negated: bool,
296 location: SourceLocation,
297 },
298
299 Getline {
301 var: Option<Box<Expr>>,
303 input: Option<GetlineInput>,
304 location: SourceLocation,
305 },
306
307 Group(Box<Expr>, SourceLocation),
309}
310
311impl Expr {
312 pub fn location(&self) -> SourceLocation {
313 match self {
314 Expr::Number(_, loc)
315 | Expr::String(_, loc)
316 | Expr::Regex(_, loc)
317 | Expr::Var(_, loc)
318 | Expr::Field(_, loc)
319 | Expr::ArrayAccess { location: loc, .. }
320 | Expr::Binary { location: loc, .. }
321 | Expr::Unary { location: loc, .. }
322 | Expr::Assign { location: loc, .. }
323 | Expr::PreIncrement(_, loc)
324 | Expr::PreDecrement(_, loc)
325 | Expr::PostIncrement(_, loc)
326 | Expr::PostDecrement(_, loc)
327 | Expr::Ternary { location: loc, .. }
328 | Expr::Call { location: loc, .. }
329 | Expr::InArray { location: loc, .. }
330 | Expr::Match { location: loc, .. }
331 | Expr::Getline { location: loc, .. }
332 | Expr::Group(_, loc) => *loc,
333 }
334 }
335}
336
337#[derive(Debug, Clone, Copy, PartialEq, Eq)]
339pub enum BinaryOp {
340 Add,
342 Sub,
343 Mul,
344 Div,
345 Mod,
346 Pow,
347
348 Lt,
350 Le,
351 Gt,
352 Ge,
353 Eq,
354 Ne,
355
356 And,
358 Or,
359
360 Concat,
362}
363
364#[derive(Debug, Clone, Copy, PartialEq, Eq)]
366pub enum UnaryOp {
367 Neg, Pos, Not, }
371
372#[derive(Debug, Clone, Copy, PartialEq, Eq)]
374pub enum AssignOp {
375 Assign, AddAssign, SubAssign, MulAssign, DivAssign, ModAssign, PowAssign, }