1use compact_str::CompactString;
2use frost_lexer::Span;
3
4#[derive(Debug, Clone, PartialEq, Default)]
5pub struct Program {
6 pub commands: Vec<CompleteCommand>,
7 pub syntax_errors: Vec<String>,
30}
31
32#[derive(Debug, Clone, PartialEq)]
33pub struct CompleteCommand {
34 pub list: List,
35 pub is_async: bool,
36}
37
38#[derive(Debug, Clone, PartialEq)]
39pub struct List {
40 pub first: Pipeline,
41 pub rest: Vec<(ListOp, Pipeline)>,
42}
43
44#[derive(Debug, Clone, Copy, PartialEq, Eq)]
45pub enum ListOp {
46 And,
47 Or,
48}
49
50#[derive(Debug, Clone, PartialEq)]
51pub struct Pipeline {
52 pub bang: bool,
53 pub commands: Vec<Command>,
54 pub pipe_stderr: Vec<bool>,
55}
56
57#[derive(Debug, Clone, PartialEq)]
58pub enum Command {
59 Simple(SimpleCommand),
60 Subshell(Subshell),
61 BraceGroup(BraceGroup),
62 If(Box<IfClause>),
63 For(Box<ForClause>),
64 While(Box<WhileClause>),
65 Until(Box<UntilClause>),
66 Case(Box<CaseClause>),
67 Select(Box<SelectClause>),
68 FunctionDef(Box<FunctionDef>),
69 Coproc(Box<Coproc>),
70 Time(Box<TimeClause>),
71 ArithCmd(CompactString),
73 Cond(Box<CondExpr>),
75 CFor(Box<CForClause>),
77 Repeat(Box<RepeatClause>),
79 TryAlways(Box<TryAlwaysClause>),
81}
82
83#[derive(Debug, Clone, PartialEq)]
85pub enum CondExpr {
86 Unary(CondOp, Word),
87 Binary(Word, CondOp, Word),
88 Not(Box<CondExpr>),
89 And(Box<CondExpr>, Box<CondExpr>),
90 Or(Box<CondExpr>, Box<CondExpr>),
91}
92
93#[derive(Debug, Clone, PartialEq, Eq)]
95pub enum CondOp {
96 FileExists, IsFile, IsDir, IsSymlink, IsReadable, IsWritable, IsExecutable, IsNonEmpty, IsBlockDev, IsCharDev, IsFifo, IsSocket, IsSetuid, IsSetgid, IsSticky, OwnedByUser, OwnedByGroup, ModifiedSinceRead, IsTty, OptionSet, VarIsSet, StrEmpty, StrNonEmpty, StrEq, StrNeq, StrLt, StrGt, StrMatch, IntEq,
128 IntNe,
129 IntLt,
130 IntLe,
131 IntGt,
132 IntGe,
133 NewerThan, OlderThan, SameFile, }
138
139#[derive(Debug, Clone, PartialEq)]
141pub struct CForClause {
142 pub init: CompactString,
143 pub condition: CompactString,
144 pub step: CompactString,
145 pub body: Vec<CompleteCommand>,
146 pub redirects: Vec<Redirect>,
147}
148
149#[derive(Debug, Clone, PartialEq)]
151pub struct RepeatClause {
152 pub count: Word,
153 pub body: Vec<CompleteCommand>,
154 pub redirects: Vec<Redirect>,
155}
156
157#[derive(Debug, Clone, PartialEq)]
159pub struct TryAlwaysClause {
160 pub try_body: Vec<CompleteCommand>,
161 pub always_body: Vec<CompleteCommand>,
162}
163
164#[derive(Debug, Clone, PartialEq)]
165pub struct SimpleCommand {
166 pub assignments: Vec<Assignment>,
167 pub words: Vec<Word>,
168 pub redirects: Vec<Redirect>,
169}
170
171#[derive(Debug, Clone, PartialEq)]
172pub struct Word {
173 pub parts: Vec<WordPart>,
174 pub span: Span,
175}
176
177#[derive(Debug, Clone, PartialEq)]
178pub enum WordPart {
179 Literal(CompactString),
180 SingleQuoted(CompactString),
181 DoubleQuoted(Vec<WordPart>),
182 AnsiCQuoted(CompactString),
192 DollarVar(CompactString),
193 DollarBrace {
194 param: CompactString,
195 operator: Option<CompactString>,
196 arg: Option<Box<Word>>,
197 },
198 ParamExp(Box<ParamExpansion>),
200 CommandSub(Box<Program>),
201 ArithSub(CompactString),
202 Glob(GlobKind),
203 Tilde(CompactString),
204 BraceExp(BraceExpansion),
206 ProcessSub {
208 kind: ProcessSubKind,
209 body: Box<Program>,
210 },
211 ExtGlob {
213 op: ExtGlobOp,
214 pattern: CompactString,
215 },
216}
217
218#[derive(Debug, Clone, PartialEq)]
225pub struct ParamExpansion {
226 pub flags: Vec<ParamFlag>,
228 pub length: bool,
230 pub is_set_test: bool,
232 pub name: CompactString,
234 pub nested: Option<Box<ParamExpansion>>,
236 pub subscript: Option<Subscript>,
238 pub modifier: Option<ParamModifier>,
240}
241
242#[derive(Debug, Clone, PartialEq)]
244pub enum Subscript {
245 Index(CompactString),
247 All,
249 Star,
251 Pattern {
253 reverse: bool,
254 pattern: CompactString,
255 },
256}
257
258#[derive(Debug, Clone, PartialEq)]
260pub enum ParamModifier {
261 Default { colon: bool, word: Box<Word> },
263 Assign { colon: bool, word: Box<Word> },
265 Alternative { colon: bool, word: Box<Word> },
267 Error { colon: bool, word: Box<Word> },
269 TrimPrefix { longest: bool, pattern: Box<Word> },
271 TrimSuffix { longest: bool, pattern: Box<Word> },
273 Substitute {
275 anchor: SubAnchor,
276 pattern: Box<Word>,
277 replacement: Option<Box<Word>>,
278 },
279 Substring {
281 offset: Box<Word>,
282 length: Option<Box<Word>>,
283 },
284 Case(CaseOp),
286}
287
288#[derive(Debug, Clone, Copy, PartialEq, Eq)]
290pub enum SubAnchor {
291 First,
293 All,
295 Start,
297 End,
299}
300
301#[derive(Debug, Clone, Copy, PartialEq, Eq)]
303pub enum CaseOp {
304 UpperFirst,
306 UpperAll,
308 LowerFirst,
310 LowerAll,
312}
313
314#[derive(Debug, Clone, Copy, PartialEq, Eq)]
316pub enum ParamFlag {
317 Lower, Upper, Capitalize, Split, Join, SplitSep(char), JoinSep(char), SortAsc, SortDesc, Unique, Keys, Values, TypeFlag, Prompt, Quote, Unquote, Expand, Words, Visible, }
337
338#[derive(Debug, Clone, PartialEq)]
342pub enum BraceExpansion {
343 List(Vec<CompactString>),
345 Range {
347 start: CompactString,
348 end: CompactString,
349 step: Option<CompactString>,
350 },
351}
352
353#[derive(Debug, Clone, Copy, PartialEq, Eq)]
355pub enum ProcessSubKind {
356 Input,
358 Output,
360}
361
362#[derive(Debug, Clone, Copy, PartialEq, Eq)]
364pub enum ExtGlobOp {
365 Star,
367 Plus,
369 Question,
371 At,
373 Not,
375}
376
377#[derive(Debug, Clone, Copy, PartialEq, Eq)]
378pub enum GlobKind {
379 Star,
380 Question,
381 At,
382}
383
384#[derive(Debug, Clone, PartialEq)]
385pub struct Redirect {
386 pub fd: Option<u32>,
387 pub op: RedirectOp,
388 pub target: Word,
389 pub span: Span,
390}
391
392#[derive(Debug, Clone, Copy, PartialEq, Eq)]
393pub enum RedirectOp {
394 Less,
395 Greater,
396 DoubleGreater,
397 GreaterPipe,
398 GreaterBang,
399 AmpGreater,
400 AmpDoubleGreater,
401 DoubleLess,
402 TripleLess,
403 DoubleLessDash,
404 LessGreater,
405 FdDup,
406}
407
408#[derive(Debug, Clone, PartialEq)]
409pub struct Assignment {
410 pub name: CompactString,
411 pub subscript: Option<CompactString>,
413 pub op: AssignOp,
414 pub value: Option<Word>,
415 pub array_value: Option<Vec<Word>>,
417 pub span: Span,
418}
419
420#[derive(Debug, Clone, Copy, PartialEq, Eq)]
421pub enum AssignOp {
422 Assign,
423 Append,
424}
425
426#[derive(Debug, Clone, PartialEq)]
427pub struct Subshell {
428 pub body: Vec<CompleteCommand>,
429 pub redirects: Vec<Redirect>,
430}
431
432#[derive(Debug, Clone, PartialEq)]
433pub struct BraceGroup {
434 pub body: Vec<CompleteCommand>,
435 pub redirects: Vec<Redirect>,
436}
437
438#[derive(Debug, Clone, PartialEq)]
439pub struct IfClause {
440 pub condition: Vec<CompleteCommand>,
441 pub then_body: Vec<CompleteCommand>,
442 pub elifs: Vec<(Vec<CompleteCommand>, Vec<CompleteCommand>)>,
443 pub else_body: Option<Vec<CompleteCommand>>,
444 pub redirects: Vec<Redirect>,
445}
446
447#[derive(Debug, Clone, PartialEq)]
448pub struct ForClause {
449 pub var: CompactString,
450 pub words: Option<Vec<Word>>,
451 pub body: Vec<CompleteCommand>,
452 pub redirects: Vec<Redirect>,
453}
454
455#[derive(Debug, Clone, PartialEq)]
456pub struct WhileClause {
457 pub condition: Vec<CompleteCommand>,
458 pub body: Vec<CompleteCommand>,
459 pub redirects: Vec<Redirect>,
460}
461
462#[derive(Debug, Clone, PartialEq)]
463pub struct UntilClause {
464 pub condition: Vec<CompleteCommand>,
465 pub body: Vec<CompleteCommand>,
466 pub redirects: Vec<Redirect>,
467}
468
469#[derive(Debug, Clone, PartialEq)]
470pub struct CaseClause {
471 pub word: Word,
472 pub items: Vec<CaseItem>,
473 pub redirects: Vec<Redirect>,
474}
475
476#[derive(Debug, Clone, PartialEq)]
477pub struct CaseItem {
478 pub patterns: Vec<Word>,
479 pub body: Vec<CompleteCommand>,
480 pub terminator: CaseTerminator,
481}
482
483#[derive(Debug, Clone, Copy, PartialEq, Eq)]
484pub enum CaseTerminator {
485 DoubleSemi,
486 SemiAnd,
487 SemiPipe,
488}
489
490#[derive(Debug, Clone, PartialEq)]
491pub struct SelectClause {
492 pub var: CompactString,
493 pub words: Option<Vec<Word>>,
494 pub body: Vec<CompleteCommand>,
495 pub redirects: Vec<Redirect>,
496}
497
498#[derive(Debug, Clone, PartialEq)]
499pub struct FunctionDef {
500 pub name: CompactString,
501 pub body: Command,
502 pub redirects: Vec<Redirect>,
503}
504
505#[derive(Debug, Clone, PartialEq)]
506pub struct Coproc {
507 pub name: Option<CompactString>,
508 pub command: Command,
509}
510
511#[derive(Debug, Clone, PartialEq)]
512pub struct TimeClause {
513 pub pipeline: Pipeline,
514}