@@ -14,20 +14,22 @@ enum Elem {
14
14
Operand ( String ) ,
15
15
RightParen ,
16
16
LeftParen ,
17
- Not , // !
17
+ Not , // !
18
18
And , // &&
19
19
Or , // ||
20
20
Ans ( bool ) ,
21
21
}
22
22
23
- pub fn op_order ( op : & Elem ) -> u8 {
23
+ fn op_order ( op : & Elem ) -> u8 {
24
24
match op {
25
25
Elem :: FileCheckOption ( _) => 14 ,
26
+ Elem :: Not => 13 ,
27
+ Elem :: And | Elem :: Or => 12 ,
26
28
_ => 0 ,
27
29
}
28
30
}
29
31
30
- pub fn to_string ( op : & Elem ) -> String {
32
+ fn to_string ( op : & Elem ) -> String {
31
33
match op {
32
34
Elem :: FileCheckOption ( op) => op. to_string ( ) ,
33
35
Elem :: Word ( w) => w. text . clone ( ) ,
@@ -42,14 +44,14 @@ pub fn to_string(op: &Elem) -> String {
42
44
}
43
45
}
44
46
45
- pub fn to_operand ( w : & Word , core : & mut ShellCore ) -> Result < Elem , String > {
47
+ fn to_operand ( w : & Word , core : & mut ShellCore ) -> Result < Elem , String > {
46
48
match w. eval_as_value ( core) {
47
49
Some ( v) => Ok ( Elem :: Operand ( v) ) ,
48
50
None => return Err ( format ! ( "{}: wrong substitution" , & w. text) ) ,
49
51
}
50
52
}
51
53
52
- pub fn pop_operand ( stack : & mut Vec < Elem > , core : & mut ShellCore ) -> Result < Elem , String > {
54
+ fn pop_operand ( stack : & mut Vec < Elem > , core : & mut ShellCore ) -> Result < Elem , String > {
53
55
let n = match stack. pop ( ) {
54
56
Some ( Elem :: Word ( w) ) => {
55
57
match to_operand ( & w, core) {
@@ -93,6 +95,13 @@ impl Command for TestCommand {
93
95
Elem :: FileCheckOption ( ref op) => {
94
96
Self :: unary_operation ( & op, & mut stack, core)
95
97
} ,
98
+ Elem :: Not => match stack. pop ( ) {
99
+ Some ( Elem :: Ans ( res) ) => {
100
+ stack. push ( Elem :: Ans ( !res) ) ;
101
+ Ok ( ( ) )
102
+ } ,
103
+ _ => Err ( "no operand to negate" . to_string ( ) ) ,
104
+ } ,
96
105
_ => Err ( error_message:: syntax ( "TODO" ) ) ,
97
106
} ;
98
107
@@ -132,7 +141,7 @@ impl Command for TestCommand {
132
141
}
133
142
134
143
impl TestCommand {
135
- pub fn rev_polish ( & mut self ) -> Result < Vec < Elem > , Elem > {
144
+ fn rev_polish ( & mut self ) -> Result < Vec < Elem > , Elem > {
136
145
let mut ans = vec ! [ ] ;
137
146
let mut stack = vec ! [ ] ;
138
147
let mut last = None ;
@@ -260,6 +269,26 @@ impl TestCommand {
260
269
true
261
270
}
262
271
272
+ fn eat_not_and_or ( feeder : & mut Feeder , ans : & mut Self ) -> bool {
273
+ if feeder. starts_with ( "!" ) {
274
+ ans. text += & feeder. consume ( 1 ) ;
275
+ ans. elements . push ( Elem :: Not ) ;
276
+ return true ;
277
+ }
278
+ if feeder. starts_with ( "&&" ) {
279
+ ans. text += & feeder. consume ( 2 ) ;
280
+ ans. elements . push ( Elem :: And ) ;
281
+ return true ;
282
+ }
283
+ if feeder. starts_with ( "||" ) {
284
+ ans. text += & feeder. consume ( 2 ) ;
285
+ ans. elements . push ( Elem :: Or ) ;
286
+ return true ;
287
+ }
288
+
289
+ false
290
+ }
291
+
263
292
fn eat_paren ( feeder : & mut Feeder , ans : & mut Self ) -> bool {
264
293
if feeder. starts_with ( "(" ) {
265
294
ans. paren_stack . push ( '(' ) ;
@@ -313,6 +342,7 @@ impl TestCommand {
313
342
}
314
343
315
344
if Self :: eat_file_check_option ( feeder, & mut ans, core)
345
+ || Self :: eat_not_and_or ( feeder, & mut ans)
316
346
|| Self :: eat_paren ( feeder, & mut ans)
317
347
|| Self :: eat_word ( feeder, & mut ans, core) {
318
348
continue ;
0 commit comments