diff options
Diffstat (limited to 'compiler/parser.nim')
-rw-r--r-- | compiler/parser.nim | 46 |
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 |