parser.nim 76 KB

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