Skip to content

Commit

Permalink
Align Parser with syntax
Browse files Browse the repository at this point in the history
 - Change doc comments to match described syntax
 - Refactor `typ` method to make it clear it matches the syntax
  • Loading branch information
odersky committed Feb 11, 2024
1 parent e06b831 commit 772fb97
Show file tree
Hide file tree
Showing 2 changed files with 87 additions and 90 deletions.
174 changes: 86 additions & 88 deletions compiler/src/dotty/tools/dotc/parsing/Parsers.scala
Original file line number Diff line number Diff line change
Expand Up @@ -1532,13 +1532,15 @@ object Parsers {
* PolyFunType ::= HKTypeParamClause '=>' Type
* | HKTypeParamClause ‘->’ [CaptureSet] Type -- under pureFunctions
* FunTypeArgs ::= InfixType
* | `(' [ [ ‘['erased'] FunArgType {`,' FunArgType } ] `)'
* | '(' [ ‘['erased'] TypedFunParam {',' TypedFunParam } ')'
* | `(' [ FunArgType {`,' FunArgType } ] `)'
* | '(' [ TypedFunParam {',' TypedFunParam } ')'
* MatchType ::= InfixType `match` <<< TypeCaseClauses >>>
*/
def typ(): Tree =
val start = in.offset
var imods = Modifiers()
var erasedArgs: ListBuffer[Boolean] = ListBuffer()

def functionRest(params: List[Tree]): Tree =
val paramSpan = Span(start, in.lastOffset)
atSpan(start, in.offset) {
Expand Down Expand Up @@ -1567,7 +1569,8 @@ object Parsers {
else
accept(ARROW)

val resultType = if isPure then capturesAndResult(typ) else typ()
val resultType =
if isPure then capturesAndResult(typ) else typ()
if token == TLARROW then
for case ValDef(_, tpt, _) <- params do
if isByNameType(tpt) then
Expand All @@ -1585,98 +1588,93 @@ object Parsers {
Function(params, resultType)
}

var isValParamList = false
def typeRest(t: Tree) = in.token match
case ARROW | CTXARROW =>
erasedArgs.addOne(false)
functionRest(t :: Nil)
case MATCH =>
matchType(t)
case FORSOME =>
syntaxError(ExistentialTypesNoLongerSupported())
t
case _ if isPureArrow =>
erasedArgs.addOne(false)
functionRest(t :: Nil)
case _ =>
if erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods] then
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
t

val t =
if (in.token == LPAREN) {
var isValParamList = false
if in.token == LPAREN then
in.nextToken()
if in.token == RPAREN then
in.nextToken()
if (in.token == RPAREN) {
in.nextToken()
functionRest(Nil)
}
else {
val paramStart = in.offset
def addErased() =
erasedArgs.addOne(isErasedKw)
if isErasedKw then { in.skipToken(); }
addErased()
val ts = in.currentRegion.withCommasExpected {
functionRest(Nil)
else
val paramStart = in.offset
def addErased() =
erasedArgs.addOne(isErasedKw)
if isErasedKw then in.skipToken()
addErased()
val args =
in.currentRegion.withCommasExpected:
funArgType() match
case Ident(name) if name != tpnme.WILDCARD && in.isColon =>
isValParamList = true
def funParam(start: Offset, mods: Modifiers) = {
atSpan(start) {
def funParam(start: Offset, mods: Modifiers) =
atSpan(start):
addErased()
typedFunParam(in.offset, ident(), imods)
}
}
commaSeparatedRest(
typedFunParam(paramStart, name.toTermName, imods),
() => funParam(in.offset, imods))
case t =>
def funParam() = {
addErased()
funArgType()
}
commaSeparatedRest(t, funParam)
}
accept(RPAREN)
if isValParamList || in.isArrow || isPureArrow then
functionRest(ts)
else {
val ts1 = ts.mapConserve { t =>
if isByNameType(t) then
syntaxError(ByNameParameterNotSupported(t), t.span)
stripByNameType(t)
else
t
}
val tuple = atSpan(start) { makeTupleOrParens(ts1) }
infixTypeRest(
refinedTypeRest(
withTypeRest(
annotTypeRest(
simpleTypeRest(tuple)))))
}
}
}
else if (in.token == LBRACKET) {
val start = in.offset
val tparams = typeParamClause(ParamOwner.TypeParam)
if (in.token == TLARROW)
atSpan(start, in.skipToken())(LambdaTypeTree(tparams, toplevelTyp()))
else if (in.token == ARROW || isPureArrow(nme.PUREARROW)) {
val arrowOffset = in.skipToken()
val body = toplevelTyp()
atSpan(start, arrowOffset) {
getFunction(body) match {
case Some(f) =>
PolyFunction(tparams, body)
case None =>
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
Ident(nme.ERROR.toTypeName)
}
}
}
else { accept(TLARROW); typ() }
}
else if (in.token == INDENT) enclosed(INDENT, typ())
else infixType()

in.token match
case ARROW | CTXARROW =>
erasedArgs.addOne(false)
functionRest(t :: Nil)
case MATCH => matchType(t)
case FORSOME => syntaxError(ExistentialTypesNoLongerSupported()); t
case _ =>
if isPureArrow then
erasedArgs.addOne(false)
functionRest(t :: Nil)
def funArg() =
addErased()
funArgType()
commaSeparatedRest(t, funArg)
accept(RPAREN)
if isValParamList || in.isArrow || isPureArrow then
functionRest(args)
else
if (erasedArgs.contains(true) && !t.isInstanceOf[FunctionWithMods])
syntaxError(ErasedTypesCanOnlyBeFunctionTypes(), implicitKwPos(start))
t
val args1 = args.mapConserve: t =>
if isByNameType(t) then
syntaxError(ByNameParameterNotSupported(t), t.span)
stripByNameType(t)
else
t
val tuple = atSpan(start):
makeTupleOrParens(args1)
typeRest:
infixTypeRest:
refinedTypeRest:
withTypeRest:
annotTypeRest:
simpleTypeRest(tuple)
else if in.token == LBRACKET then
val start = in.offset
val tparams = typeParamClause(ParamOwner.TypeParam)
if in.token == TLARROW then
atSpan(start, in.skipToken()):
LambdaTypeTree(tparams, toplevelTyp())
else if in.token == ARROW || isPureArrow(nme.PUREARROW) then
val arrowOffset = in.skipToken()
val body = toplevelTyp()
atSpan(start, arrowOffset):
getFunction(body) match
case Some(f) =>
PolyFunction(tparams, body)
case None =>
syntaxError(em"Implementation restriction: polymorphic function types must have a value parameter", arrowOffset)
Ident(nme.ERROR.toTypeName)
else
accept(TLARROW)
typ()
else if in.token == INDENT then
enclosed(INDENT, typ())
else
typeRest(infixType())
end typ

private def makeKindProjectorTypeDef(name: TypeName): TypeDef = {
Expand Down Expand Up @@ -1713,7 +1711,7 @@ object Parsers {
private def implicitKwPos(start: Int): Span =
Span(start, start + nme.IMPLICITkw.asSimpleName.length)

/** TypedFunParam ::= id ':' Type */
/** TypedFunParam ::= [`erased`] id ':' Type */
def typedFunParam(start: Offset, name: TermName, mods: Modifiers = EmptyModifiers): ValDef =
atSpan(start) {
acceptColon()
Expand Down Expand Up @@ -2068,7 +2066,7 @@ object Parsers {
*/
def paramType(): Tree = paramTypeOf(paramValueType)

/** ParamValueType ::= [`into`] Type [`*']
/** ParamValueType ::= Type [`*']
*/
def paramValueType(): Tree = {
val t = maybeInto(toplevelTyp)
Expand Down Expand Up @@ -2425,7 +2423,7 @@ object Parsers {
Match(t, inBracesOrIndented(caseClauses(() => caseClause())))
}

/** `match' `{' TypeCaseClauses `}'
/** `match' <<< TypeCaseClauses >>>
*/
def matchType(t: Tree): MatchTypeTree =
atSpan(startOffset(t), accept(MATCH)) {
Expand All @@ -2435,7 +2433,7 @@ object Parsers {
/** FunParams ::= Bindings
* | id
* | `_'
* Bindings ::= `(' [[‘erased’] Binding {`,' Binding}] `)'
* Bindings ::= `(' [Binding {`,' Binding}] `)'
*/
def funParams(mods: Modifiers, location: Location): List[Tree] =
if in.token == LPAREN then
Expand Down Expand Up @@ -3173,7 +3171,7 @@ object Parsers {
* | AccessModifier
* | override
* | opaque
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | erased | inline | transparent
* LocalModifier ::= abstract | final | sealed | open | implicit | lazy | inline | transparent | infix | erased
*/
def modifiers(allowed: BitSet = modifierTokens, start: Modifiers = Modifiers()): Modifiers = {
@tailrec
Expand Down
3 changes: 1 addition & 2 deletions compiler/src/dotty/tools/dotc/transform/Recheck.scala
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,13 @@ import ast.*
import Names.Name
import Phases.Phase
import DenotTransformers.{DenotTransformer, IdentityDenotTransformer, SymTransformer}
import NamerOps.{methodType, linkConstructorParams}
import NamerOps.linkConstructorParams
import NullOpsDecorator.stripNull
import typer.ErrorReporting.err
import typer.ProtoTypes.*
import typer.TypeAssigner.seqLitType
import typer.ConstFold
import typer.ErrorReporting.{Addenda, NothingToAdd}
import NamerOps.methodType
import config.Printers.recheckr
import util.Property
import StdNames.nme
Expand Down

0 comments on commit 772fb97

Please sign in to comment.