parser.nim 76 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042204320442045204620472048204920502051205220532054205520562057205820592060206120622063206420652066206720682069207020712072207320742075207620772078207920802081208220832084208520862087208820892090209120922093209420952096209720982099210021012102210321042105210621072108210921102111211221132114211521162117211821192120212121222123212421252126212721282129213021312132213321342135213621372138213921402141214221432144214521462147214821492150215121522153215421552156215721582159216021612162216321642165216621672168216921702171217221732174217521762177217821792180218121822183218421852186218721882189219021912192219321942195219621972198219922002201220222032204220522062207220822092210221122122213221422152216221722182219222022212222222322242225222622272228222922302231223222332234223522362237223822392240224122422243224422452246224722482249225022512252225322542255225622572258225922602261226222632264226522662267226822692270227122722273227422752276227722782279228022812282228322842285228622872288228922902291229222932294229522962297229822992300230123022303230423052306230723082309231023112312231323142315231623172318231923202321232223232324232523262327232823292330233123322333233423352336233723382339234023412342234323442345234623472348234923502351235223532354235523562357235823592360236123622363236423652366
  1. #
  2. #
  3. # The Nim Compiler
  4. # (c) Copyright 2015 Andreas Rumpf
  5. #
  6. # See the file "copying.txt", included in this
  7. # distribution, for details about the copyright.
  8. #
  9. # This module implements the parser of the standard Nim syntax.
  10. # The parser strictly reflects the grammar ("doc/grammar.txt"); however
  11. # it uses several helper routines to keep the parser small. A special
  12. # efficient algorithm is used for the precedence levels. The parser here can
  13. # be seen as a refinement of the grammar, as it specifies how the AST is built
  14. # from the grammar and how comments belong to the AST.
  15. # In fact the grammar is generated from this file:
  16. when isMainModule:
  17. # Leave a note in grammar.txt that it is generated:
  18. #| # This file is generated by compiler/parser.nim.
  19. import pegs
  20. var outp = open("doc/grammar.txt", fmWrite)
  21. for line in lines("compiler/parser.nim"):
  22. if line =~ peg" \s* '#| ' {.*}":
  23. outp.write matches[0], "\L"
  24. outp.close
  25. import
  26. llstream, lexer, idents, strutils, ast, msgs, options, lineinfos,
  27. pathutils
  28. when defined(nimpretty):
  29. import layouter
  30. type
  31. TParser* = object # A TParser object represents a file that
  32. # is being parsed
  33. currInd: int # current indentation level
  34. firstTok: bool # Has the first token been read?
  35. hasProgress: bool # some while loop requires progress ensurance
  36. lex*: TLexer # The lexer that is used for parsing
  37. tok*: TToken # The current token
  38. inPragma*: int # Pragma level
  39. inSemiStmtList*: int
  40. emptyNode: PNode
  41. when defined(nimpretty):
  42. em*: Emitter
  43. SymbolMode = enum
  44. smNormal, smAllowNil, smAfterDot
  45. TPrimaryMode = enum
  46. pmNormal, pmTypeDesc, pmTypeDef, pmSkipSuffix
  47. proc parseAll*(p: var TParser): PNode
  48. proc closeParser*(p: var TParser)
  49. proc parseTopLevelStmt*(p: var TParser): PNode
  50. # helpers for the other parsers
  51. proc isOperator*(tok: TToken): bool
  52. proc getTok*(p: var TParser)
  53. proc parMessage*(p: TParser, msg: TMsgKind, arg: string = "")
  54. proc skipComment*(p: var TParser, node: PNode)
  55. proc newNodeP*(kind: TNodeKind, p: TParser): PNode
  56. proc newIntNodeP*(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode
  57. proc newFloatNodeP*(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode
  58. proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode
  59. proc newIdentNodeP*(ident: PIdent, p: TParser): PNode
  60. proc expectIdentOrKeyw*(p: TParser)
  61. proc expectIdent*(p: TParser)
  62. proc parLineInfo*(p: TParser): TLineInfo
  63. proc eat*(p: var TParser, tokType: TTokType)
  64. proc skipInd*(p: var TParser)
  65. proc optPar*(p: var TParser)
  66. proc optInd*(p: var TParser, n: PNode)
  67. proc indAndComment*(p: var TParser, n: PNode)
  68. proc setBaseFlags*(n: PNode, base: TNumericalBase)
  69. proc parseSymbol*(p: var TParser, mode = smNormal): PNode
  70. proc parseTry(p: var TParser; isExpr: bool): PNode
  71. proc parseCase(p: var TParser): PNode
  72. proc parseStmtPragma(p: var TParser): PNode
  73. proc parsePragma(p: var TParser): PNode
  74. proc postExprBlocks(p: var TParser, x: PNode): PNode
  75. proc parseExprStmt(p: var TParser): PNode
  76. proc parseBlock(p: var TParser): PNode
  77. proc primary(p: var TParser, mode: TPrimaryMode): PNode
  78. proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode
  79. # implementation
  80. template prettySection(body) =
  81. when defined(nimpretty): beginSection(p.em)
  82. body
  83. when defined(nimpretty): endSection(p.em)
  84. proc getTok(p: var TParser) =
  85. ## Get the next token from the parser's lexer, and store it in the parser's
  86. ## `tok` member.
  87. rawGetTok(p.lex, p.tok)
  88. p.hasProgress = true
  89. when defined(nimpretty):
  90. emitTok(p.em, p.lex, p.tok)
  91. # skip the additional tokens that nimpretty needs but the parser has no
  92. # interest in:
  93. while p.tok.tokType == tkComment:
  94. rawGetTok(p.lex, p.tok)
  95. emitTok(p.em, p.lex, p.tok)
  96. proc openParser*(p: var TParser, fileIdx: FileIndex, inputStream: PLLStream,
  97. cache: IdentCache; config: ConfigRef) =
  98. ## Open a parser, using the given arguments to set up its internal state.
  99. ##
  100. initToken(p.tok)
  101. openLexer(p.lex, fileIdx, inputStream, cache, config)
  102. when defined(nimpretty):
  103. openEmitter(p.em, cache, config, fileIdx)
  104. getTok(p) # read the first token
  105. p.firstTok = true
  106. p.emptyNode = newNode(nkEmpty)
  107. proc openParser*(p: var TParser, filename: AbsoluteFile, inputStream: PLLStream,
  108. cache: IdentCache; config: ConfigRef) =
  109. openParser(p, fileInfoIdx(config, filename), inputStream, cache, config)
  110. proc closeParser(p: var TParser) =
  111. ## Close a parser, freeing up its resources.
  112. closeLexer(p.lex)
  113. when defined(nimpretty):
  114. closeEmitter(p.em)
  115. proc parMessage(p: TParser, msg: TMsgKind, arg = "") =
  116. ## Produce and emit the parser message `arg` to output.
  117. lexMessageTok(p.lex, msg, p.tok, arg)
  118. proc parMessage(p: TParser, msg: string, tok: TToken) =
  119. ## Produce and emit a parser message to output about the token `tok`
  120. parMessage(p, errGenerated, msg % prettyTok(tok))
  121. proc parMessage(p: TParser, arg: string) =
  122. ## Produce and emit the parser message `arg` to output.
  123. lexMessageTok(p.lex, errGenerated, p.tok, arg)
  124. template withInd(p, body: untyped) =
  125. let oldInd = p.currInd
  126. p.currInd = p.tok.indent
  127. body
  128. p.currInd = oldInd
  129. template newlineWasSplitting(p: var TParser) =
  130. when defined(nimpretty):
  131. layouter.newlineWasSplitting(p.em)
  132. template realInd(p): bool = p.tok.indent > p.currInd
  133. template sameInd(p): bool = p.tok.indent == p.currInd
  134. template sameOrNoInd(p): bool = p.tok.indent == p.currInd or p.tok.indent < 0
  135. proc validInd(p: var TParser): bool {.inline.} =
  136. result = p.tok.indent < 0 or p.tok.indent > p.currInd
  137. proc rawSkipComment(p: var TParser, node: PNode) =
  138. if p.tok.tokType == tkComment:
  139. if node != nil:
  140. when not defined(nimNoNilSeqs):
  141. if node.comment == nil: node.comment = ""
  142. when defined(nimpretty):
  143. if p.tok.commentOffsetB > p.tok.commentOffsetA:
  144. add node.comment, fileSection(p.lex.config, p.lex.fileIdx, p.tok.commentOffsetA, p.tok.commentOffsetB)
  145. else:
  146. add node.comment, p.tok.literal
  147. else:
  148. add(node.comment, p.tok.literal)
  149. else:
  150. parMessage(p, errInternal, "skipComment")
  151. getTok(p)
  152. proc skipComment(p: var TParser, node: PNode) =
  153. if p.tok.indent < 0: rawSkipComment(p, node)
  154. proc flexComment(p: var TParser, node: PNode) =
  155. if p.tok.indent < 0 or realInd(p): rawSkipComment(p, node)
  156. const
  157. errInvalidIndentation = "invalid indentation"
  158. errIdentifierExpected = "identifier expected, but got '$1'"
  159. errExprExpected = "expression expected, but found '$1'"
  160. errTokenExpected = "'$1' expected"
  161. proc skipInd(p: var TParser) =
  162. if p.tok.indent >= 0:
  163. if not realInd(p): parMessage(p, errInvalidIndentation)
  164. proc optPar(p: var TParser) =
  165. if p.tok.indent >= 0:
  166. if p.tok.indent < p.currInd: parMessage(p, errInvalidIndentation)
  167. proc optInd(p: var TParser, n: PNode) =
  168. skipComment(p, n)
  169. skipInd(p)
  170. proc getTokNoInd(p: var TParser) =
  171. getTok(p)
  172. if p.tok.indent >= 0: parMessage(p, errInvalidIndentation)
  173. proc expectIdentOrKeyw(p: TParser) =
  174. if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType):
  175. lexMessage(p.lex, errGenerated, errIdentifierExpected % prettyTok(p.tok))
  176. proc expectIdent(p: TParser) =
  177. if p.tok.tokType != tkSymbol:
  178. lexMessage(p.lex, errGenerated, errIdentifierExpected % prettyTok(p.tok))
  179. proc eat(p: var TParser, tokType: TTokType) =
  180. ## Move the parser to the next token if the current token is of type
  181. ## `tokType`, otherwise error.
  182. if p.tok.tokType == tokType:
  183. getTok(p)
  184. else:
  185. lexMessage(p.lex, errGenerated,
  186. "expected: '" & TokTypeToStr[tokType] & "', but got: '" & prettyTok(p.tok) & "'")
  187. proc parLineInfo(p: TParser): TLineInfo =
  188. ## Retrieve the line information associated with the parser's current state.
  189. result = getLineInfo(p.lex, p.tok)
  190. proc indAndComment(p: var TParser, n: PNode) =
  191. if p.tok.indent > p.currInd:
  192. if p.tok.tokType == tkComment: rawSkipComment(p, n)
  193. else: parMessage(p, errInvalidIndentation)
  194. else:
  195. skipComment(p, n)
  196. proc newNodeP(kind: TNodeKind, p: TParser): PNode =
  197. result = newNodeI(kind, parLineInfo(p))
  198. proc newIntNodeP(kind: TNodeKind, intVal: BiggestInt, p: TParser): PNode =
  199. result = newNodeP(kind, p)
  200. result.intVal = intVal
  201. proc newFloatNodeP(kind: TNodeKind, floatVal: BiggestFloat,
  202. p: TParser): PNode =
  203. result = newNodeP(kind, p)
  204. result.floatVal = floatVal
  205. proc newStrNodeP(kind: TNodeKind, strVal: string, p: TParser): PNode =
  206. result = newNodeP(kind, p)
  207. result.strVal = strVal
  208. proc newIdentNodeP(ident: PIdent, p: TParser): PNode =
  209. result = newNodeP(nkIdent, p)
  210. result.ident = ident
  211. proc parseExpr(p: var TParser): PNode
  212. proc parseStmt(p: var TParser): PNode
  213. proc parseTypeDesc(p: var TParser): PNode
  214. proc parseParamList(p: var TParser, retColon = true): PNode
  215. proc isSigilLike(tok: TToken): bool {.inline.} =
  216. result = tok.tokType == tkOpr and tok.ident.s[0] == '@'
  217. proc isRightAssociative(tok: TToken): bool {.inline.} =
  218. ## Determines whether the token is right assocative.
  219. result = tok.tokType == tkOpr and tok.ident.s[0] == '^'
  220. # or (let L = tok.ident.s.len; L > 1 and tok.ident.s[L-1] == '>'))
  221. proc isOperator(tok: TToken): bool =
  222. ## Determines if the given token is an operator type token.
  223. tok.tokType in {tkOpr, tkDiv, tkMod, tkShl, tkShr, tkIn, tkNotin, tkIs,
  224. tkIsnot, tkNot, tkOf, tkAs, tkDotDot, tkAnd, tkOr, tkXor}
  225. proc isUnary(p: TParser): bool =
  226. ## Check if the current parser token is a unary operator
  227. if p.tok.tokType in {tkOpr, tkDotDot} and
  228. p.tok.strongSpaceB == 0 and
  229. p.tok.strongSpaceA > 0:
  230. result = true
  231. proc checkBinary(p: TParser) {.inline.} =
  232. ## Check if the current parser token is a binary operator.
  233. # we don't check '..' here as that's too annoying
  234. if p.tok.tokType == tkOpr:
  235. if p.tok.strongSpaceB > 0 and p.tok.strongSpaceA == 0:
  236. parMessage(p, warnInconsistentSpacing, prettyTok(p.tok))
  237. #| module = stmt ^* (';' / IND{=})
  238. #|
  239. #| comma = ',' COMMENT?
  240. #| semicolon = ';' COMMENT?
  241. #| colon = ':' COMMENT?
  242. #| colcom = ':' COMMENT?
  243. #|
  244. #| operator = OP0 | OP1 | OP2 | OP3 | OP4 | OP5 | OP6 | OP7 | OP8 | OP9
  245. #| | 'or' | 'xor' | 'and'
  246. #| | 'is' | 'isnot' | 'in' | 'notin' | 'of'
  247. #| | 'div' | 'mod' | 'shl' | 'shr' | 'not' | 'static' | '..'
  248. #|
  249. #| prefixOperator = operator
  250. #|
  251. #| optInd = COMMENT? IND?
  252. #| optPar = (IND{>} | IND{=})?
  253. #|
  254. #| simpleExpr = arrowExpr (OP0 optInd arrowExpr)* pragma?
  255. #| arrowExpr = assignExpr (OP1 optInd assignExpr)*
  256. #| assignExpr = orExpr (OP2 optInd orExpr)*
  257. #| orExpr = andExpr (OP3 optInd andExpr)*
  258. #| andExpr = cmpExpr (OP4 optInd cmpExpr)*
  259. #| cmpExpr = sliceExpr (OP5 optInd sliceExpr)*
  260. #| sliceExpr = ampExpr (OP6 optInd ampExpr)*
  261. #| ampExpr = plusExpr (OP7 optInd plusExpr)*
  262. #| plusExpr = mulExpr (OP8 optInd mulExpr)*
  263. #| mulExpr = dollarExpr (OP9 optInd dollarExpr)*
  264. #| dollarExpr = primary (OP10 optInd primary)*
  265. proc colcom(p: var TParser, n: PNode) =
  266. eat(p, tkColon)
  267. skipComment(p, n)
  268. const tkBuiltInMagics = {tkType, tkStatic, tkAddr}
  269. proc parseSymbol(p: var TParser, mode = smNormal): PNode =
  270. #| symbol = '`' (KEYW|IDENT|literal|(operator|'('|')'|'['|']'|'{'|'}'|'=')+)+ '`'
  271. #| | IDENT | KEYW
  272. case p.tok.tokType
  273. of tkSymbol:
  274. result = newIdentNodeP(p.tok.ident, p)
  275. getTok(p)
  276. of tokKeywordLow..tokKeywordHigh:
  277. if p.tok.tokType in tkBuiltInMagics or mode == smAfterDot:
  278. # for backwards compatibility these 2 are always valid:
  279. result = newIdentNodeP(p.tok.ident, p)
  280. getTok(p)
  281. elif p.tok.tokType == tkNil and mode == smAllowNil:
  282. result = newNodeP(nkNilLit, p)
  283. getTok(p)
  284. else:
  285. parMessage(p, errIdentifierExpected, p.tok)
  286. result = p.emptyNode
  287. of tkAccent:
  288. result = newNodeP(nkAccQuoted, p)
  289. getTok(p)
  290. # progress guaranteed
  291. while true:
  292. case p.tok.tokType
  293. of tkAccent:
  294. if result.len == 0:
  295. parMessage(p, errIdentifierExpected, p.tok)
  296. break
  297. of tkOpr, tkDot, tkDotDot, tkEquals, tkParLe..tkParDotRi:
  298. let lineinfo = parLineInfo(p)
  299. var accm = ""
  300. while p.tok.tokType in {tkOpr, tkDot, tkDotDot, tkEquals,
  301. tkParLe..tkParDotRi}:
  302. accm.add($p.tok)
  303. getTok(p)
  304. let node = newNodeI(nkIdent, lineinfo)
  305. node.ident = p.lex.cache.getIdent(accm)
  306. result.add(node)
  307. of tokKeywordLow..tokKeywordHigh, tkSymbol, tkIntLit..tkCharLit:
  308. result.add(newIdentNodeP(p.lex.cache.getIdent($p.tok), p))
  309. getTok(p)
  310. else:
  311. parMessage(p, errIdentifierExpected, p.tok)
  312. break
  313. eat(p, tkAccent)
  314. else:
  315. parMessage(p, errIdentifierExpected, p.tok)
  316. # BUGFIX: We must consume a token here to prevent endless loops!
  317. # But: this really sucks for idetools and keywords, so we don't do it
  318. # if it is a keyword:
  319. #if not isKeyword(p.tok.tokType): getTok(p)
  320. result = p.emptyNode
  321. proc colonOrEquals(p: var TParser, a: PNode): PNode =
  322. if p.tok.tokType == tkColon:
  323. result = newNodeP(nkExprColonExpr, p)
  324. getTok(p)
  325. newlineWasSplitting(p)
  326. #optInd(p, result)
  327. addSon(result, a)
  328. addSon(result, parseExpr(p))
  329. elif p.tok.tokType == tkEquals:
  330. result = newNodeP(nkExprEqExpr, p)
  331. getTok(p)
  332. #optInd(p, result)
  333. addSon(result, a)
  334. addSon(result, parseExpr(p))
  335. else:
  336. result = a
  337. proc exprColonEqExpr(p: var TParser): PNode =
  338. #| exprColonEqExpr = expr (':'|'=' expr)?
  339. var a = parseExpr(p)
  340. if p.tok.tokType == tkDo:
  341. result = postExprBlocks(p, a)
  342. else:
  343. result = colonOrEquals(p, a)
  344. proc exprList(p: var TParser, endTok: TTokType, result: PNode) =
  345. #| exprList = expr ^+ comma
  346. when defined(nimpretty):
  347. inc p.em.doIndentMore
  348. getTok(p)
  349. optInd(p, result)
  350. # progress guaranteed
  351. while (p.tok.tokType != endTok) and (p.tok.tokType != tkEof):
  352. var a = parseExpr(p)
  353. addSon(result, a)
  354. if p.tok.tokType != tkComma: break
  355. getTok(p)
  356. optInd(p, a)
  357. when defined(nimpretty):
  358. dec p.em.doIndentMore
  359. proc exprColonEqExprListAux(p: var TParser, endTok: TTokType, result: PNode) =
  360. assert(endTok in {tkCurlyRi, tkCurlyDotRi, tkBracketRi, tkParRi})
  361. getTok(p)
  362. flexComment(p, result)
  363. optPar(p)
  364. # progress guaranteed
  365. while p.tok.tokType != endTok and p.tok.tokType != tkEof:
  366. var a = exprColonEqExpr(p)
  367. addSon(result, a)
  368. if p.tok.tokType != tkComma: break
  369. getTok(p)
  370. # (1,) produces a tuple expression
  371. if endTok == tkParRi and p.tok.tokType == tkParRi and result.kind == nkPar:
  372. result.kind = nkTupleConstr
  373. skipComment(p, a)
  374. optPar(p)
  375. eat(p, endTok)
  376. proc exprColonEqExprList(p: var TParser, kind: TNodeKind,
  377. endTok: TTokType): PNode =
  378. #| exprColonEqExprList = exprColonEqExpr (comma exprColonEqExpr)* (comma)?
  379. result = newNodeP(kind, p)
  380. exprColonEqExprListAux(p, endTok, result)
  381. proc dotExpr(p: var TParser, a: PNode): PNode =
  382. #| dotExpr = expr '.' optInd (symbol | '[:' exprList ']')
  383. #| explicitGenericInstantiation = '[:' exprList ']' ( '(' exprColonEqExpr ')' )?
  384. var info = p.parLineInfo
  385. getTok(p)
  386. result = newNodeI(nkDotExpr, info)
  387. optInd(p, result)
  388. addSon(result, a)
  389. addSon(result, parseSymbol(p, smAfterDot))
  390. if p.tok.tokType == tkBracketLeColon and p.tok.strongSpaceA <= 0:
  391. var x = newNodeI(nkBracketExpr, p.parLineInfo)
  392. # rewrite 'x.y[:z]()' to 'y[z](x)'
  393. x.add result[1]
  394. exprList(p, tkBracketRi, x)
  395. eat(p, tkBracketRi)
  396. var y = newNodeI(nkCall, p.parLineInfo)
  397. y.add x
  398. y.add result[0]
  399. if p.tok.tokType == tkParLe and p.tok.strongSpaceA <= 0:
  400. exprColonEqExprListAux(p, tkParRi, y)
  401. result = y
  402. proc qualifiedIdent(p: var TParser): PNode =
  403. #| qualifiedIdent = symbol ('.' optInd symbol)?
  404. result = parseSymbol(p)
  405. if p.tok.tokType == tkDot: result = dotExpr(p, result)
  406. proc setOrTableConstr(p: var TParser): PNode =
  407. #| setOrTableConstr = '{' ((exprColonEqExpr comma)* | ':' ) '}'
  408. result = newNodeP(nkCurly, p)
  409. getTok(p) # skip '{'
  410. optInd(p, result)
  411. if p.tok.tokType == tkColon:
  412. getTok(p) # skip ':'
  413. result.kind = nkTableConstr
  414. else:
  415. # progress guaranteed
  416. while p.tok.tokType notin {tkCurlyRi, tkEof}:
  417. var a = exprColonEqExpr(p)
  418. if a.kind == nkExprColonExpr: result.kind = nkTableConstr
  419. addSon(result, a)
  420. if p.tok.tokType != tkComma: break
  421. getTok(p)
  422. skipComment(p, a)
  423. optPar(p)
  424. eat(p, tkCurlyRi) # skip '}'
  425. proc parseCast(p: var TParser): PNode =
  426. #| castExpr = 'cast' '[' optInd typeDesc optPar ']' '(' optInd expr optPar ')'
  427. result = newNodeP(nkCast, p)
  428. getTok(p)
  429. eat(p, tkBracketLe)
  430. optInd(p, result)
  431. addSon(result, parseTypeDesc(p))
  432. optPar(p)
  433. eat(p, tkBracketRi)
  434. eat(p, tkParLe)
  435. optInd(p, result)
  436. addSon(result, parseExpr(p))
  437. optPar(p)
  438. eat(p, tkParRi)
  439. proc setBaseFlags(n: PNode, base: TNumericalBase) =
  440. case base
  441. of base10: discard
  442. of base2: incl(n.flags, nfBase2)
  443. of base8: incl(n.flags, nfBase8)
  444. of base16: incl(n.flags, nfBase16)
  445. proc parseGStrLit(p: var TParser, a: PNode): PNode =
  446. case p.tok.tokType
  447. of tkGStrLit:
  448. result = newNodeP(nkCallStrLit, p)
  449. addSon(result, a)
  450. addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p))
  451. getTok(p)
  452. of tkGTripleStrLit:
  453. result = newNodeP(nkCallStrLit, p)
  454. addSon(result, a)
  455. addSon(result, newStrNodeP(nkTripleStrLit, p.tok.literal, p))
  456. getTok(p)
  457. else:
  458. result = a
  459. proc complexOrSimpleStmt(p: var TParser): PNode
  460. proc simpleExpr(p: var TParser, mode = pmNormal): PNode
  461. proc semiStmtList(p: var TParser, result: PNode) =
  462. inc p.inSemiStmtList
  463. result.add(complexOrSimpleStmt(p))
  464. # progress guaranteed
  465. while p.tok.tokType == tkSemiColon:
  466. getTok(p)
  467. optInd(p, result)
  468. result.add(complexOrSimpleStmt(p))
  469. dec p.inSemiStmtList
  470. result.kind = nkStmtListExpr
  471. proc parsePar(p: var TParser): PNode =
  472. #| parKeyw = 'discard' | 'include' | 'if' | 'while' | 'case' | 'try'
  473. #| | 'finally' | 'except' | 'for' | 'block' | 'const' | 'let'
  474. #| | 'when' | 'var' | 'mixin'
  475. #| par = '(' optInd
  476. #| ( &parKeyw complexOrSimpleStmt ^+ ';'
  477. #| | ';' complexOrSimpleStmt ^+ ';'
  478. #| | pragmaStmt
  479. #| | simpleExpr ( ('=' expr (';' complexOrSimpleStmt ^+ ';' )? )
  480. #| | (':' expr (',' exprColonEqExpr ^+ ',' )? ) ) )
  481. #| optPar ')'
  482. #
  483. # unfortunately it's ambiguous: (expr: expr) vs (exprStmt); however a
  484. # leading ';' could be used to enforce a 'stmt' context ...
  485. result = newNodeP(nkPar, p)
  486. getTok(p)
  487. optInd(p, result)
  488. flexComment(p, result)
  489. if p.tok.tokType in {tkDiscard, tkInclude, tkIf, tkWhile, tkCase,
  490. tkTry, tkDefer, tkFinally, tkExcept, tkFor, tkBlock,
  491. tkConst, tkLet, tkWhen, tkVar, tkFor,
  492. tkMixin}:
  493. # XXX 'bind' used to be an expression, so we exclude it here;
  494. # tests/reject/tbind2 fails otherwise.
  495. semiStmtList(p, result)
  496. elif p.tok.tokType == tkSemiColon:
  497. # '(;' enforces 'stmt' context:
  498. getTok(p)
  499. optInd(p, result)
  500. semiStmtList(p, result)
  501. elif p.tok.tokType == tkCurlyDotLe:
  502. result.add(parseStmtPragma(p))
  503. elif p.tok.tokType != tkParRi:
  504. var a = simpleExpr(p)
  505. if p.tok.tokType == tkDo:
  506. result = postExprBlocks(p, a)
  507. elif p.tok.tokType == tkEquals:
  508. # special case: allow assignments
  509. let asgn = newNodeP(nkAsgn, p)
  510. getTok(p)
  511. optInd(p, result)
  512. let b = parseExpr(p)
  513. asgn.add a
  514. asgn.add b
  515. result.add(asgn)
  516. if p.tok.tokType == tkSemiColon:
  517. semiStmtList(p, result)
  518. elif p.tok.tokType == tkSemiColon:
  519. # stmt context:
  520. result.add(a)
  521. semiStmtList(p, result)
  522. else:
  523. a = colonOrEquals(p, a)
  524. result.add(a)
  525. if p.tok.tokType == tkComma:
  526. getTok(p)
  527. skipComment(p, a)
  528. # (1,) produces a tuple expression:
  529. if p.tok.tokType == tkParRi:
  530. result.kind = nkTupleConstr
  531. # progress guaranteed
  532. while p.tok.tokType != tkParRi and p.tok.tokType != tkEof:
  533. var a = exprColonEqExpr(p)
  534. addSon(result, a)
  535. if p.tok.tokType != tkComma: break
  536. getTok(p)
  537. skipComment(p, a)
  538. optPar(p)
  539. eat(p, tkParRi)
  540. proc identOrLiteral(p: var TParser, mode: TPrimaryMode): PNode =
  541. #| literal = | INT_LIT | INT8_LIT | INT16_LIT | INT32_LIT | INT64_LIT
  542. #| | UINT_LIT | UINT8_LIT | UINT16_LIT | UINT32_LIT | UINT64_LIT
  543. #| | FLOAT_LIT | FLOAT32_LIT | FLOAT64_LIT
  544. #| | STR_LIT | RSTR_LIT | TRIPLESTR_LIT
  545. #| | CHAR_LIT
  546. #| | NIL
  547. #| generalizedLit = GENERALIZED_STR_LIT | GENERALIZED_TRIPLESTR_LIT
  548. #| identOrLiteral = generalizedLit | symbol | literal
  549. #| | par | arrayConstr | setOrTableConstr
  550. #| | castExpr
  551. #| tupleConstr = '(' optInd (exprColonEqExpr comma?)* optPar ')'
  552. #| arrayConstr = '[' optInd (exprColonEqExpr comma?)* optPar ']'
  553. case p.tok.tokType
  554. of tkSymbol, tkBuiltInMagics, tkOut:
  555. result = newIdentNodeP(p.tok.ident, p)
  556. getTok(p)
  557. result = parseGStrLit(p, result)
  558. of tkAccent:
  559. result = parseSymbol(p) # literals
  560. of tkIntLit:
  561. result = newIntNodeP(nkIntLit, p.tok.iNumber, p)
  562. setBaseFlags(result, p.tok.base)
  563. getTok(p)
  564. of tkInt8Lit:
  565. result = newIntNodeP(nkInt8Lit, p.tok.iNumber, p)
  566. setBaseFlags(result, p.tok.base)
  567. getTok(p)
  568. of tkInt16Lit:
  569. result = newIntNodeP(nkInt16Lit, p.tok.iNumber, p)
  570. setBaseFlags(result, p.tok.base)
  571. getTok(p)
  572. of tkInt32Lit:
  573. result = newIntNodeP(nkInt32Lit, p.tok.iNumber, p)
  574. setBaseFlags(result, p.tok.base)
  575. getTok(p)
  576. of tkInt64Lit:
  577. result = newIntNodeP(nkInt64Lit, p.tok.iNumber, p)
  578. setBaseFlags(result, p.tok.base)
  579. getTok(p)
  580. of tkUIntLit:
  581. result = newIntNodeP(nkUIntLit, p.tok.iNumber, p)
  582. setBaseFlags(result, p.tok.base)
  583. getTok(p)
  584. of tkUInt8Lit:
  585. result = newIntNodeP(nkUInt8Lit, p.tok.iNumber, p)
  586. setBaseFlags(result, p.tok.base)
  587. getTok(p)
  588. of tkUInt16Lit:
  589. result = newIntNodeP(nkUInt16Lit, p.tok.iNumber, p)
  590. setBaseFlags(result, p.tok.base)
  591. getTok(p)
  592. of tkUInt32Lit:
  593. result = newIntNodeP(nkUInt32Lit, p.tok.iNumber, p)
  594. setBaseFlags(result, p.tok.base)
  595. getTok(p)
  596. of tkUInt64Lit:
  597. result = newIntNodeP(nkUInt64Lit, p.tok.iNumber, p)
  598. setBaseFlags(result, p.tok.base)
  599. getTok(p)
  600. of tkFloatLit:
  601. result = newFloatNodeP(nkFloatLit, p.tok.fNumber, p)
  602. setBaseFlags(result, p.tok.base)
  603. getTok(p)
  604. of tkFloat32Lit:
  605. result = newFloatNodeP(nkFloat32Lit, p.tok.fNumber, p)
  606. setBaseFlags(result, p.tok.base)
  607. getTok(p)
  608. of tkFloat64Lit:
  609. result = newFloatNodeP(nkFloat64Lit, p.tok.fNumber, p)
  610. setBaseFlags(result, p.tok.base)
  611. getTok(p)
  612. of tkFloat128Lit:
  613. result = newFloatNodeP(nkFloat128Lit, p.tok.fNumber, p)
  614. setBaseFlags(result, p.tok.base)
  615. getTok(p)
  616. of tkStrLit:
  617. result = newStrNodeP(nkStrLit, p.tok.literal, p)
  618. getTok(p)
  619. of tkRStrLit:
  620. result = newStrNodeP(nkRStrLit, p.tok.literal, p)
  621. getTok(p)
  622. of tkTripleStrLit:
  623. result = newStrNodeP(nkTripleStrLit, p.tok.literal, p)
  624. getTok(p)
  625. of tkCharLit:
  626. result = newIntNodeP(nkCharLit, ord(p.tok.literal[0]), p)
  627. getTok(p)
  628. of tkNil:
  629. result = newNodeP(nkNilLit, p)
  630. getTok(p)
  631. of tkParLe:
  632. # () constructor
  633. if mode in {pmTypeDesc, pmTypeDef}:
  634. result = exprColonEqExprList(p, nkPar, tkParRi)
  635. else:
  636. result = parsePar(p)
  637. of tkCurlyLe:
  638. # {} constructor
  639. result = setOrTableConstr(p)
  640. of tkBracketLe:
  641. # [] constructor
  642. result = exprColonEqExprList(p, nkBracket, tkBracketRi)
  643. of tkCast:
  644. result = parseCast(p)
  645. else:
  646. parMessage(p, errExprExpected, p.tok)
  647. getTok(p) # we must consume a token here to prevend endless loops!
  648. result = p.emptyNode
  649. proc namedParams(p: var TParser, callee: PNode,
  650. kind: TNodeKind, endTok: TTokType): PNode =
  651. let a = callee
  652. result = newNodeP(kind, p)
  653. addSon(result, a)
  654. # progress guaranteed
  655. exprColonEqExprListAux(p, endTok, result)
  656. proc commandParam(p: var TParser, isFirstParam: var bool; mode: TPrimaryMode): PNode =
  657. if mode == pmTypeDesc:
  658. result = simpleExpr(p, mode)
  659. else:
  660. result = parseExpr(p)
  661. if p.tok.tokType == tkDo:
  662. result = postExprBlocks(p, result)
  663. elif p.tok.tokType == tkEquals and not isFirstParam:
  664. let lhs = result
  665. result = newNodeP(nkExprEqExpr, p)
  666. getTok(p)
  667. addSon(result, lhs)
  668. addSon(result, parseExpr(p))
  669. isFirstParam = false
  670. const
  671. tkTypeClasses = {tkRef, tkPtr, tkVar, tkStatic, tkType,
  672. tkEnum, tkTuple, tkObject, tkProc}
  673. proc commandExpr(p: var TParser; r: PNode; mode: TPrimaryMode): PNode =
  674. result = newNodeP(nkCommand, p)
  675. addSon(result, r)
  676. var isFirstParam = true
  677. # progress NOT guaranteed
  678. p.hasProgress = false
  679. addSon result, commandParam(p, isFirstParam, mode)
  680. proc primarySuffix(p: var TParser, r: PNode,
  681. baseIndent: int, mode: TPrimaryMode): PNode =
  682. #| primarySuffix = '(' (exprColonEqExpr comma?)* ')' doBlocks?
  683. #| | doBlocks
  684. #| | '.' optInd symbol generalizedLit?
  685. #| | '[' optInd indexExprList optPar ']'
  686. #| | '{' optInd indexExprList optPar '}'
  687. #| | &( '`'|IDENT|literal|'cast'|'addr'|'type') expr # command syntax
  688. result = r
  689. # progress guaranteed
  690. while p.tok.indent < 0 or
  691. (p.tok.tokType == tkDot and p.tok.indent >= baseIndent):
  692. case p.tok.tokType
  693. of tkParLe:
  694. # progress guaranteed
  695. if p.tok.strongSpaceA > 0:
  696. # inside type sections, expressions such as `ref (int, bar)`
  697. # are parsed as a nkCommand with a single tuple argument (nkPar)
  698. if mode == pmTypeDef:
  699. result = newNodeP(nkCommand, p)
  700. result.addSon r
  701. result.addSon primary(p, pmNormal)
  702. else:
  703. result = commandExpr(p, result, mode)
  704. break
  705. result = namedParams(p, result, nkCall, tkParRi)
  706. if result.len > 1 and result.sons[1].kind == nkExprColonExpr:
  707. result.kind = nkObjConstr
  708. of tkDot:
  709. # progress guaranteed
  710. result = dotExpr(p, result)
  711. result = parseGStrLit(p, result)
  712. of tkBracketLe:
  713. # progress guaranteed
  714. if p.tok.strongSpaceA > 0:
  715. result = commandExpr(p, result, mode)
  716. break
  717. result = namedParams(p, result, nkBracketExpr, tkBracketRi)
  718. of tkCurlyLe:
  719. # progress guaranteed
  720. if p.tok.strongSpaceA > 0:
  721. result = commandExpr(p, result, mode)
  722. break
  723. result = namedParams(p, result, nkCurlyExpr, tkCurlyRi)
  724. of tkSymbol, tkAccent, tkIntLit..tkCharLit, tkNil, tkCast,
  725. tkOpr, tkDotDot, tkTypeClasses - {tkRef, tkPtr}:
  726. # XXX: In type sections we allow the free application of the
  727. # command syntax, with the exception of expressions such as
  728. # `foo ref` or `foo ptr`. Unfortunately, these two are also
  729. # used as infix operators for the memory regions feature and
  730. # the current parsing rules don't play well here.
  731. if p.inPragma == 0 and (isUnary(p) or p.tok.tokType notin {tkOpr, tkDotDot}):
  732. # actually parsing {.push hints:off.} as {.push(hints:off).} is a sweet
  733. # solution, but pragmas.nim can't handle that
  734. result = commandExpr(p, result, mode)
  735. break
  736. else:
  737. break
  738. proc parseOperators(p: var TParser, headNode: PNode,
  739. limit: int, mode: TPrimaryMode): PNode =
  740. result = headNode
  741. # expand while operators have priorities higher than 'limit'
  742. var opPrec = getPrecedence(p.tok, false)
  743. let modeB = if mode == pmTypeDef: pmTypeDesc else: mode
  744. # the operator itself must not start on a new line:
  745. # progress guaranteed
  746. while opPrec >= limit and p.tok.indent < 0 and not isUnary(p):
  747. checkBinary(p)
  748. var leftAssoc = 1-ord(isRightAssociative(p.tok))
  749. var a = newNodeP(nkInfix, p)
  750. var opNode = newIdentNodeP(p.tok.ident, p) # skip operator:
  751. getTok(p)
  752. flexComment(p, a)
  753. optPar(p)
  754. # read sub-expression with higher priority:
  755. var b = simpleExprAux(p, opPrec + leftAssoc, modeB)
  756. addSon(a, opNode)
  757. addSon(a, result)
  758. addSon(a, b)
  759. result = a
  760. opPrec = getPrecedence(p.tok, false)
  761. proc simpleExprAux(p: var TParser, limit: int, mode: TPrimaryMode): PNode =
  762. result = primary(p, mode)
  763. if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)) and
  764. mode == pmNormal:
  765. var pragmaExp = newNodeP(nkPragmaExpr, p)
  766. pragmaExp.addSon result
  767. pragmaExp.addSon p.parsePragma
  768. result = pragmaExp
  769. result = parseOperators(p, result, limit, mode)
  770. proc simpleExpr(p: var TParser, mode = pmNormal): PNode =
  771. when defined(nimpretty):
  772. inc p.em.doIndentMore
  773. result = simpleExprAux(p, -1, mode)
  774. when defined(nimpretty):
  775. dec p.em.doIndentMore
  776. proc parseIfExpr(p: var TParser, kind: TNodeKind): PNode =
  777. #| condExpr = expr colcom expr optInd
  778. #| ('elif' expr colcom expr optInd)*
  779. #| 'else' colcom expr
  780. #| ifExpr = 'if' condExpr
  781. #| whenExpr = 'when' condExpr
  782. when true:
  783. result = newNodeP(kind, p)
  784. while true:
  785. getTok(p) # skip `if`, `when`, `elif`
  786. var branch = newNodeP(nkElifExpr, p)
  787. optInd(p, branch)
  788. addSon(branch, parseExpr(p))
  789. colcom(p, branch)
  790. addSon(branch, parseStmt(p))
  791. skipComment(p, branch)
  792. addSon(result, branch)
  793. if p.tok.tokType != tkElif: break # or not sameOrNoInd(p): break
  794. if p.tok.tokType == tkElse: # and sameOrNoInd(p):
  795. var branch = newNodeP(nkElseExpr, p)
  796. eat(p, tkElse)
  797. colcom(p, branch)
  798. addSon(branch, parseStmt(p))
  799. addSon(result, branch)
  800. else:
  801. var
  802. b: PNode
  803. wasIndented = false
  804. result = newNodeP(kind, p)
  805. getTok(p)
  806. let branch = newNodeP(nkElifExpr, p)
  807. addSon(branch, parseExpr(p))
  808. colcom(p, branch)
  809. let oldInd = p.currInd
  810. if realInd(p):
  811. p.currInd = p.tok.indent
  812. wasIndented = true
  813. addSon(branch, parseExpr(p))
  814. result.add branch
  815. while sameInd(p) or not wasIndented:
  816. case p.tok.tokType
  817. of tkElif:
  818. b = newNodeP(nkElifExpr, p)
  819. getTok(p)
  820. optInd(p, b)
  821. addSon(b, parseExpr(p))
  822. of tkElse:
  823. b = newNodeP(nkElseExpr, p)
  824. getTok(p)
  825. else: break
  826. colcom(p, b)
  827. addSon(b, parseStmt(p))
  828. addSon(result, b)
  829. if b.kind == nkElseExpr: break
  830. if wasIndented:
  831. p.currInd = oldInd
  832. proc parsePragma(p: var TParser): PNode =
  833. #| pragma = '{.' optInd (exprColonExpr comma?)* optPar ('.}' | '}')
  834. result = newNodeP(nkPragma, p)
  835. inc p.inPragma
  836. when defined(nimpretty):
  837. inc p.em.doIndentMore
  838. inc p.em.keepIndents
  839. getTok(p)
  840. optInd(p, result)
  841. while p.tok.tokType notin {tkCurlyDotRi, tkCurlyRi, tkEof}:
  842. p.hasProgress = false
  843. var a = exprColonEqExpr(p)
  844. if not p.hasProgress: break
  845. addSon(result, a)
  846. if p.tok.tokType == tkComma:
  847. getTok(p)
  848. skipComment(p, a)
  849. optPar(p)
  850. if p.tok.tokType in {tkCurlyDotRi, tkCurlyRi}:
  851. when defined(nimpretty):
  852. if p.tok.tokType == tkCurlyRi: curlyRiWasPragma(p.em)
  853. getTok(p)
  854. else:
  855. parMessage(p, "expected '.}'")
  856. dec p.inPragma
  857. when defined(nimpretty):
  858. dec p.em.doIndentMore
  859. dec p.em.keepIndents
  860. proc identVis(p: var TParser; allowDot=false): PNode =
  861. #| identVis = symbol opr? # postfix position
  862. #| identVisDot = symbol '.' optInd symbol opr?
  863. var a = parseSymbol(p)
  864. if p.tok.tokType == tkOpr:
  865. when defined(nimpretty):
  866. starWasExportMarker(p.em)
  867. result = newNodeP(nkPostfix, p)
  868. addSon(result, newIdentNodeP(p.tok.ident, p))
  869. addSon(result, a)
  870. getTok(p)
  871. elif p.tok.tokType == tkDot and allowDot:
  872. result = dotExpr(p, a)
  873. else:
  874. result = a
  875. proc identWithPragma(p: var TParser; allowDot=false): PNode =
  876. #| identWithPragma = identVis pragma?
  877. #| identWithPragmaDot = identVisDot pragma?
  878. var a = identVis(p, allowDot)
  879. if p.tok.tokType == tkCurlyDotLe:
  880. result = newNodeP(nkPragmaExpr, p)
  881. addSon(result, a)
  882. addSon(result, parsePragma(p))
  883. else:
  884. result = a
  885. type
  886. TDeclaredIdentFlag = enum
  887. withPragma, # identifier may have pragma
  888. withBothOptional # both ':' and '=' parts are optional
  889. withDot # allow 'var ident.ident = value'
  890. TDeclaredIdentFlags = set[TDeclaredIdentFlag]
  891. proc parseIdentColonEquals(p: var TParser, flags: TDeclaredIdentFlags): PNode =
  892. #| declColonEquals = identWithPragma (comma identWithPragma)* comma?
  893. #| (':' optInd typeDesc)? ('=' optInd expr)?
  894. #| identColonEquals = ident (comma ident)* comma?
  895. #| (':' optInd typeDesc)? ('=' optInd expr)?)
  896. var a: PNode
  897. result = newNodeP(nkIdentDefs, p)
  898. # progress guaranteed
  899. while true:
  900. case p.tok.tokType
  901. of tkSymbol, tkAccent:
  902. if withPragma in flags: a = identWithPragma(p, allowDot=withDot in flags)
  903. else: a = parseSymbol(p)
  904. if a.kind == nkEmpty: return
  905. else: break
  906. addSon(result, a)
  907. if p.tok.tokType != tkComma: break
  908. getTok(p)
  909. optInd(p, a)
  910. if p.tok.tokType == tkColon:
  911. getTok(p)
  912. optInd(p, result)
  913. addSon(result, parseTypeDesc(p))
  914. else:
  915. addSon(result, newNodeP(nkEmpty, p))
  916. if p.tok.tokType != tkEquals and withBothOptional notin flags:
  917. parMessage(p, "':' or '=' expected, but got '$1'", p.tok)
  918. if p.tok.tokType == tkEquals:
  919. getTok(p)
  920. optInd(p, result)
  921. addSon(result, parseExpr(p))
  922. else:
  923. addSon(result, newNodeP(nkEmpty, p))
  924. proc parseTuple(p: var TParser, indentAllowed = false): PNode =
  925. #| inlTupleDecl = 'tuple'
  926. #| [' optInd (identColonEquals (comma/semicolon)?)* optPar ']'
  927. #| extTupleDecl = 'tuple'
  928. #| COMMENT? (IND{>} identColonEquals (IND{=} identColonEquals)*)?
  929. #| tupleClass = 'tuple'
  930. result = newNodeP(nkTupleTy, p)
  931. getTok(p)
  932. if p.tok.tokType == tkBracketLe:
  933. getTok(p)
  934. optInd(p, result)
  935. # progress guaranteed
  936. while p.tok.tokType in {tkSymbol, tkAccent}:
  937. var a = parseIdentColonEquals(p, {})
  938. addSon(result, a)
  939. if p.tok.tokType notin {tkComma, tkSemiColon}: break
  940. when defined(nimpretty):
  941. commaWasSemicolon(p.em)
  942. getTok(p)
  943. skipComment(p, a)
  944. optPar(p)
  945. eat(p, tkBracketRi)
  946. elif indentAllowed:
  947. skipComment(p, result)
  948. if realInd(p):
  949. withInd(p):
  950. rawSkipComment(p, result)
  951. # progress guaranteed
  952. while true:
  953. case p.tok.tokType
  954. of tkSymbol, tkAccent:
  955. var a = parseIdentColonEquals(p, {})
  956. if p.tok.indent < 0 or p.tok.indent >= p.currInd:
  957. rawSkipComment(p, a)
  958. addSon(result, a)
  959. of tkEof: break
  960. else:
  961. parMessage(p, errIdentifierExpected, p.tok)
  962. break
  963. if not sameInd(p): break
  964. elif p.tok.tokType == tkParLe:
  965. parMessage(p, errGenerated, "the syntax for tuple types is 'tuple[...]', not 'tuple(...)'")
  966. else:
  967. result = newNodeP(nkTupleClassTy, p)
  968. proc parseParamList(p: var TParser, retColon = true): PNode =
  969. #| paramList = '(' declColonEquals ^* (comma/semicolon) ')'
  970. #| paramListArrow = paramList? ('->' optInd typeDesc)?
  971. #| paramListColon = paramList? (':' optInd typeDesc)?
  972. var a: PNode
  973. result = newNodeP(nkFormalParams, p)
  974. addSon(result, p.emptyNode) # return type
  975. when defined(nimpretty):
  976. inc p.em.doIndentMore
  977. inc p.em.keepIndents
  978. let hasParLe = p.tok.tokType == tkParLe and p.tok.indent < 0
  979. if hasParLe:
  980. getTok(p)
  981. optInd(p, result)
  982. # progress guaranteed
  983. while true:
  984. case p.tok.tokType
  985. of tkSymbol, tkAccent:
  986. a = parseIdentColonEquals(p, {withBothOptional, withPragma})
  987. of tkParRi:
  988. break
  989. of tkVar:
  990. parMessage(p, errGenerated, "the syntax is 'parameter: var T', not 'var parameter: T'")
  991. break
  992. else:
  993. parMessage(p, "expected closing ')'")
  994. break
  995. addSon(result, a)
  996. if p.tok.tokType notin {tkComma, tkSemiColon}: break
  997. when defined(nimpretty):
  998. commaWasSemicolon(p.em)
  999. getTok(p)
  1000. skipComment(p, a)
  1001. optPar(p)
  1002. eat(p, tkParRi)
  1003. let hasRet = if retColon: p.tok.tokType == tkColon
  1004. else: p.tok.tokType == tkOpr and p.tok.ident.s == "->"
  1005. if hasRet and p.tok.indent < 0:
  1006. getTok(p)
  1007. optInd(p, result)
  1008. result.sons[0] = parseTypeDesc(p)
  1009. elif not retColon and not hasParLe:
  1010. # Mark as "not there" in order to mark for deprecation in the semantic pass:
  1011. result = p.emptyNode
  1012. when defined(nimpretty):
  1013. dec p.em.doIndentMore
  1014. dec p.em.keepIndents
  1015. proc optPragmas(p: var TParser): PNode =
  1016. if p.tok.tokType == tkCurlyDotLe and (p.tok.indent < 0 or realInd(p)):
  1017. result = parsePragma(p)
  1018. else:
  1019. result = p.emptyNode
  1020. proc parseDoBlock(p: var TParser; info: TLineInfo): PNode =
  1021. #| doBlock = 'do' paramListArrow pragmas? colcom stmt
  1022. let params = parseParamList(p, retColon=false)
  1023. let pragmas = optPragmas(p)
  1024. colcom(p, result)
  1025. result = parseStmt(p)
  1026. if params.kind != nkEmpty:
  1027. result = newProcNode(nkDo, info,
  1028. body = result, params = params, name = p.emptyNode, pattern = p.emptyNode,
  1029. genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
  1030. proc parseProcExpr(p: var TParser; isExpr: bool; kind: TNodeKind): PNode =
  1031. #| procExpr = 'proc' paramListColon pragmas? ('=' COMMENT? stmt)?
  1032. # either a proc type or a anonymous proc
  1033. let info = parLineInfo(p)
  1034. getTok(p)
  1035. let hasSignature = p.tok.tokType in {tkParLe, tkColon} and p.tok.indent < 0
  1036. let params = parseParamList(p)
  1037. let pragmas = optPragmas(p)
  1038. if p.tok.tokType == tkEquals and isExpr:
  1039. getTok(p)
  1040. skipComment(p, result)
  1041. result = newProcNode(kind, info, body = parseStmt(p),
  1042. params = params, name = p.emptyNode, pattern = p.emptyNode,
  1043. genericParams = p.emptyNode, pragmas = pragmas, exceptions = p.emptyNode)
  1044. else:
  1045. result = newNodeI(nkProcTy, info)
  1046. if hasSignature:
  1047. addSon(result, params)
  1048. if kind == nkFuncDef:
  1049. parMessage(p, "func keyword is not allowed in type descriptions, use proc with {.noSideEffect.} pragma instead")
  1050. addSon(result, pragmas)
  1051. proc isExprStart(p: TParser): bool =
  1052. case p.tok.tokType
  1053. of tkSymbol, tkAccent, tkOpr, tkNot, tkNil, tkCast, tkIf, tkFor,
  1054. tkProc, tkFunc, tkIterator, tkBind, tkBuiltInMagics,
  1055. tkParLe, tkBracketLe, tkCurlyLe, tkIntLit..tkCharLit, tkVar, tkRef, tkPtr,
  1056. tkTuple, tkObject, tkWhen, tkCase, tkOut:
  1057. result = true
  1058. else: result = false
  1059. proc parseSymbolList(p: var TParser, result: PNode) =
  1060. # progress guaranteed
  1061. while true:
  1062. var s = parseSymbol(p, smAllowNil)
  1063. if s.kind == nkEmpty: break
  1064. addSon(result, s)
  1065. if p.tok.tokType != tkComma: break
  1066. getTok(p)
  1067. optInd(p, s)
  1068. proc parseTypeDescKAux(p: var TParser, kind: TNodeKind,
  1069. mode: TPrimaryMode): PNode =
  1070. #| distinct = 'distinct' optInd typeDesc
  1071. result = newNodeP(kind, p)
  1072. getTok(p)
  1073. if p.tok.indent != -1 and p.tok.indent <= p.currInd: return
  1074. optInd(p, result)
  1075. if not isOperator(p.tok) and isExprStart(p):
  1076. addSon(result, primary(p, mode))
  1077. if kind == nkDistinctTy and p.tok.tokType == tkSymbol:
  1078. # XXX document this feature!
  1079. var nodeKind: TNodeKind
  1080. if p.tok.ident.s == "with":
  1081. nodeKind = nkWith
  1082. elif p.tok.ident.s == "without":
  1083. nodeKind = nkWithout
  1084. else:
  1085. return result
  1086. getTok(p)
  1087. let list = newNodeP(nodeKind, p)
  1088. result.addSon list
  1089. parseSymbolList(p, list)
  1090. proc parseVarTuple(p: var TParser): PNode
  1091. proc parseFor(p: var TParser): PNode =
  1092. #| forStmt = 'for' (identWithPragma ^+ comma) 'in' expr colcom stmt
  1093. #| forExpr = forStmt
  1094. getTokNoInd(p)
  1095. result = newNodeP(nkForStmt, p)
  1096. if p.tok.tokType == tkParLe:
  1097. addSon(result, parseVarTuple(p))
  1098. else:
  1099. var a = identWithPragma(p)
  1100. addSon(result, a)
  1101. while p.tok.tokType == tkComma:
  1102. getTok(p)
  1103. optInd(p, a)
  1104. if p.tok.tokType == tkParLe:
  1105. addSon(result, parseVarTuple(p))
  1106. break
  1107. a = identWithPragma(p)
  1108. addSon(result, a)
  1109. eat(p, tkIn)
  1110. addSon(result, parseExpr(p))
  1111. colcom(p, result)
  1112. addSon(result, parseStmt(p))
  1113. template nimprettyDontTouch(body) =
  1114. when defined(nimpretty):
  1115. inc p.em.keepIndents
  1116. body
  1117. when defined(nimpretty):
  1118. dec p.em.keepIndents
  1119. proc parseExpr(p: var TParser): PNode =
  1120. #| expr = (blockExpr
  1121. #| | ifExpr
  1122. #| | whenExpr
  1123. #| | caseExpr
  1124. #| | forExpr
  1125. #| | tryExpr)
  1126. #| / simpleExpr
  1127. case p.tok.tokType:
  1128. of tkBlock:
  1129. nimprettyDontTouch:
  1130. result = parseBlock(p)
  1131. of tkIf:
  1132. nimprettyDontTouch:
  1133. result = parseIfExpr(p, nkIfExpr)
  1134. of tkFor:
  1135. nimprettyDontTouch:
  1136. result = parseFor(p)
  1137. of tkWhen:
  1138. nimprettyDontTouch:
  1139. result = parseIfExpr(p, nkWhenExpr)
  1140. of tkCase:
  1141. # Currently we think nimpretty is good enough with case expressions,
  1142. # so it is allowed to touch them:
  1143. #nimprettyDontTouch:
  1144. result = parseCase(p)
  1145. of tkTry:
  1146. nimprettyDontTouch:
  1147. result = parseTry(p, isExpr=true)
  1148. else: result = simpleExpr(p)
  1149. proc parseEnum(p: var TParser): PNode
  1150. proc parseObject(p: var TParser): PNode
  1151. proc parseTypeClass(p: var TParser): PNode
  1152. proc primary(p: var TParser, mode: TPrimaryMode): PNode =
  1153. #| typeKeyw = 'var' | 'out' | 'ref' | 'ptr' | 'shared' | 'tuple'
  1154. #| | 'proc' | 'iterator' | 'distinct' | 'object' | 'enum'
  1155. #| primary = typeKeyw typeDescK
  1156. #| / prefixOperator* identOrLiteral primarySuffix*
  1157. #| / 'bind' primary
  1158. if isOperator(p.tok):
  1159. let isSigil = isSigilLike(p.tok)
  1160. result = newNodeP(nkPrefix, p)
  1161. var a = newIdentNodeP(p.tok.ident, p)
  1162. addSon(result, a)
  1163. getTok(p)
  1164. optInd(p, a)
  1165. if isSigil:
  1166. #XXX prefix operators
  1167. let baseInd = p.lex.currLineIndent
  1168. addSon(result, primary(p, pmSkipSuffix))
  1169. result = primarySuffix(p, result, baseInd, mode)
  1170. else:
  1171. addSon(result, primary(p, pmNormal))
  1172. return
  1173. case p.tok.tokType:
  1174. of tkTuple: result = parseTuple(p, mode == pmTypeDef)
  1175. of tkProc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
  1176. of tkFunc: result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkFuncDef)
  1177. of tkIterator:
  1178. result = parseProcExpr(p, mode notin {pmTypeDesc, pmTypeDef}, nkLambda)
  1179. if result.kind == nkLambda: result.kind = nkIteratorDef
  1180. else: result.kind = nkIteratorTy
  1181. of tkEnum:
  1182. if mode == pmTypeDef:
  1183. prettySection:
  1184. result = parseEnum(p)
  1185. else:
  1186. result = newNodeP(nkEnumTy, p)
  1187. getTok(p)
  1188. of tkObject:
  1189. if mode == pmTypeDef:
  1190. prettySection:
  1191. result = parseObject(p)
  1192. else:
  1193. result = newNodeP(nkObjectTy, p)
  1194. getTok(p)
  1195. of tkConcept:
  1196. if mode == pmTypeDef:
  1197. result = parseTypeClass(p)
  1198. else:
  1199. parMessage(p, "the 'concept' keyword is only valid in 'type' sections")
  1200. of tkBind:
  1201. result = newNodeP(nkBind, p)
  1202. getTok(p)
  1203. optInd(p, result)
  1204. addSon(result, primary(p, pmNormal))
  1205. of tkVar: result = parseTypeDescKAux(p, nkVarTy, mode)
  1206. of tkRef: result = parseTypeDescKAux(p, nkRefTy, mode)
  1207. of tkPtr: result = parseTypeDescKAux(p, nkPtrTy, mode)
  1208. of tkDistinct: result = parseTypeDescKAux(p, nkDistinctTy, mode)
  1209. else:
  1210. let baseInd = p.lex.currLineIndent
  1211. result = identOrLiteral(p, mode)
  1212. if mode != pmSkipSuffix:
  1213. result = primarySuffix(p, result, baseInd, mode)
  1214. proc binaryNot(p: var TParser; a: PNode): PNode =
  1215. if p.tok.tokType == tkNot:
  1216. let notOpr = newIdentNodeP(p.tok.ident, p)
  1217. getTok(p)
  1218. optInd(p, notOpr)
  1219. let b = parseExpr(p)
  1220. result = newNodeP(nkInfix, p)
  1221. result.add notOpr
  1222. result.add a
  1223. result.add b
  1224. else:
  1225. result = a
  1226. proc parseTypeDesc(p: var TParser): PNode =
  1227. #| typeDesc = simpleExpr ('not' expr)?
  1228. newlineWasSplitting(p)
  1229. result = simpleExpr(p, pmTypeDesc)
  1230. result = binaryNot(p, result)
  1231. proc parseTypeDefAux(p: var TParser): PNode =
  1232. #| typeDefAux = simpleExpr ('not' expr)?
  1233. #| | 'concept' typeClass
  1234. result = simpleExpr(p, pmTypeDef)
  1235. result = binaryNot(p, result)
  1236. proc makeCall(n: PNode): PNode =
  1237. ## Creates a call if the given node isn't already a call.
  1238. if n.kind in nkCallKinds:
  1239. result = n
  1240. else:
  1241. result = newNodeI(nkCall, n.info)
  1242. result.add n
  1243. proc postExprBlocks(p: var TParser, x: PNode): PNode =
  1244. #| postExprBlocks = ':' stmt? ( IND{=} doBlock
  1245. #| | IND{=} 'of' exprList ':' stmt
  1246. #| | IND{=} 'elif' expr ':' stmt
  1247. #| | IND{=} 'except' exprList ':' stmt
  1248. #| | IND{=} 'else' ':' stmt )*
  1249. result = x
  1250. if p.tok.indent >= 0: return
  1251. var
  1252. openingParams = p.emptyNode
  1253. openingPragmas = p.emptyNode
  1254. if p.tok.tokType == tkDo:
  1255. getTok(p)
  1256. openingParams = parseParamList(p, retColon=false)
  1257. openingPragmas = optPragmas(p)
  1258. if p.tok.tokType == tkColon:
  1259. result = makeCall(result)
  1260. getTok(p)
  1261. skipComment(p, result)
  1262. if p.tok.tokType notin {tkOf, tkElif, tkElse, tkExcept}:
  1263. var stmtList = newNodeP(nkStmtList, p)
  1264. stmtList.add parseStmt(p)
  1265. # to keep backwards compatibility (see tests/vm/tstringnil)
  1266. if stmtList[0].kind == nkStmtList: stmtList = stmtList[0]
  1267. stmtList.flags.incl nfBlockArg
  1268. if openingParams.kind != nkEmpty:
  1269. result.add newProcNode(nkDo, stmtList.info, body = stmtList,
  1270. params = openingParams,
  1271. name = p.emptyNode, pattern = p.emptyNode,
  1272. genericParams = p.emptyNode,
  1273. pragmas = openingPragmas,
  1274. exceptions = p.emptyNode)
  1275. else:
  1276. result.add stmtList
  1277. while sameInd(p):
  1278. var nextBlock: PNode
  1279. let nextToken = p.tok.tokType
  1280. if nextToken == tkDo:
  1281. let info = parLineInfo(p)
  1282. getTok(p)
  1283. nextBlock = parseDoBlock(p, info)
  1284. else:
  1285. case nextToken:
  1286. of tkOf:
  1287. nextBlock = newNodeP(nkOfBranch, p)
  1288. exprList(p, tkColon, nextBlock)
  1289. of tkElif:
  1290. nextBlock = newNodeP(nkElifBranch, p)
  1291. getTok(p)
  1292. optInd(p, nextBlock)
  1293. nextBlock.addSon parseExpr(p)
  1294. of tkExcept:
  1295. nextBlock = newNodeP(nkExceptBranch, p)
  1296. exprList(p, tkColon, nextBlock)
  1297. of tkElse:
  1298. nextBlock = newNodeP(nkElse, p)
  1299. getTok(p)
  1300. else: break
  1301. eat(p, tkColon)
  1302. nextBlock.addSon parseStmt(p)
  1303. nextBlock.flags.incl nfBlockArg
  1304. result.add nextBlock
  1305. if nextBlock.kind == nkElse: break
  1306. else:
  1307. if openingParams.kind != nkEmpty:
  1308. parMessage(p, "expected ':'")
  1309. proc parseExprStmt(p: var TParser): PNode =
  1310. #| exprStmt = simpleExpr
  1311. #| (( '=' optInd expr colonBody? )
  1312. #| / ( expr ^+ comma
  1313. #| doBlocks
  1314. #| / macroColon
  1315. #| ))?
  1316. var a = simpleExpr(p)
  1317. if p.tok.tokType == tkEquals:
  1318. result = newNodeP(nkAsgn, p)
  1319. getTok(p)
  1320. optInd(p, result)
  1321. var b = parseExpr(p)
  1322. b = postExprBlocks(p, b)
  1323. addSon(result, a)
  1324. addSon(result, b)
  1325. else:
  1326. # simpleExpr parsed 'p a' from 'p a, b'?
  1327. var isFirstParam = false
  1328. if p.tok.indent < 0 and p.tok.tokType == tkComma and a.kind == nkCommand:
  1329. result = a
  1330. while true:
  1331. getTok(p)
  1332. optInd(p, result)
  1333. addSon(result, commandParam(p, isFirstParam, pmNormal))
  1334. if p.tok.tokType != tkComma: break
  1335. elif p.tok.indent < 0 and isExprStart(p):
  1336. result = newNode(nkCommand, a.info, @[a])
  1337. while true:
  1338. addSon(result, commandParam(p, isFirstParam, pmNormal))
  1339. if p.tok.tokType != tkComma: break
  1340. getTok(p)
  1341. optInd(p, result)
  1342. else:
  1343. result = a
  1344. result = postExprBlocks(p, result)
  1345. proc parseModuleName(p: var TParser, kind: TNodeKind): PNode =
  1346. result = parseExpr(p)
  1347. when false:
  1348. # parseExpr already handles 'as' syntax ...
  1349. if p.tok.tokType == tkAs and kind == nkImportStmt:
  1350. let a = result
  1351. result = newNodeP(nkImportAs, p)
  1352. getTok(p)
  1353. result.add(a)
  1354. result.add(parseExpr(p))
  1355. proc parseImport(p: var TParser, kind: TNodeKind): PNode =
  1356. #| importStmt = 'import' optInd expr
  1357. #| ((comma expr)*
  1358. #| / 'except' optInd (expr ^+ comma))
  1359. result = newNodeP(kind, p)
  1360. getTok(p) # skip `import` or `export`
  1361. optInd(p, result)
  1362. var a = parseModuleName(p, kind)
  1363. addSon(result, a)
  1364. if p.tok.tokType in {tkComma, tkExcept}:
  1365. if p.tok.tokType == tkExcept:
  1366. result.kind = succ(kind)
  1367. getTok(p)
  1368. optInd(p, result)
  1369. while true:
  1370. # was: while p.tok.tokType notin {tkEof, tkSad, tkDed}:
  1371. p.hasProgress = false
  1372. a = parseModuleName(p, kind)
  1373. if a.kind == nkEmpty or not p.hasProgress: break
  1374. addSon(result, a)
  1375. if p.tok.tokType != tkComma: break
  1376. getTok(p)
  1377. optInd(p, a)
  1378. #expectNl(p)
  1379. proc parseIncludeStmt(p: var TParser): PNode =
  1380. #| includeStmt = 'include' optInd expr ^+ comma
  1381. result = newNodeP(nkIncludeStmt, p)
  1382. getTok(p) # skip `import` or `include`
  1383. optInd(p, result)
  1384. while true:
  1385. # was: while p.tok.tokType notin {tkEof, tkSad, tkDed}:
  1386. p.hasProgress = false
  1387. var a = parseExpr(p)
  1388. if a.kind == nkEmpty or not p.hasProgress: break
  1389. addSon(result, a)
  1390. if p.tok.tokType != tkComma: break
  1391. getTok(p)
  1392. optInd(p, a)
  1393. #expectNl(p)
  1394. proc parseFromStmt(p: var TParser): PNode =
  1395. #| fromStmt = 'from' moduleName 'import' optInd expr (comma expr)*
  1396. result = newNodeP(nkFromStmt, p)
  1397. getTok(p) # skip `from`
  1398. optInd(p, result)
  1399. var a = parseModuleName(p, nkImportStmt)
  1400. addSon(result, a) #optInd(p, a);
  1401. eat(p, tkImport)
  1402. optInd(p, result)
  1403. while true:
  1404. # p.tok.tokType notin {tkEof, tkSad, tkDed}:
  1405. p.hasProgress = false
  1406. a = parseExpr(p)
  1407. if a.kind == nkEmpty or not p.hasProgress: break
  1408. addSon(result, a)
  1409. if p.tok.tokType != tkComma: break
  1410. getTok(p)
  1411. optInd(p, a)
  1412. #expectNl(p)
  1413. proc parseReturnOrRaise(p: var TParser, kind: TNodeKind): PNode =
  1414. #| returnStmt = 'return' optInd expr?
  1415. #| raiseStmt = 'raise' optInd expr?
  1416. #| yieldStmt = 'yield' optInd expr?
  1417. #| discardStmt = 'discard' optInd expr?
  1418. #| breakStmt = 'break' optInd expr?
  1419. #| continueStmt = 'break' optInd expr?
  1420. result = newNodeP(kind, p)
  1421. getTok(p)
  1422. if p.tok.tokType == tkComment:
  1423. skipComment(p, result)
  1424. addSon(result, p.emptyNode)
  1425. elif p.tok.indent >= 0 and p.tok.indent <= p.currInd or not isExprStart(p):
  1426. # NL terminates:
  1427. addSon(result, p.emptyNode)
  1428. # nimpretty here!
  1429. else:
  1430. var e = parseExpr(p)
  1431. e = postExprBlocks(p, e)
  1432. addSon(result, e)
  1433. proc parseIfOrWhen(p: var TParser, kind: TNodeKind): PNode =
  1434. #| condStmt = expr colcom stmt COMMENT?
  1435. #| (IND{=} 'elif' expr colcom stmt)*
  1436. #| (IND{=} 'else' colcom stmt)?
  1437. #| ifStmt = 'if' condStmt
  1438. #| whenStmt = 'when' condStmt
  1439. result = newNodeP(kind, p)
  1440. while true:
  1441. getTok(p) # skip `if`, `when`, `elif`
  1442. var branch = newNodeP(nkElifBranch, p)
  1443. optInd(p, branch)
  1444. addSon(branch, parseExpr(p))
  1445. colcom(p, branch)
  1446. addSon(branch, parseStmt(p))
  1447. skipComment(p, branch)
  1448. addSon(result, branch)
  1449. if p.tok.tokType != tkElif or not sameOrNoInd(p): break
  1450. if p.tok.tokType == tkElse and sameOrNoInd(p):
  1451. var branch = newNodeP(nkElse, p)
  1452. eat(p, tkElse)
  1453. colcom(p, branch)
  1454. addSon(branch, parseStmt(p))
  1455. addSon(result, branch)
  1456. proc parseWhile(p: var TParser): PNode =
  1457. #| whileStmt = 'while' expr colcom stmt
  1458. result = newNodeP(nkWhileStmt, p)
  1459. getTok(p)
  1460. optInd(p, result)
  1461. addSon(result, parseExpr(p))
  1462. colcom(p, result)
  1463. addSon(result, parseStmt(p))
  1464. proc parseCase(p: var TParser): PNode =
  1465. #| ofBranch = 'of' exprList colcom stmt
  1466. #| ofBranches = ofBranch (IND{=} ofBranch)*
  1467. #| (IND{=} 'elif' expr colcom stmt)*
  1468. #| (IND{=} 'else' colcom stmt)?
  1469. #| caseStmt = 'case' expr ':'? COMMENT?
  1470. #| (IND{>} ofBranches DED
  1471. #| | IND{=} ofBranches)
  1472. var
  1473. b: PNode
  1474. inElif = false
  1475. wasIndented = false
  1476. result = newNodeP(nkCaseStmt, p)
  1477. getTok(p)
  1478. addSon(result, parseExpr(p))
  1479. if p.tok.tokType == tkColon: getTok(p)
  1480. skipComment(p, result)
  1481. let oldInd = p.currInd
  1482. if realInd(p):
  1483. p.currInd = p.tok.indent
  1484. wasIndented = true
  1485. while sameInd(p):
  1486. case p.tok.tokType
  1487. of tkOf:
  1488. if inElif: break
  1489. b = newNodeP(nkOfBranch, p)
  1490. exprList(p, tkColon, b)
  1491. of tkElif:
  1492. inElif = true
  1493. b = newNodeP(nkElifBranch, p)
  1494. getTok(p)
  1495. optInd(p, b)
  1496. addSon(b, parseExpr(p))
  1497. of tkElse:
  1498. b = newNodeP(nkElse, p)
  1499. getTok(p)
  1500. else: break
  1501. colcom(p, b)
  1502. addSon(b, parseStmt(p))
  1503. addSon(result, b)
  1504. if b.kind == nkElse: break
  1505. if wasIndented:
  1506. p.currInd = oldInd
  1507. proc parseTry(p: var TParser; isExpr: bool): PNode =
  1508. #| tryStmt = 'try' colcom stmt &(IND{=}? 'except'|'finally')
  1509. #| (IND{=}? 'except' exprList colcom stmt)*
  1510. #| (IND{=}? 'finally' colcom stmt)?
  1511. #| tryExpr = 'try' colcom stmt &(optInd 'except'|'finally')
  1512. #| (optInd 'except' exprList colcom stmt)*
  1513. #| (optInd 'finally' colcom stmt)?
  1514. result = newNodeP(nkTryStmt, p)
  1515. getTok(p)
  1516. colcom(p, result)
  1517. addSon(result, parseStmt(p))
  1518. var b: PNode = nil
  1519. while sameOrNoInd(p) or isExpr:
  1520. case p.tok.tokType
  1521. of tkExcept:
  1522. b = newNodeP(nkExceptBranch, p)
  1523. exprList(p, tkColon, b)
  1524. of tkFinally:
  1525. b = newNodeP(nkFinally, p)
  1526. getTok(p)
  1527. else: break
  1528. colcom(p, b)
  1529. addSon(b, parseStmt(p))
  1530. addSon(result, b)
  1531. if b == nil: parMessage(p, "expected 'except'")
  1532. proc parseExceptBlock(p: var TParser, kind: TNodeKind): PNode =
  1533. #| exceptBlock = 'except' colcom stmt
  1534. result = newNodeP(kind, p)
  1535. getTok(p)
  1536. colcom(p, result)
  1537. addSon(result, parseStmt(p))
  1538. proc parseBlock(p: var TParser): PNode =
  1539. #| blockStmt = 'block' symbol? colcom stmt
  1540. #| blockExpr = 'block' symbol? colcom stmt
  1541. result = newNodeP(nkBlockStmt, p)
  1542. getTokNoInd(p)
  1543. if p.tok.tokType == tkColon: addSon(result, p.emptyNode)
  1544. else: addSon(result, parseSymbol(p))
  1545. colcom(p, result)
  1546. addSon(result, parseStmt(p))
  1547. proc parseStaticOrDefer(p: var TParser; k: TNodeKind): PNode =
  1548. #| staticStmt = 'static' colcom stmt
  1549. #| deferStmt = 'defer' colcom stmt
  1550. result = newNodeP(k, p)
  1551. getTok(p)
  1552. colcom(p, result)
  1553. addSon(result, parseStmt(p))
  1554. proc parseAsm(p: var TParser): PNode =
  1555. #| asmStmt = 'asm' pragma? (STR_LIT | RSTR_LIT | TRIPLESTR_LIT)
  1556. result = newNodeP(nkAsmStmt, p)
  1557. getTokNoInd(p)
  1558. if p.tok.tokType == tkCurlyDotLe: addSon(result, parsePragma(p))
  1559. else: addSon(result, p.emptyNode)
  1560. case p.tok.tokType
  1561. of tkStrLit: addSon(result, newStrNodeP(nkStrLit, p.tok.literal, p))
  1562. of tkRStrLit: addSon(result, newStrNodeP(nkRStrLit, p.tok.literal, p))
  1563. of tkTripleStrLit: addSon(result,
  1564. newStrNodeP(nkTripleStrLit, p.tok.literal, p))
  1565. else:
  1566. parMessage(p, "the 'asm' statement takes a string literal")
  1567. addSon(result, p.emptyNode)
  1568. return
  1569. getTok(p)
  1570. proc parseGenericParam(p: var TParser): PNode =
  1571. #| genericParam = symbol (comma symbol)* (colon expr)? ('=' optInd expr)?
  1572. var a: PNode
  1573. result = newNodeP(nkIdentDefs, p)
  1574. # progress guaranteed
  1575. while true:
  1576. case p.tok.tokType
  1577. of tkIn, tkOut:
  1578. let x = p.lex.cache.getIdent(if p.tok.tokType == tkIn: "in" else: "out")
  1579. a = newNodeP(nkPrefix, p)
  1580. a.addSon newIdentNodeP(x, p)
  1581. getTok(p)
  1582. expectIdent(p)
  1583. a.addSon(parseSymbol(p))
  1584. of tkSymbol, tkAccent:
  1585. a = parseSymbol(p)
  1586. if a.kind == nkEmpty: return
  1587. else: break
  1588. addSon(result, a)
  1589. if p.tok.tokType != tkComma: break
  1590. getTok(p)
  1591. optInd(p, a)
  1592. if p.tok.tokType == tkColon:
  1593. getTok(p)
  1594. optInd(p, result)
  1595. addSon(result, parseExpr(p))
  1596. else:
  1597. addSon(result, p.emptyNode)
  1598. if p.tok.tokType == tkEquals:
  1599. getTok(p)
  1600. optInd(p, result)
  1601. addSon(result, parseExpr(p))
  1602. else:
  1603. addSon(result, p.emptyNode)
  1604. proc parseGenericParamList(p: var TParser): PNode =
  1605. #| genericParamList = '[' optInd
  1606. #| genericParam ^* (comma/semicolon) optPar ']'
  1607. result = newNodeP(nkGenericParams, p)
  1608. getTok(p)
  1609. optInd(p, result)
  1610. # progress guaranteed
  1611. while p.tok.tokType in {tkSymbol, tkAccent, tkIn, tkOut}:
  1612. var a = parseGenericParam(p)
  1613. addSon(result, a)
  1614. if p.tok.tokType notin {tkComma, tkSemiColon}: break
  1615. when defined(nimpretty):
  1616. commaWasSemicolon(p.em)
  1617. getTok(p)
  1618. skipComment(p, a)
  1619. optPar(p)
  1620. eat(p, tkBracketRi)
  1621. proc parsePattern(p: var TParser): PNode =
  1622. #| pattern = '{' stmt '}'
  1623. eat(p, tkCurlyLe)
  1624. result = parseStmt(p)
  1625. eat(p, tkCurlyRi)
  1626. proc parseRoutine(p: var TParser, kind: TNodeKind): PNode =
  1627. #| indAndComment = (IND{>} COMMENT)? | COMMENT?
  1628. #| routine = optInd identVis pattern? genericParamList?
  1629. #| paramListColon pragma? ('=' COMMENT? stmt)? indAndComment
  1630. result = newNodeP(kind, p)
  1631. getTok(p)
  1632. optInd(p, result)
  1633. addSon(result, identVis(p))
  1634. if p.tok.tokType == tkCurlyLe and p.validInd: addSon(result, p.parsePattern)
  1635. else: addSon(result, p.emptyNode)
  1636. if p.tok.tokType == tkBracketLe and p.validInd:
  1637. result.add(p.parseGenericParamList)
  1638. else:
  1639. addSon(result, p.emptyNode)
  1640. addSon(result, p.parseParamList)
  1641. if p.tok.tokType == tkCurlyDotLe and p.validInd: addSon(result, p.parsePragma)
  1642. else: addSon(result, p.emptyNode)
  1643. # empty exception tracking:
  1644. addSon(result, p.emptyNode)
  1645. if p.tok.tokType == tkEquals and p.validInd:
  1646. getTok(p)
  1647. skipComment(p, result)
  1648. addSon(result, parseStmt(p))
  1649. else:
  1650. addSon(result, p.emptyNode)
  1651. indAndComment(p, result)
  1652. proc newCommentStmt(p: var TParser): PNode =
  1653. #| commentStmt = COMMENT
  1654. result = newNodeP(nkCommentStmt, p)
  1655. result.comment = p.tok.literal
  1656. getTok(p)
  1657. type
  1658. TDefParser = proc (p: var TParser): PNode {.nimcall.}
  1659. proc parseSection(p: var TParser, kind: TNodeKind,
  1660. defparser: TDefParser): PNode =
  1661. #| section(p) = COMMENT? p / (IND{>} (p / COMMENT)^+IND{=} DED)
  1662. result = newNodeP(kind, p)
  1663. if kind != nkTypeSection: getTok(p)
  1664. skipComment(p, result)
  1665. if realInd(p):
  1666. withInd(p):
  1667. skipComment(p, result)
  1668. # progress guaranteed
  1669. while sameInd(p):
  1670. case p.tok.tokType
  1671. of tkSymbol, tkAccent, tkParLe:
  1672. var a = defparser(p)
  1673. skipComment(p, a)
  1674. addSon(result, a)
  1675. of tkComment:
  1676. var a = newCommentStmt(p)
  1677. addSon(result, a)
  1678. else:
  1679. parMessage(p, errIdentifierExpected, p.tok)
  1680. break
  1681. if result.len == 0: parMessage(p, errIdentifierExpected, p.tok)
  1682. elif p.tok.tokType in {tkSymbol, tkAccent, tkParLe} and p.tok.indent < 0:
  1683. # tkParLe is allowed for ``var (x, y) = ...`` tuple parsing
  1684. addSon(result, defparser(p))
  1685. else:
  1686. parMessage(p, errIdentifierExpected, p.tok)
  1687. proc parseEnum(p: var TParser): PNode =
  1688. #| enum = 'enum' optInd (symbol optPragmas optInd ('=' optInd expr COMMENT?)? comma?)+
  1689. result = newNodeP(nkEnumTy, p)
  1690. getTok(p)
  1691. addSon(result, p.emptyNode)
  1692. optInd(p, result)
  1693. flexComment(p, result)
  1694. # progress guaranteed
  1695. while true:
  1696. var a = parseSymbol(p)
  1697. if a.kind == nkEmpty: return
  1698. var symPragma = a
  1699. var pragma: PNode
  1700. if p.tok.tokType == tkCurlyDotLe:
  1701. pragma = optPragmas(p)
  1702. symPragma = newNodeP(nkPragmaExpr, p)
  1703. addSon(symPragma, a)
  1704. addSon(symPragma, pragma)
  1705. # nimpretty support here
  1706. if p.tok.indent >= 0 and p.tok.indent <= p.currInd:
  1707. add(result, symPragma)
  1708. break
  1709. if p.tok.tokType == tkEquals and p.tok.indent < 0:
  1710. getTok(p)
  1711. optInd(p, symPragma)
  1712. var b = symPragma
  1713. symPragma = newNodeP(nkEnumFieldDef, p)
  1714. addSon(symPragma, b)
  1715. addSon(symPragma, parseExpr(p))
  1716. if p.tok.indent < 0 or p.tok.indent >= p.currInd:
  1717. rawSkipComment(p, symPragma)
  1718. if p.tok.tokType == tkComma and p.tok.indent < 0:
  1719. getTok(p)
  1720. rawSkipComment(p, symPragma)
  1721. else:
  1722. if p.tok.indent < 0 or p.tok.indent >= p.currInd:
  1723. rawSkipComment(p, symPragma)
  1724. addSon(result, symPragma)
  1725. if p.tok.indent >= 0 and p.tok.indent <= p.currInd or
  1726. p.tok.tokType == tkEof:
  1727. break
  1728. if result.len <= 1:
  1729. parMessage(p, errIdentifierExpected, p.tok)
  1730. proc parseObjectPart(p: var TParser): PNode
  1731. proc parseObjectWhen(p: var TParser): PNode =
  1732. #| objectWhen = 'when' expr colcom objectPart COMMENT?
  1733. #| ('elif' expr colcom objectPart COMMENT?)*
  1734. #| ('else' colcom objectPart COMMENT?)?
  1735. result = newNodeP(nkRecWhen, p)
  1736. # progress guaranteed
  1737. while sameInd(p):
  1738. getTok(p) # skip `when`, `elif`
  1739. var branch = newNodeP(nkElifBranch, p)
  1740. optInd(p, branch)
  1741. addSon(branch, parseExpr(p))
  1742. colcom(p, branch)
  1743. addSon(branch, parseObjectPart(p))
  1744. flexComment(p, branch)
  1745. addSon(result, branch)
  1746. if p.tok.tokType != tkElif: break
  1747. if p.tok.tokType == tkElse and sameInd(p):
  1748. var branch = newNodeP(nkElse, p)
  1749. eat(p, tkElse)
  1750. colcom(p, branch)
  1751. addSon(branch, parseObjectPart(p))
  1752. flexComment(p, branch)
  1753. addSon(result, branch)
  1754. proc parseObjectCase(p: var TParser): PNode =
  1755. #| objectBranch = 'of' exprList colcom objectPart
  1756. #| objectBranches = objectBranch (IND{=} objectBranch)*
  1757. #| (IND{=} 'elif' expr colcom objectPart)*
  1758. #| (IND{=} 'else' colcom objectPart)?
  1759. #| objectCase = 'case' identWithPragma ':' typeDesc ':'? COMMENT?
  1760. #| (IND{>} objectBranches DED
  1761. #| | IND{=} objectBranches)
  1762. result = newNodeP(nkRecCase, p)
  1763. getTokNoInd(p)
  1764. var a = newNodeP(nkIdentDefs, p)
  1765. addSon(a, identWithPragma(p))
  1766. eat(p, tkColon)
  1767. addSon(a, parseTypeDesc(p))
  1768. addSon(a, p.emptyNode)
  1769. addSon(result, a)
  1770. if p.tok.tokType == tkColon: getTok(p)
  1771. flexComment(p, result)
  1772. var wasIndented = false
  1773. let oldInd = p.currInd
  1774. if realInd(p):
  1775. p.currInd = p.tok.indent
  1776. wasIndented = true
  1777. # progress guaranteed
  1778. while sameInd(p):
  1779. var b: PNode
  1780. case p.tok.tokType
  1781. of tkOf:
  1782. b = newNodeP(nkOfBranch, p)
  1783. exprList(p, tkColon, b)
  1784. of tkElse:
  1785. b = newNodeP(nkElse, p)
  1786. getTok(p)
  1787. else: break
  1788. colcom(p, b)
  1789. var fields = parseObjectPart(p)
  1790. if fields.kind == nkEmpty:
  1791. parMessage(p, errIdentifierExpected, p.tok)
  1792. fields = newNodeP(nkNilLit, p) # don't break further semantic checking
  1793. addSon(b, fields)
  1794. addSon(result, b)
  1795. if b.kind == nkElse: break
  1796. if wasIndented:
  1797. p.currInd = oldInd
  1798. proc parseObjectPart(p: var TParser): PNode =
  1799. #| objectPart = IND{>} objectPart^+IND{=} DED
  1800. #| / objectWhen / objectCase / 'nil' / 'discard' / declColonEquals
  1801. if realInd(p):
  1802. result = newNodeP(nkRecList, p)
  1803. withInd(p):
  1804. rawSkipComment(p, result)
  1805. while sameInd(p):
  1806. case p.tok.tokType
  1807. of tkCase, tkWhen, tkSymbol, tkAccent, tkNil, tkDiscard:
  1808. addSon(result, parseObjectPart(p))
  1809. else:
  1810. parMessage(p, errIdentifierExpected, p.tok)
  1811. break
  1812. else:
  1813. case p.tok.tokType
  1814. of tkWhen:
  1815. result = parseObjectWhen(p)
  1816. of tkCase:
  1817. result = parseObjectCase(p)
  1818. of tkSymbol, tkAccent:
  1819. result = parseIdentColonEquals(p, {withPragma})
  1820. if p.tok.indent < 0 or p.tok.indent >= p.currInd:
  1821. rawSkipComment(p, result)
  1822. of tkNil, tkDiscard:
  1823. result = newNodeP(nkNilLit, p)
  1824. getTok(p)
  1825. else:
  1826. result = p.emptyNode
  1827. proc parseObject(p: var TParser): PNode =
  1828. #| object = 'object' pragma? ('of' typeDesc)? COMMENT? objectPart
  1829. result = newNodeP(nkObjectTy, p)
  1830. getTok(p)
  1831. if p.tok.tokType == tkCurlyDotLe and p.validInd:
  1832. # Deprecated since v0.20.0
  1833. parMessage(p, warnDeprecated, "type pragmas follow the type name; this form of writing pragmas is deprecated")
  1834. addSon(result, parsePragma(p))
  1835. else:
  1836. addSon(result, p.emptyNode)
  1837. if p.tok.tokType == tkOf and p.tok.indent < 0:
  1838. var a = newNodeP(nkOfInherit, p)
  1839. getTok(p)
  1840. addSon(a, parseTypeDesc(p))
  1841. addSon(result, a)
  1842. else:
  1843. addSon(result, p.emptyNode)
  1844. if p.tok.tokType == tkComment:
  1845. skipComment(p, result)
  1846. # an initial IND{>} HAS to follow:
  1847. if not realInd(p):
  1848. addSon(result, p.emptyNode)
  1849. return
  1850. addSon(result, parseObjectPart(p))
  1851. proc parseTypeClassParam(p: var TParser): PNode =
  1852. let modifier = case p.tok.tokType
  1853. of tkOut, tkVar: nkVarTy
  1854. of tkPtr: nkPtrTy
  1855. of tkRef: nkRefTy
  1856. of tkStatic: nkStaticTy
  1857. of tkType: nkTypeOfExpr
  1858. else: nkEmpty
  1859. if modifier != nkEmpty:
  1860. result = newNodeP(modifier, p)
  1861. getTok(p)
  1862. result.addSon(p.parseSymbol)
  1863. else:
  1864. result = p.parseSymbol
  1865. proc parseTypeClass(p: var TParser): PNode =
  1866. #| typeClassParam = ('var' | 'out')? symbol
  1867. #| typeClass = typeClassParam ^* ',' (pragma)? ('of' typeDesc ^* ',')?
  1868. #| &IND{>} stmt
  1869. result = newNodeP(nkTypeClassTy, p)
  1870. getTok(p)
  1871. var args = newNodeP(nkArgList, p)
  1872. addSon(result, args)
  1873. addSon(args, p.parseTypeClassParam)
  1874. while p.tok.tokType == tkComma:
  1875. getTok(p)
  1876. addSon(args, p.parseTypeClassParam)
  1877. if p.tok.tokType == tkCurlyDotLe and p.validInd:
  1878. addSon(result, parsePragma(p))
  1879. else:
  1880. addSon(result, p.emptyNode)
  1881. if p.tok.tokType == tkOf and p.tok.indent < 0:
  1882. var a = newNodeP(nkOfInherit, p)
  1883. getTok(p)
  1884. # progress guaranteed
  1885. while true:
  1886. addSon(a, parseTypeDesc(p))
  1887. if p.tok.tokType != tkComma: break
  1888. getTok(p)
  1889. addSon(result, a)
  1890. else:
  1891. addSon(result, p.emptyNode)
  1892. if p.tok.tokType == tkComment:
  1893. skipComment(p, result)
  1894. # an initial IND{>} HAS to follow:
  1895. if not realInd(p):
  1896. addSon(result, p.emptyNode)
  1897. else:
  1898. addSon(result, parseStmt(p))
  1899. proc parseTypeDef(p: var TParser): PNode =
  1900. #|
  1901. #| typeDef = identWithPragmaDot genericParamList? '=' optInd typeDefAux
  1902. #| indAndComment? / identVisDot genericParamList? pragma '=' optInd typeDefAux
  1903. #| indAndComment?
  1904. result = newNodeP(nkTypeDef, p)
  1905. var identifier = identVis(p, allowDot=true)
  1906. var identPragma = identifier
  1907. var pragma: PNode
  1908. var genericParam: PNode
  1909. var noPragmaYet = true
  1910. if p.tok.tokType == tkCurlyDotLe:
  1911. pragma = optPragmas(p)
  1912. identPragma = newNodeP(nkPragmaExpr, p)
  1913. addSon(identPragma, identifier)
  1914. addSon(identPragma, pragma)
  1915. noPragmaYet = false
  1916. if p.tok.tokType == tkBracketLe and p.validInd:
  1917. if not noPragmaYet:
  1918. # Deprecated since v0.20.0
  1919. parMessage(p, warnDeprecated, "pragma before generic parameter list is deprecated")
  1920. genericParam = parseGenericParamList(p)
  1921. else:
  1922. genericParam = p.emptyNode
  1923. if noPragmaYet:
  1924. pragma = optPragmas(p)
  1925. if pragma.kind != nkEmpty:
  1926. identPragma = newNodeP(nkPragmaExpr, p)
  1927. addSon(identPragma, identifier)
  1928. addSon(identPragma, pragma)
  1929. elif p.tok.tokType == tkCurlyDotLe:
  1930. parMessage(p, errGenerated, "pragma already present")
  1931. addSon(result, identPragma)
  1932. addSon(result, genericParam)
  1933. if p.tok.tokType == tkEquals:
  1934. result.info = parLineInfo(p)
  1935. getTok(p)
  1936. optInd(p, result)
  1937. addSon(result, parseTypeDefAux(p))
  1938. else:
  1939. addSon(result, p.emptyNode)
  1940. indAndComment(p, result) # special extension!
  1941. proc parseVarTuple(p: var TParser): PNode =
  1942. #| varTuple = '(' optInd identWithPragma ^+ comma optPar ')' '=' optInd expr
  1943. result = newNodeP(nkVarTuple, p)
  1944. getTok(p) # skip '('
  1945. optInd(p, result)
  1946. # progress guaranteed
  1947. while p.tok.tokType in {tkSymbol, tkAccent}:
  1948. var a = identWithPragma(p, allowDot=true)
  1949. addSon(result, a)
  1950. if p.tok.tokType != tkComma: break
  1951. getTok(p)
  1952. skipComment(p, a)
  1953. addSon(result, p.emptyNode) # no type desc
  1954. optPar(p)
  1955. eat(p, tkParRi)
  1956. proc parseVariable(p: var TParser): PNode =
  1957. #| colonBody = colcom stmt doBlocks?
  1958. #| variable = (varTuple / identColonEquals) colonBody? indAndComment
  1959. if p.tok.tokType == tkParLe:
  1960. result = parseVarTuple(p)
  1961. eat(p, tkEquals)
  1962. optInd(p, result)
  1963. addSon(result, parseExpr(p))
  1964. else: result = parseIdentColonEquals(p, {withPragma, withDot})
  1965. result[^1] = postExprBlocks(p, result[^1])
  1966. indAndComment(p, result)
  1967. proc parseConstant(p: var TParser): PNode =
  1968. #| constant = (parseVarTuple / identWithPragma) (colon typeDesc)? '=' optInd expr indAndComment
  1969. if p.tok.tokType == tkParLe: result = parseVarTuple(p)
  1970. else:
  1971. result = newNodeP(nkConstDef, p)
  1972. addSon(result, identWithPragma(p))
  1973. if p.tok.tokType == tkColon:
  1974. getTok(p)
  1975. optInd(p, result)
  1976. addSon(result, parseTypeDesc(p))
  1977. else:
  1978. addSon(result, p.emptyNode)
  1979. eat(p, tkEquals)
  1980. optInd(p, result)
  1981. #addSon(result, parseStmtListExpr(p))
  1982. addSon(result, parseExpr(p))
  1983. result[^1] = postExprBlocks(p, result[^1])
  1984. indAndComment(p, result)
  1985. proc parseBind(p: var TParser, k: TNodeKind): PNode =
  1986. #| bindStmt = 'bind' optInd qualifiedIdent ^+ comma
  1987. #| mixinStmt = 'mixin' optInd qualifiedIdent ^+ comma
  1988. result = newNodeP(k, p)
  1989. getTok(p)
  1990. optInd(p, result)
  1991. # progress guaranteed
  1992. while true:
  1993. var a = qualifiedIdent(p)
  1994. addSon(result, a)
  1995. if p.tok.tokType != tkComma: break
  1996. getTok(p)
  1997. optInd(p, a)
  1998. #expectNl(p)
  1999. proc parseStmtPragma(p: var TParser): PNode =
  2000. #| pragmaStmt = pragma (':' COMMENT? stmt)?
  2001. result = parsePragma(p)
  2002. if p.tok.tokType == tkColon and p.tok.indent < 0:
  2003. let a = result
  2004. result = newNodeI(nkPragmaBlock, a.info)
  2005. getTok(p)
  2006. skipComment(p, result)
  2007. result.add a
  2008. result.add parseStmt(p)
  2009. proc simpleStmt(p: var TParser): PNode =
  2010. #| simpleStmt = ((returnStmt | raiseStmt | yieldStmt | discardStmt | breakStmt
  2011. #| | continueStmt | pragmaStmt | importStmt | exportStmt | fromStmt
  2012. #| | includeStmt | commentStmt) / exprStmt) COMMENT?
  2013. #|
  2014. case p.tok.tokType
  2015. of tkReturn: result = parseReturnOrRaise(p, nkReturnStmt)
  2016. of tkRaise: result = parseReturnOrRaise(p, nkRaiseStmt)
  2017. of tkYield: result = parseReturnOrRaise(p, nkYieldStmt)
  2018. of tkDiscard: result = parseReturnOrRaise(p, nkDiscardStmt)
  2019. of tkBreak: result = parseReturnOrRaise(p, nkBreakStmt)
  2020. of tkContinue: result = parseReturnOrRaise(p, nkContinueStmt)
  2021. of tkCurlyDotLe: result = parseStmtPragma(p)
  2022. of tkImport: result = parseImport(p, nkImportStmt)
  2023. of tkExport: result = parseImport(p, nkExportStmt)
  2024. of tkFrom: result = parseFromStmt(p)
  2025. of tkInclude: result = parseIncludeStmt(p)
  2026. of tkComment: result = newCommentStmt(p)
  2027. else:
  2028. if isExprStart(p): result = parseExprStmt(p)
  2029. else: result = p.emptyNode
  2030. if result.kind notin {nkEmpty, nkCommentStmt}: skipComment(p, result)
  2031. proc complexOrSimpleStmt(p: var TParser): PNode =
  2032. #| complexOrSimpleStmt = (ifStmt | whenStmt | whileStmt
  2033. #| | tryStmt | forStmt
  2034. #| | blockStmt | staticStmt | deferStmt | asmStmt
  2035. #| | 'proc' routine
  2036. #| | 'method' routine
  2037. #| | 'iterator' routine
  2038. #| | 'macro' routine
  2039. #| | 'template' routine
  2040. #| | 'converter' routine
  2041. #| | 'type' section(typeDef)
  2042. #| | 'const' section(constant)
  2043. #| | ('let' | 'var' | 'using') section(variable)
  2044. #| | bindStmt | mixinStmt)
  2045. #| / simpleStmt
  2046. case p.tok.tokType
  2047. of tkIf: result = parseIfOrWhen(p, nkIfStmt)
  2048. of tkWhile: result = parseWhile(p)
  2049. of tkCase: result = parseCase(p)
  2050. of tkTry: result = parseTry(p, isExpr=false)
  2051. of tkFinally: result = parseExceptBlock(p, nkFinally)
  2052. of tkExcept: result = parseExceptBlock(p, nkExceptBranch)
  2053. of tkFor: result = parseFor(p)
  2054. of tkBlock: result = parseBlock(p)
  2055. of tkStatic: result = parseStaticOrDefer(p, nkStaticStmt)
  2056. of tkDefer: result = parseStaticOrDefer(p, nkDefer)
  2057. of tkAsm: result = parseAsm(p)
  2058. of tkProc: result = parseRoutine(p, nkProcDef)
  2059. of tkFunc: result = parseRoutine(p, nkFuncDef)
  2060. of tkMethod: result = parseRoutine(p, nkMethodDef)
  2061. of tkIterator: result = parseRoutine(p, nkIteratorDef)
  2062. of tkMacro: result = parseRoutine(p, nkMacroDef)
  2063. of tkTemplate: result = parseRoutine(p, nkTemplateDef)
  2064. of tkConverter: result = parseRoutine(p, nkConverterDef)
  2065. of tkType:
  2066. getTok(p)
  2067. if p.tok.tokType == tkParLe:
  2068. getTok(p)
  2069. result = newNodeP(nkTypeOfExpr, p)
  2070. result.addSon(primary(p, pmTypeDesc))
  2071. eat(p, tkParRi)
  2072. result = parseOperators(p, result, -1, pmNormal)
  2073. else:
  2074. result = parseSection(p, nkTypeSection, parseTypeDef)
  2075. of tkConst:
  2076. prettySection:
  2077. result = parseSection(p, nkConstSection, parseConstant)
  2078. of tkLet:
  2079. prettySection:
  2080. result = parseSection(p, nkLetSection, parseVariable)
  2081. of tkVar:
  2082. prettySection:
  2083. result = parseSection(p, nkVarSection, parseVariable)
  2084. of tkWhen: result = parseIfOrWhen(p, nkWhenStmt)
  2085. of tkBind: result = parseBind(p, nkBindStmt)
  2086. of tkMixin: result = parseBind(p, nkMixinStmt)
  2087. of tkUsing: result = parseSection(p, nkUsingStmt, parseVariable)
  2088. else: result = simpleStmt(p)
  2089. proc parseStmt(p: var TParser): PNode =
  2090. #| stmt = (IND{>} complexOrSimpleStmt^+(IND{=} / ';') DED)
  2091. #| / simpleStmt ^+ ';'
  2092. if p.tok.indent > p.currInd:
  2093. # nimpretty support here
  2094. result = newNodeP(nkStmtList, p)
  2095. withInd(p):
  2096. while true:
  2097. if p.tok.indent == p.currInd:
  2098. discard
  2099. elif p.tok.tokType == tkSemiColon:
  2100. getTok(p)
  2101. if p.tok.indent < 0 or p.tok.indent == p.currInd: discard
  2102. else: break
  2103. else:
  2104. if p.tok.indent > p.currInd and p.tok.tokType != tkDot:
  2105. parMessage(p, errInvalidIndentation)
  2106. break
  2107. if p.tok.tokType in {tkCurlyRi, tkParRi, tkCurlyDotRi, tkBracketRi}:
  2108. # XXX this ensures tnamedparamanonproc still compiles;
  2109. # deprecate this syntax later
  2110. break
  2111. p.hasProgress = false
  2112. var a = complexOrSimpleStmt(p)
  2113. if a.kind != nkEmpty:
  2114. addSon(result, a)
  2115. else:
  2116. # This is done to make the new 'if' expressions work better.
  2117. # XXX Eventually we need to be more strict here.
  2118. if p.tok.tokType notin {tkElse, tkElif}:
  2119. parMessage(p, errExprExpected, p.tok)
  2120. getTok(p)
  2121. else:
  2122. break
  2123. if not p.hasProgress and p.tok.tokType == tkEof: break
  2124. else:
  2125. # the case statement is only needed for better error messages:
  2126. case p.tok.tokType
  2127. of tkIf, tkWhile, tkCase, tkTry, tkFor, tkBlock, tkAsm, tkProc, tkFunc,
  2128. tkIterator, tkMacro, tkType, tkConst, tkWhen, tkVar:
  2129. parMessage(p, "complex statement requires indentation")
  2130. result = p.emptyNode
  2131. else:
  2132. if p.inSemiStmtList > 0:
  2133. result = simpleStmt(p)
  2134. if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
  2135. else:
  2136. result = newNodeP(nkStmtList, p)
  2137. while true:
  2138. if p.tok.indent >= 0:
  2139. parMessage(p, errInvalidIndentation)
  2140. p.hasProgress = false
  2141. let a = simpleStmt(p)
  2142. let err = not p.hasProgress
  2143. if a.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
  2144. result.add(a)
  2145. if p.tok.tokType != tkSemiColon: break
  2146. getTok(p)
  2147. if err and p.tok.tokType == tkEof: break
  2148. proc parseAll(p: var TParser): PNode =
  2149. ## Parses the rest of the input stream held by the parser into a PNode.
  2150. result = newNodeP(nkStmtList, p)
  2151. while p.tok.tokType != tkEof:
  2152. p.hasProgress = false
  2153. var a = complexOrSimpleStmt(p)
  2154. if a.kind != nkEmpty and p.hasProgress:
  2155. addSon(result, a)
  2156. else:
  2157. parMessage(p, errExprExpected, p.tok)
  2158. # bugfix: consume a token here to prevent an endless loop:
  2159. getTok(p)
  2160. if p.tok.indent != 0:
  2161. parMessage(p, errInvalidIndentation)
  2162. proc parseTopLevelStmt(p: var TParser): PNode =
  2163. ## Implements an iterator which, when called repeatedly, returns the next
  2164. ## top-level statement or emptyNode if end of stream.
  2165. result = p.emptyNode
  2166. # progress guaranteed
  2167. while true:
  2168. # nimpretty support here
  2169. if p.tok.indent != 0:
  2170. if p.firstTok and p.tok.indent < 0: discard
  2171. elif p.tok.tokType != tkSemiColon:
  2172. # special casing for better error messages:
  2173. if p.tok.tokType == tkOpr and p.tok.ident.s == "*":
  2174. parMessage(p, errGenerated,
  2175. "invalid indentation; an export marker '*' follows the declared identifier")
  2176. else:
  2177. parMessage(p, errInvalidIndentation)
  2178. p.firstTok = false
  2179. case p.tok.tokType
  2180. of tkSemiColon:
  2181. getTok(p)
  2182. if p.tok.indent <= 0: discard
  2183. else: parMessage(p, errInvalidIndentation)
  2184. p.firstTok = true
  2185. of tkEof: break
  2186. else:
  2187. result = complexOrSimpleStmt(p)
  2188. if result.kind == nkEmpty: parMessage(p, errExprExpected, p.tok)
  2189. break
  2190. proc parseString*(s: string; cache: IdentCache; config: ConfigRef;
  2191. filename: string = ""; line: int = 0;
  2192. errorHandler: TErrorHandler = nil): PNode =
  2193. ## Parses a string into an AST, returning the top node.
  2194. ## `filename` and `line`, although optional, provide info so that the
  2195. ## compiler can generate correct error messages referring to the original
  2196. ## source.
  2197. var stream = llStreamOpen(s)
  2198. stream.lineOffset = line
  2199. var parser: TParser
  2200. parser.lex.errorHandler = errorHandler
  2201. openParser(parser, AbsoluteFile filename, stream, cache, config)
  2202. result = parser.parseAll
  2203. closeParser(parser)