parser.nim 76 KB

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