summary refs log tree commit diff stats
path: root/compiler/parser.nim
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/parser.nim')
-rw-r--r--compiler/parser.nim46
1 files changed, 28 insertions, 18 deletions
diff --git a/compiler/parser.nim b/compiler/parser.nim
index 8bd99acd3..3cd1e4d92 100644
--- a/compiler/parser.nim
+++ b/compiler/parser.nim
@@ -39,6 +39,9 @@ type
     inPragma*: int             # Pragma level
     inSemiStmtList*: int
 
+  SymbolMode = enum
+    smNormal, smAllowNil, smAfterDot
+
 proc parseAll*(p: var TParser): PNode
 proc closeParser*(p: var TParser)
 proc parseTopLevelStmt*(p: var TParser): PNode
@@ -62,7 +65,7 @@ proc optPar*(p: var TParser)
 proc optInd*(p: var TParser, n: PNode)
 proc indAndComment*(p: var TParser, n: PNode)
 proc setBaseFlags*(n: PNode, base: TNumericalBase)
-proc parseSymbol*(p: var TParser, allowNil = false): PNode
+proc parseSymbol*(p: var TParser, mode = smNormal): PNode
 proc parseTry(p: var TParser; isExpr: bool): PNode
 proc parseCase(p: var TParser): PNode
 proc parseStmtPragma(p: var TParser): PNode
@@ -304,13 +307,24 @@ proc colcom(p: var TParser, n: PNode) =
   eat(p, tkColon)
   skipComment(p, n)
 
-proc parseSymbol(p: var TParser, allowNil = false): PNode =
+proc parseSymbol(p: var TParser, mode = smNormal): PNode =
   #| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
-  #|        | IDENT | 'addr' | 'type'
+  #|        | IDENT | KEYW
   case p.tok.tokType
-  of tkSymbol, tkAddr, tkType:
+  of tkSymbol:
     result = newIdentNodeP(p.tok.ident, p)
     getTok(p)
+  of tokKeywordLow..tokKeywordHigh:
+    if p.tok.tokType == tkAddr or p.tok.tokType == tkType or mode == smAfterDot:
+      # for backwards compatibility these 2 are always valid:
+      result = newIdentNodeP(p.tok.ident, p)
+      getTok(p)
+    elif p.tok.tokType == tkNil and mode == smAllowNil:
+      result = newNodeP(nkNilLit, p)
+      getTok(p)
+    else:
+      parMessage(p, errIdentifierExpected, p.tok)
+      result = ast.emptyNode
   of tkAccent:
     result = newNodeP(nkAccQuoted, p)
     getTok(p)
@@ -336,16 +350,12 @@ proc parseSymbol(p: var TParser, allowNil = false): PNode =
         break
     eat(p, tkAccent)
   else:
-    if allowNil and p.tok.tokType == tkNil:
-      result = newNodeP(nkNilLit, p)
-      getTok(p)
-    else:
-      parMessage(p, errIdentifierExpected, p.tok)
-      # BUGFIX: We must consume a token here to prevent endless loops!
-      # But: this really sucks for idetools and keywords, so we don't do it
-      # if it is a keyword:
-      #if not isKeyword(p.tok.tokType): getTok(p)
-      result = ast.emptyNode
+    parMessage(p, errIdentifierExpected, p.tok)
+    # BUGFIX: We must consume a token here to prevent endless loops!
+    # But: this really sucks for idetools and keywords, so we don't do it
+    # if it is a keyword:
+    #if not isKeyword(p.tok.tokType): getTok(p)
+    result = ast.emptyNode
 
 proc colonOrEquals(p: var TParser, a: PNode): PNode =
   if p.tok.tokType == tkColon:
@@ -390,7 +400,7 @@ proc dotExpr(p: var TParser, a: PNode): PNode =
   result = newNodeI(nkDotExpr, info)
   optInd(p, result)
   addSon(result, a)
-  addSon(result, parseSymbol(p))
+  addSon(result, parseSymbol(p, smAfterDot))
 
 proc qualifiedIdent(p: var TParser): PNode =
   #| qualifiedIdent = symbol ('.' optInd symbol)?
@@ -1005,10 +1015,10 @@ proc isExprStart(p: TParser): bool =
     result = true
   else: result = false
 
-proc parseSymbolList(p: var TParser, result: PNode, allowNil = false) =
+proc parseSymbolList(p: var TParser, result: PNode) =
   # progress guaranteed
   while true:
-    var s = parseSymbol(p, allowNil)
+    var s = parseSymbol(p, smAllowNil)
     if s.kind == nkEmpty: break
     addSon(result, s)
     if p.tok.tokType != tkComma: break
@@ -1029,7 +1039,7 @@ proc parseTypeDescKAux(p: var TParser, kind: TNodeKind,
     getTok(p)
     let list = newNodeP(nodeKind, p)
     result.addSon list
-    parseSymbolList(p, list, allowNil = true)
+    parseSymbolList(p, list)
 
 proc parseExpr(p: var TParser): PNode =
   #| expr = (ifExpr