@@ -27,7 +27,7 @@ impl BinaryOperator {
27
27
}
28
28
29
29
#[ inline]
30
- pub fn preceeds_unary_expression ( & self ) -> bool {
30
+ pub fn precedes_unary_expression ( & self ) -> bool {
31
31
match self {
32
32
Self :: Caret => true ,
33
33
_ => false ,
@@ -50,6 +50,36 @@ impl BinaryOperator {
50
50
}
51
51
}
52
52
53
+ pub fn left_needs_parentheses ( & self , left : & Expression ) -> bool {
54
+ match left {
55
+ Expression :: Binary ( left) => {
56
+ if self . is_left_associative ( ) {
57
+ self . precedes ( left. operator ( ) )
58
+ } else {
59
+ !left. operator ( ) . precedes ( * self )
60
+ }
61
+ }
62
+ Expression :: Unary ( _) => {
63
+ self . precedes_unary_expression ( )
64
+ }
65
+ _ => false ,
66
+ }
67
+ }
68
+
69
+ pub fn right_needs_parentheses ( & self , right : & Expression ) -> bool {
70
+ match right {
71
+ Expression :: Binary ( right) => {
72
+ if self . is_right_associative ( ) {
73
+ self . precedes ( right. operator ( ) )
74
+ } else {
75
+ !right. operator ( ) . precedes ( * self )
76
+ }
77
+ }
78
+ Expression :: Unary ( _) => false ,
79
+ _ => false ,
80
+ }
81
+ }
82
+
53
83
fn get_precedence ( & self ) -> u8 {
54
84
match self {
55
85
Self :: Or => 0 ,
@@ -113,32 +143,51 @@ impl BinaryExpression {
113
143
}
114
144
}
115
145
146
+ #[ inline]
116
147
pub fn mutate_left ( & mut self ) -> & mut Expression {
117
148
& mut self . left
118
149
}
119
150
151
+ #[ inline]
120
152
pub fn mutate_right ( & mut self ) -> & mut Expression {
121
153
& mut self . right
122
154
}
123
155
156
+ #[ inline]
124
157
pub fn left ( & self ) -> & Expression {
125
158
& self . left
126
159
}
127
160
161
+ #[ inline]
128
162
pub fn right ( & self ) -> & Expression {
129
163
& self . right
130
164
}
131
165
166
+ #[ inline]
132
167
pub fn operator ( & self ) -> BinaryOperator {
133
168
self . operator
134
169
}
135
170
}
136
171
137
172
impl ToLua for BinaryExpression {
138
173
fn to_lua ( & self , generator : & mut LuaGenerator ) {
139
- self . left . to_lua ( generator) ;
174
+ if self . operator . left_needs_parentheses ( & self . left ) {
175
+ generator. push_char ( '(' ) ;
176
+ self . left . to_lua ( generator) ;
177
+ generator. push_char ( ')' ) ;
178
+ } else {
179
+ self . left . to_lua ( generator) ;
180
+ }
181
+
140
182
self . operator . to_lua ( generator) ;
141
- self . right . to_lua ( generator) ;
183
+
184
+ if self . operator . right_needs_parentheses ( & self . right ) {
185
+ generator. push_char ( '(' ) ;
186
+ self . right . to_lua ( generator) ;
187
+ generator. push_char ( ')' ) ;
188
+ } else {
189
+ self . right . to_lua ( generator) ;
190
+ }
142
191
}
143
192
}
144
193
@@ -168,7 +217,7 @@ mod test {
168
217
assert ! ( Caret . precedes( Percent ) ) ;
169
218
assert ! ( Caret . precedes( Concat ) ) ;
170
219
assert ! ( !Caret . precedes( Caret ) ) ;
171
- assert ! ( Caret . preceeds_unary_expression ( ) ) ;
220
+ assert ! ( Caret . precedes_unary_expression ( ) ) ;
172
221
}
173
222
174
223
#[ test]
@@ -188,7 +237,7 @@ mod test {
188
237
assert ! ( !Asterisk . precedes( Percent ) ) ;
189
238
assert ! ( Asterisk . precedes( Concat ) ) ;
190
239
assert ! ( !Asterisk . precedes( Caret ) ) ;
191
- assert ! ( !Asterisk . preceeds_unary_expression ( ) ) ;
240
+ assert ! ( !Asterisk . precedes_unary_expression ( ) ) ;
192
241
}
193
242
194
243
#[ test]
@@ -208,7 +257,7 @@ mod test {
208
257
assert ! ( !Slash . precedes( Percent ) ) ;
209
258
assert ! ( Slash . precedes( Concat ) ) ;
210
259
assert ! ( !Slash . precedes( Caret ) ) ;
211
- assert ! ( !Slash . preceeds_unary_expression ( ) ) ;
260
+ assert ! ( !Slash . precedes_unary_expression ( ) ) ;
212
261
}
213
262
214
263
#[ test]
@@ -228,7 +277,7 @@ mod test {
228
277
assert ! ( !Percent . precedes( Percent ) ) ;
229
278
assert ! ( Percent . precedes( Concat ) ) ;
230
279
assert ! ( !Percent . precedes( Caret ) ) ;
231
- assert ! ( !Percent . preceeds_unary_expression ( ) ) ;
280
+ assert ! ( !Percent . precedes_unary_expression ( ) ) ;
232
281
}
233
282
234
283
#[ test]
@@ -248,7 +297,7 @@ mod test {
248
297
assert ! ( !Plus . precedes( Percent ) ) ;
249
298
assert ! ( Plus . precedes( Concat ) ) ;
250
299
assert ! ( !Plus . precedes( Caret ) ) ;
251
- assert ! ( !Plus . preceeds_unary_expression ( ) ) ;
300
+ assert ! ( !Plus . precedes_unary_expression ( ) ) ;
252
301
}
253
302
254
303
#[ test]
@@ -268,7 +317,7 @@ mod test {
268
317
assert ! ( !Minus . precedes( Percent ) ) ;
269
318
assert ! ( Minus . precedes( Concat ) ) ;
270
319
assert ! ( !Minus . precedes( Caret ) ) ;
271
- assert ! ( !Minus . preceeds_unary_expression ( ) ) ;
320
+ assert ! ( !Minus . precedes_unary_expression ( ) ) ;
272
321
}
273
322
274
323
#[ test]
@@ -288,7 +337,7 @@ mod test {
288
337
assert ! ( !Concat . precedes( Percent ) ) ;
289
338
assert ! ( !Concat . precedes( Concat ) ) ;
290
339
assert ! ( !Concat . precedes( Caret ) ) ;
291
- assert ! ( !Concat . preceeds_unary_expression ( ) ) ;
340
+ assert ! ( !Concat . precedes_unary_expression ( ) ) ;
292
341
}
293
342
294
343
#[ test]
@@ -308,7 +357,146 @@ mod test {
308
357
assert ! ( !And . precedes( Percent ) ) ;
309
358
assert ! ( !And . precedes( Concat ) ) ;
310
359
assert ! ( !And . precedes( Caret ) ) ;
311
- assert ! ( !And . preceeds_unary_expression( ) ) ;
360
+ assert ! ( !And . precedes_unary_expression( ) ) ;
361
+ }
362
+ }
363
+
364
+ mod to_lua {
365
+ use super :: * ;
366
+
367
+ use crate :: nodes:: { DecimalNumber , UnaryExpression , UnaryOperator } ;
368
+
369
+ #[ test]
370
+ fn left_associative_wraps_left_operand_if_has_lower_precedence ( ) {
371
+ let expression = BinaryExpression :: new (
372
+ BinaryOperator :: Asterisk ,
373
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
374
+ BinaryExpression :: new (
375
+ BinaryOperator :: Plus ,
376
+ DecimalNumber :: new ( 1.0 ) . into ( ) ,
377
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
378
+ ) . into ( ) ,
379
+ ) ;
380
+
381
+ assert_eq ! ( "2*(1+3)" , expression. to_lua_string( ) ) ;
382
+ }
383
+
384
+ #[ test]
385
+ fn left_associative_wraps_right_operand_if_has_lower_precedence ( ) {
386
+ let expression = BinaryExpression :: new (
387
+ BinaryOperator :: And ,
388
+ Expression :: False ,
389
+ BinaryExpression :: new (
390
+ BinaryOperator :: Or ,
391
+ Expression :: False ,
392
+ Expression :: True ,
393
+ ) . into ( ) ,
394
+ ) ;
395
+
396
+ assert_eq ! ( "false and(false or true)" , expression. to_lua_string( ) ) ;
397
+ }
398
+
399
+ #[ test]
400
+ fn left_associative_wraps_right_operand_if_has_same_precedence ( ) {
401
+ let expression = BinaryExpression :: new (
402
+ BinaryOperator :: Equal ,
403
+ Expression :: True ,
404
+ BinaryExpression :: new (
405
+ BinaryOperator :: LowerThan ,
406
+ DecimalNumber :: new ( 1.0 ) . into ( ) ,
407
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
408
+ ) . into ( ) ,
409
+ ) ;
410
+
411
+ assert_eq ! ( "true==(1<2)" , expression. to_lua_string( ) ) ;
412
+ }
413
+
414
+ #[ test]
415
+ fn right_associative_wrap_unary_left_operand_if_has_lower_precedence ( ) {
416
+ let expression = BinaryExpression :: new (
417
+ BinaryOperator :: Caret ,
418
+ UnaryExpression :: new (
419
+ UnaryOperator :: Minus ,
420
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
421
+ ) . into ( ) ,
422
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
423
+ ) ;
424
+
425
+ assert_eq ! ( "(-2)^2" , expression. to_lua_string( ) ) ;
426
+ }
427
+
428
+ #[ test]
429
+ fn right_associative_wraps_left_operand_if_has_lower_precedence ( ) {
430
+ let expression = BinaryExpression :: new (
431
+ BinaryOperator :: Caret ,
432
+ BinaryExpression :: new (
433
+ BinaryOperator :: Plus ,
434
+ DecimalNumber :: new ( 1.0 ) . into ( ) ,
435
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
436
+ ) . into ( ) ,
437
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
438
+ ) ;
439
+
440
+ assert_eq ! ( "(1+2)^3" , expression. to_lua_string( ) ) ;
441
+ }
442
+
443
+ #[ test]
444
+ fn right_associative_wraps_left_operand_if_has_same_precedence ( ) {
445
+ let expression = BinaryExpression :: new (
446
+ BinaryOperator :: Caret ,
447
+ BinaryExpression :: new (
448
+ BinaryOperator :: Caret ,
449
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
450
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
451
+ ) . into ( ) ,
452
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
453
+ ) ;
454
+
455
+ assert_eq ! ( "(2^2)^3" , expression. to_lua_string( ) ) ;
456
+ }
457
+
458
+ #[ test]
459
+ fn right_associative_does_not_wrap_right_operand_if_unary ( ) {
460
+ let expression = BinaryExpression :: new (
461
+ BinaryOperator :: Caret ,
462
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
463
+ UnaryExpression :: new (
464
+ UnaryOperator :: Minus ,
465
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
466
+ ) . into ( ) ,
467
+ ) ;
468
+
469
+ assert_eq ! ( "2^-2" , expression. to_lua_string( ) ) ;
470
+ }
471
+
472
+ #[ test]
473
+ fn right_associative_does_not_wrap_right_operand_if_has_same_precedence ( ) {
474
+ let expression = BinaryExpression :: new (
475
+ BinaryOperator :: Caret ,
476
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
477
+ BinaryExpression :: new (
478
+ BinaryOperator :: Caret ,
479
+ DecimalNumber :: new ( 2.0 ) . into ( ) ,
480
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
481
+ ) . into ( ) ,
482
+ ) ;
483
+
484
+ assert_eq ! ( "2^2^3" , expression. to_lua_string( ) ) ;
485
+ }
486
+
487
+ #[ test]
488
+ fn right_associative_does_not_wrap_right_operand_if_has_higher_precedence ( ) {
489
+ let expression = BinaryExpression :: new (
490
+ BinaryOperator :: Concat ,
491
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
492
+ BinaryExpression :: new (
493
+ BinaryOperator :: Plus ,
494
+ DecimalNumber :: new ( 9.0 ) . into ( ) ,
495
+ DecimalNumber :: new ( 3.0 ) . into ( ) ,
496
+ ) . into ( ) ,
497
+ ) ;
498
+
499
+ assert_eq ! ( "3 ..9+3" , expression. to_lua_string( ) ) ;
312
500
}
313
501
}
314
502
0 commit comments