@@ -476,14 +476,117 @@ extension AST.Atom {
476
476
}
477
477
478
478
extension AST . Atom {
479
- public struct Callout : Hashable {
480
- public enum Argument : Hashable {
481
- case number( Int )
482
- case string( String )
479
+ public enum Callout : Hashable {
480
+ /// A PCRE callout written `(?C...)`
481
+ public struct PCRE : Hashable {
482
+ public enum Argument : Hashable {
483
+ case number( Int )
484
+ case string( String )
485
+ }
486
+ public var arg : AST . Located < Argument >
487
+
488
+ public init ( _ arg: AST . Located < Argument > ) {
489
+ self . arg = arg
490
+ }
491
+
492
+ /// Whether the argument isn't written explicitly in the source, e.g
493
+ /// `(?C)` which is implicitly `(?C0)`.
494
+ public var isImplicit : Bool { arg. location. isEmpty }
483
495
}
484
- public var arg : AST . Located < Argument >
485
- public init ( _ arg: AST . Located < Argument > ) {
486
- self . arg = arg
496
+
497
+ /// A named Oniguruma callout written `(*name[tag]{args, ...})`
498
+ public struct OnigurumaNamed : Hashable {
499
+ public struct ArgList : Hashable {
500
+ public var leftBrace : SourceLocation
501
+ public var args : [ AST . Located < String > ]
502
+ public var rightBrace : SourceLocation
503
+
504
+ public init (
505
+ _ leftBrace: SourceLocation ,
506
+ _ args: [ AST . Located < String > ] ,
507
+ _ rightBrace: SourceLocation
508
+ ) {
509
+ self . leftBrace = leftBrace
510
+ self . args = args
511
+ self . rightBrace = rightBrace
512
+ }
513
+ }
514
+
515
+ public var name : AST . Located < String >
516
+ public var tag : OnigurumaTag ?
517
+ public var args : ArgList ?
518
+
519
+ public init (
520
+ _ name: AST . Located < String > , tag: OnigurumaTag ? , args: ArgList ?
521
+ ) {
522
+ self . name = name
523
+ self . tag = tag
524
+ self . args = args
525
+ }
526
+ }
527
+
528
+ /// An Oniguruma callout 'of contents', written `(?{...}[tag]D)`
529
+ public struct OnigurumaOfContents : Hashable {
530
+ public enum Direction : Hashable {
531
+ case inProgress // > (the default)
532
+ case inRetraction // <
533
+ case both // X
534
+ }
535
+ public var openBraces : SourceLocation
536
+ public var contents : AST . Located < String >
537
+ public var closeBraces : SourceLocation
538
+ public var tag : OnigurumaTag ?
539
+ public var direction : AST . Located < Direction >
540
+
541
+ public init (
542
+ _ openBraces: SourceLocation , _ contents: AST . Located < String > ,
543
+ _ closeBraces: SourceLocation , tag: OnigurumaTag ? ,
544
+ direction: AST . Located < Direction >
545
+ ) {
546
+ self . openBraces = openBraces
547
+ self . contents = contents
548
+ self . closeBraces = closeBraces
549
+ self . tag = tag
550
+ self . direction = direction
551
+ }
552
+
553
+ /// Whether the direction flag isn't written explicitly in the
554
+ /// source, e.g `(?{x})` which is implicitly `(?{x}>)`.
555
+ public var isDirectionImplicit : Bool { direction. location. isEmpty }
556
+ }
557
+ case pcre( PCRE )
558
+ case onigurumaNamed( OnigurumaNamed )
559
+ case onigurumaOfContents( OnigurumaOfContents )
560
+
561
+ private var _associatedValue : Any {
562
+ switch self {
563
+ case . pcre( let v) : return v
564
+ case . onigurumaNamed( let v) : return v
565
+ case . onigurumaOfContents( let v) : return v
566
+ }
567
+ }
568
+
569
+ func `as`< T> ( _ t: T . Type = T . self) -> T ? {
570
+ _associatedValue as? T
571
+ }
572
+ }
573
+ }
574
+
575
+ extension AST . Atom . Callout {
576
+ /// A tag specifier `[...]` which may appear in an Oniguruma callout.
577
+ public struct OnigurumaTag : Hashable {
578
+ public var leftBracket : SourceLocation
579
+ public var name : AST . Located < String >
580
+ public var rightBracket : SourceLocation
581
+
582
+ public init (
583
+ _ leftBracket: SourceLocation ,
584
+ _ name: AST . Located < String > ,
585
+ _ rightBracket: SourceLocation
586
+ ) {
587
+ self . leftBracket = leftBracket
588
+ self . name = name
589
+ self . rightBracket = rightBracket
487
590
}
488
591
}
489
592
}
0 commit comments