@@ -196,9 +196,9 @@ def pairs(self, prod):
196
196
def pairs (self , prod ):
197
197
return [prod .pair ]
198
198
199
- @_ ('ident COLON expr' )
199
+ @_ ('ident COLON expr' , 'ident EQUALS expr' )
200
200
def pair (self , prod ):
201
- return (prod .ident , prod .expr )
201
+ return (prod .ident , MapValue ( prod [ 1 ], prod .expr ) )
202
202
203
203
@_ ('ident' , 'binary_operator' , 'map' , 'list' , 'string' , 'integer' , 'bool' )
204
204
def expr (self , prod ):
@@ -272,6 +272,9 @@ def is_map(self):
272
272
def is_list (self ):
273
273
return False
274
274
275
+ def is_map_value (self ):
276
+ return False
277
+
275
278
def is_ident (self ):
276
279
return False
277
280
@@ -390,6 +393,12 @@ def to_str(self, pretty=True, indent=4, depth=0):
390
393
def is_binary_operator (self ):
391
394
return True
392
395
396
+ def str_op (self , cmp ):
397
+ return (
398
+ (self .lhs .is_string () and self .lhs .str_op (cmp ))
399
+ or (self .rhs .is_string () and self .rhs .str_op (cmp ))
400
+ )
401
+
393
402
def __eq__ (self , other ):
394
403
return (self .lhs , self .op , self .rhs ) == (other .lhs , other .op , other .rhs )
395
404
@@ -434,7 +443,7 @@ def __str__(self):
434
443
def to_str (self , pretty = True , indent = 4 , depth = 0 ):
435
444
fmt = lambda x : x .to_str (pretty , indent , depth + 1 )
436
445
result = '{'
437
- pairs = [f'{ fmt (k )} : { fmt (v )} ' for k , v in self .items ()]
446
+ pairs = [f'{ fmt (k )} { fmt (v )} ' for k , v in self .items ()]
438
447
if len (self ) == 0 :
439
448
result += '}'
440
449
elif pretty :
@@ -454,13 +463,13 @@ def is_test(self):
454
463
name = self .get ('name' )
455
464
if name is None :
456
465
return False
457
- return 'test' in name .lower ()
466
+ return 'test' in name .value . lower ()
458
467
459
468
def is_benchmark (self ):
460
469
name = self .get ('name' )
461
470
if name is None :
462
471
return False
463
- return 'benchmark' in name .lower ()
472
+ return 'benchmark' in name .value . lower ()
464
473
465
474
def is_dev (self ):
466
475
return self .is_test () or self .is_benchmark ()
@@ -475,8 +484,8 @@ def recurse(self, max_depth=-1, depth=0):
475
484
if depth != max_depth :
476
485
for key , value in self .items ():
477
486
yield (key , value , depth + 1 , self )
478
- if value .is_map ():
479
- yield from value .recurse (max_depth , depth + 1 )
487
+ if value .value . is_map ():
488
+ yield from value .value . recurse (max_depth , depth + 1 )
480
489
481
490
482
491
class List (list , Node ):
@@ -507,6 +516,41 @@ def filter(self, op):
507
516
self [:] = [i for i in self if op (i )]
508
517
509
518
519
+ class MapValue (Node ):
520
+ def __init__ (self , delimiter , value ):
521
+ # map key/value separators can be `:` or `=`.
522
+ assert delimiter in (':' , '=' )
523
+ self .delimiter = delimiter
524
+ self .value = value
525
+
526
+ def __repr__ (self ):
527
+ return f'MapValue({ str (self )} )'
528
+
529
+ def __str__ (self ):
530
+ return self .to_str (False )
531
+
532
+ def __eq__ (self , other ):
533
+ # delimiter doesn't matter for equality comparison
534
+ if isinstance (other , MapValue ):
535
+ return self .value == other .value
536
+ return self .value == other
537
+
538
+ def __len__ (self ):
539
+ return len (self .value )
540
+
541
+ def to_str (self , pretty = True , indent = 4 , depth = 0 ):
542
+ value = self .value .to_str (pretty , indent , depth )
543
+ if self .delimiter == '=' :
544
+ return f' = { value } '
545
+ return f': { value } '
546
+
547
+ def is_map_value (self ):
548
+ return True
549
+
550
+ def filter (self , op ):
551
+ self .value .filter (op )
552
+
553
+
510
554
class Ident (str , Node ):
511
555
def __repr__ (self ):
512
556
return f'Ident({ str (self )} )'
@@ -528,6 +572,9 @@ def __repr__(self):
528
572
def to_str (self , * _ , ** __ ):
529
573
return f'{ super ().__str__ ()} '
530
574
575
+ def str_op (self , cmp ):
576
+ return cmp (self )
577
+
531
578
def __str__ (self ):
532
579
# `"target"` should be shown as `'target'`, not `'"target"'`
533
580
return super ().__str__ ()[1 :- 1 ]
0 commit comments