@@ -149,6 +149,9 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
149
149
fail(s " Expected ${explain(kind)} but got ${explain(t.kind)}" )
150
150
}
151
151
152
+ inline def expect [T ](expected : String )(inline f : PartialFunction [TokenKind , T ]): T =
153
+ val kind = peek.kind
154
+ if f.isDefinedAt(kind) then { skip(); f(kind) } else fail(s " Expected ${expected}" )
152
155
153
156
/* The actual parser itself
154
157
* ------------------------
@@ -517,12 +520,12 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
517
520
case _ => externFun()
518
521
}
519
522
520
- def featureFlag (): FeatureFlag =
521
- next().kind match {
523
+ def featureFlag (): FeatureFlag = {
524
+ expect( " feature flag identifier " ) {
522
525
case Ident (" default" ) => FeatureFlag .Default
523
526
case Ident (flag) => FeatureFlag .NamedFeatureFlag (flag)
524
- case _ => fail(" Expected identifier" )
525
527
}
528
+ }
526
529
527
530
def maybeFeatureFlag (): FeatureFlag =
528
531
nonterminal :
@@ -549,9 +552,8 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
549
552
consume(`extern`)
550
553
val posAfterExtern = pos()
551
554
val ff = maybeFeatureFlag()
552
- next().kind match {
555
+ expect( " string literal " ) {
553
556
case Str (contents, _) => ExternInclude (ff, " " , Some (contents), IdDef (" " , Span (source, posAfterExtern, posAfterExtern, Synthesized )))
554
- case _ => fail(" Expected string literal." )
555
557
}
556
558
557
559
def externFun (): Def =
@@ -600,19 +602,16 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
600
602
601
603
def path (): String =
602
604
nonterminal :
603
- next().kind match {
605
+ expect( " path as string literal " ) {
604
606
case Str (s, false ) => s
605
- case _ => fail(" Expected path as string literal." )
606
607
}
607
608
608
609
def string (): String =
609
610
nonterminal :
610
- next().kind match {
611
+ expect( " string literal " ) {
611
612
case Str (s, _) => s
612
- case _ => fail(" Expected string literal." )
613
613
}
614
614
615
-
616
615
def maybeValueTypeAnnotation (): Option [ValueType ] =
617
616
nonterminal :
618
617
if peek(`:`) then Some (valueTypeAnnotation()) else None
@@ -1071,6 +1070,8 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
1071
1070
Call (IdTarget (target), Nil , Nil , List (blk))
1072
1071
}
1073
1072
1073
+ // TODO: This should use `expect` as it follows the same pattern.
1074
+ // However, we currently cannot use `expect` here as the unit literal consists of two tokens
1074
1075
def literal (): Literal =
1075
1076
nonterminal :
1076
1077
peek.kind match {
@@ -1110,10 +1111,7 @@ class RecursiveDescent(positions: Positions, tokens: Seq[Token], source: Source)
1110
1111
}
1111
1112
def ident (): String =
1112
1113
nonterminal :
1113
- next().kind match {
1114
- case Ident (id) => id
1115
- case _ => fail(s " Expected identifier " )
1116
- }
1114
+ expect(" identifier" ) { case Ident (id) => id }
1117
1115
1118
1116
/*
1119
1117
* Type grammar by precedence:
0 commit comments