astspec.txt 26 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403
  1. The AST in Nim
  2. ==============
  3. This section describes how the AST is modelled with Nim's type system.
  4. The AST consists of nodes (``NimNode``) with a variable number of
  5. children. Each node has a field named ``kind`` which describes what the node
  6. contains:
  7. .. code-block:: nim
  8. type
  9. NimNodeKind = enum ## kind of a node; only explanatory
  10. nnkNone, ## invalid node kind
  11. nnkEmpty, ## empty node
  12. nnkIdent, ## node contains an identifier
  13. nnkIntLit, ## node contains an int literal (example: 10)
  14. nnkStrLit, ## node contains a string literal (example: "abc")
  15. nnkNilLit, ## node contains a nil literal (example: nil)
  16. nnkCaseStmt, ## node represents a case statement
  17. ... ## many more
  18. NimNode = ref NimNodeObj
  19. NimNodeObj = object
  20. case kind: NimNodeKind ## the node's kind
  21. of nnkNone, nnkEmpty, nnkNilLit:
  22. discard ## node contains no additional fields
  23. of nnkCharLit..nnkUInt64Lit:
  24. intVal: BiggestInt ## the int literal
  25. of nnkFloatLit..nnkFloat64Lit:
  26. floatVal: BiggestFloat ## the float literal
  27. of nnkStrLit..nnkTripleStrLit, nnkCommentStmt, nnkIdent, nnkSym:
  28. strVal: string ## the string literal
  29. else:
  30. sons: seq[NimNode] ## the node's sons (or children)
  31. For the ``NimNode`` type, the ``[]`` operator has been overloaded:
  32. ``n[i]`` is ``n``'s ``i``-th child.
  33. To specify the AST for the different Nim constructs, the notation
  34. ``nodekind(son1, son2, ...)`` or ``nodekind(value)`` or
  35. ``nodekind(field=value)`` is used.
  36. Some child may be missing. A missing child is a node of kind ``nnkEmpty``;
  37. a child can never be nil.
  38. Leaf nodes/Atoms
  39. ================
  40. A leaf of the AST often corresponds to a terminal symbol in the concrete
  41. syntax. Note that the default ``float`` in Nim maps to ``float64`` such that
  42. the default AST for a float is ``nnkFloat64Lit`` as below.
  43. ----------------- ---------------------------------------------
  44. Nim expression Corresponding AST
  45. ----------------- ---------------------------------------------
  46. ``42`` ``nnkIntLit(intVal = 42)``
  47. ``42'i8`` ``nnkInt8Lit(intVal = 42)``
  48. ``42'i16`` ``nnkInt16Lit(intVal = 42)``
  49. ``42'i32`` ``nnkInt32Lit(intVal = 42)``
  50. ``42'i64`` ``nnkInt64Lit(intVal = 42)``
  51. ``42'u8`` ``nnkUInt8Lit(intVal = 42)``
  52. ``42'u16`` ``nnkUInt16Lit(intVal = 42)``
  53. ``42'u32`` ``nnkUInt32Lit(intVal = 42)``
  54. ``42'u64`` ``nnkUInt64Lit(intVal = 42)``
  55. ``42.0`` ``nnkFloat64Lit(floatVal = 42.0)``
  56. ``42.0'f32`` ``nnkFloat32Lit(floatVal = 42.0)``
  57. ``42.0'f64`` ``nnkFloat64Lit(floatVal = 42.0)``
  58. ``"abc"`` ``nnkStrLit(strVal = "abc")``
  59. ``r"abc"`` ``nnkRStrLit(strVal = "abc")``
  60. ``"""abc"""`` ``nnkTripleStrLit(strVal = "abc")``
  61. ``' '`` ``nnkCharLit(intVal = 32)``
  62. ``nil`` ``nnkNilLit()``
  63. ``myIdentifier`` ``nnkIdent(strVal = "myIdentifier")``
  64. ``myIdentifier`` after lookup pass: ``nnkSym(strVal = "myIdentifier", ...)``
  65. ----------------- ---------------------------------------------
  66. Identifiers are ``nnkIdent`` nodes. After the name lookup pass these nodes
  67. get transferred into ``nnkSym`` nodes.
  68. Calls/expressions
  69. =================
  70. Command call
  71. ------------
  72. Concrete syntax:
  73. .. code-block:: nim
  74. echo "abc", "xyz"
  75. AST:
  76. .. code-block:: nim
  77. nnkCommand(
  78. nnkIdent("echo"),
  79. nnkStrLit("abc"),
  80. nnkStrLit("xyz")
  81. )
  82. Call with ``()``
  83. ----------------
  84. Concrete syntax:
  85. .. code-block:: nim
  86. echo("abc", "xyz")
  87. AST:
  88. .. code-block:: nim
  89. nnkCall(
  90. nnkIdent("echo"),
  91. nnkStrLit("abc"),
  92. nnkStrLit("xyz")
  93. )
  94. Infix operator call
  95. -------------------
  96. Concrete syntax:
  97. .. code-block:: nim
  98. "abc" & "xyz"
  99. AST:
  100. .. code-block:: nim
  101. nnkInfix(
  102. nnkIdent("&"),
  103. nnkStrLit("abc"),
  104. nnkStrLit("xyz")
  105. )
  106. Note that with multiple infix operators, the command is parsed by operator
  107. precedence.
  108. Concrete syntax:
  109. .. code-block:: nim
  110. 5 + 3 * 4
  111. AST:
  112. .. code-block:: nim
  113. nnkInfix(
  114. nnkIdent("+"),
  115. nnkIntLit(5),
  116. nnkInfix(
  117. nnkIdent("*"),
  118. nnkIntLit(3),
  119. nnkIntLit(4)
  120. )
  121. )
  122. As a side note, if you choose to use infix operators in a prefix form, the AST
  123. behaves as a
  124. [parenthetical function call](./macros.html#calls-expressions-call-with) with
  125. ``nnkAccQuoted``, as follows:
  126. Concrete syntax:
  127. .. code-block:: nim
  128. `+`(3, 4)
  129. AST:
  130. .. code-block:: nim
  131. nnkCall(
  132. nnkAccQuoted(
  133. nnkIdent("+")
  134. ),
  135. nnkIntLit(3),
  136. nnkIntLit(4)
  137. )
  138. Prefix operator call
  139. --------------------
  140. Concrete syntax:
  141. .. code-block:: nim
  142. ? "xyz"
  143. AST:
  144. .. code-block:: nim
  145. nnkPrefix(
  146. nnkIdent("?"),
  147. nnkStrLit("abc")
  148. )
  149. Postfix operator call
  150. ---------------------
  151. **Note:** There are no postfix operators in Nim. However, the
  152. ``nnkPostfix`` node is used for the *asterisk export marker* ``*``:
  153. Concrete syntax:
  154. .. code-block:: nim
  155. identifier*
  156. AST:
  157. .. code-block:: nim
  158. nnkPostfix(
  159. nnkIdent("*"),
  160. nnkIdent("identifier")
  161. )
  162. Call with named arguments
  163. -------------------------
  164. Concrete syntax:
  165. .. code-block:: nim
  166. writeLine(file=stdout, "hallo")
  167. AST:
  168. .. code-block:: nim
  169. nnkCall(
  170. nnkIdent("writeLine"),
  171. nnkExprEqExpr(
  172. nnkIdent("file"),
  173. nnkIdent("stdout")
  174. ),
  175. nnkStrLit("hallo")
  176. )
  177. Call with raw string literal
  178. ----------------------------
  179. This is used, for example, in the ``bindSym`` examples
  180. [here](http://nim-lang.org/docs/manual.html#macros-bindsym) and with
  181. ``re"some regexp"`` in the regular expression module.
  182. Concrete syntax:
  183. .. code-block:: nim
  184. echo"abc"
  185. AST:
  186. .. code-block:: nim
  187. nnkCallStrLit(
  188. nnkIdent("echo"),
  189. nnkRStrLit("hello")
  190. )
  191. Dereference operator ``[]``
  192. ---------------------------
  193. Concrete syntax:
  194. .. code-block:: nim
  195. x[]
  196. AST:
  197. .. code-block:: nim
  198. nnkDerefExpr(nnkIdent("x"))
  199. Addr operator
  200. -------------
  201. Concrete syntax:
  202. .. code-block:: nim
  203. addr(x)
  204. AST:
  205. .. code-block:: nim
  206. nnkAddr(nnkIdent("x"))
  207. Cast operator
  208. -------------
  209. Concrete syntax:
  210. .. code-block:: nim
  211. cast[T](x)
  212. AST:
  213. .. code-block:: nim
  214. nnkCast(nnkIdent("T"), nnkIdent("x"))
  215. Object access operator ``.``
  216. ----------------------------
  217. Concrete syntax:
  218. .. code-block:: nim
  219. x.y
  220. AST:
  221. .. code-block:: nim
  222. nnkDotExpr(nnkIdent("x"), nnkIdent("y"))
  223. If you use Nim's flexible calling syntax (as in ``x.len()``), the result is the
  224. same as above but wrapped in an ``nnkCall``.
  225. Array access operator ``[]``
  226. ----------------------------
  227. Concrete syntax:
  228. .. code-block:: nim
  229. x[y]
  230. AST:
  231. .. code-block:: nim
  232. nnkBracketExpr(nnkIdent("x"), nnkIdent("y"))
  233. Parentheses
  234. -----------
  235. Parentheses for affecting operator precedence or tuple construction
  236. are built with the ``nnkPar`` node.
  237. Concrete syntax:
  238. .. code-block:: nim
  239. (1, 2, (3))
  240. AST:
  241. .. code-block:: nim
  242. nnkPar(nnkIntLit(1), nnkIntLit(2), nnkPar(nnkIntLit(3)))
  243. Curly braces
  244. ------------
  245. Curly braces are used as the set constructor.
  246. Concrete syntax:
  247. .. code-block:: nim
  248. {1, 2, 3}
  249. AST:
  250. .. code-block:: nim
  251. nnkCurly(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
  252. When used as a table constructor, the syntax is different.
  253. Concrete syntax:
  254. .. code-block:: nim
  255. {a: 3, b: 5}
  256. AST:
  257. .. code-block:: nim
  258. nnkTableConstr(
  259. nnkExprColonExpr(nnkIdent("a"), nnkIntLit(3)),
  260. nnkExprColonExpr(nnkIdent("b"), nnkIntLit(5))
  261. )
  262. Brackets
  263. --------
  264. Brackets are used as the array constructor.
  265. Concrete syntax:
  266. .. code-block:: nim
  267. [1, 2, 3]
  268. AST:
  269. .. code-block:: nim
  270. nnkBracket(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
  271. Ranges
  272. ------
  273. Ranges occur in set constructors, case statement branches, or array slices.
  274. Internally, the node kind ``nnkRange`` is used, but when constructing the
  275. AST, construction with ``..`` as an infix operator should be used instead.
  276. Concrete syntax:
  277. .. code-block:: nim
  278. 1..3
  279. AST:
  280. .. code-block:: nim
  281. nnkInfix(
  282. nnkIdent(".."),
  283. nnkIntLit(1),
  284. nnkIntLit(3)
  285. )
  286. Example code:
  287. .. code-block:: nim
  288. macro genRepeatEcho(): stmt =
  289. result = newNimNode(nnkStmtList)
  290. var forStmt = newNimNode(nnkForStmt) # generate a for statement
  291. forStmt.add(ident("i")) # use the variable `i` for iteration
  292. var rangeDef = newNimNode(nnkInfix).add(
  293. ident("..")).add(
  294. newIntLitNode(3),newIntLitNode(5)) # iterate over the range 3..5
  295. forStmt.add(rangeDef)
  296. forStmt.add(newCall(ident("echo"), newIntLitNode(3))) # meat of the loop
  297. result.add(forStmt)
  298. genRepeatEcho() # gives:
  299. # 3
  300. # 3
  301. # 3
  302. If expression
  303. -------------
  304. The representation of the ``if`` expression is subtle, but easy to traverse.
  305. Concrete syntax:
  306. .. code-block:: nim
  307. if cond1: expr1 elif cond2: expr2 else: expr3
  308. AST:
  309. .. code-block:: nim
  310. nnkIfExpr(
  311. nnkElifExpr(cond1, expr1),
  312. nnkElifExpr(cond2, expr2),
  313. nnkElseExpr(expr3)
  314. )
  315. Documentation Comments
  316. ----------------------
  317. Double-hash (``##``) comments in the code actually have their own format,
  318. using ``strVal`` to get and set the comment text. Single-hash (``#``)
  319. comments are ignored.
  320. Concrete syntax:
  321. .. code-block:: nim
  322. ## This is a comment
  323. ## This is part of the first comment
  324. stmt1
  325. ## Yet another
  326. AST:
  327. .. code-block:: nim
  328. nnkCommentStmt() # only appears once for the first two lines!
  329. stmt1
  330. nnkCommentStmt() # another nnkCommentStmt because there is another comment
  331. # (separate from the first)
  332. Pragmas
  333. -------
  334. One of Nim's cool features is pragmas, which allow fine-tuning of various
  335. aspects of the language. They come in all types, such as adorning procs and
  336. objects, but the standalone ``emit`` pragma shows the basics with the AST.
  337. Concrete syntax:
  338. .. code-block:: nim
  339. {.emit: "#include <stdio.h>".}
  340. AST:
  341. .. code-block:: nim
  342. nnkPragma(
  343. nnkExprColonExpr(
  344. nnkIdent("emit"),
  345. nnkStrLit("#include <stdio.h>") # the "argument"
  346. )
  347. )
  348. As many ``nnkIdent`` appear as there are pragmas between ``{..}``. Note that
  349. the declaration of new pragmas is essentially the same:
  350. Concrete syntax:
  351. .. code-block:: nim
  352. {.pragma: cdeclRename, cdecl.}
  353. AST:
  354. .. code-block:: nim
  355. nnkPragma(
  356. nnkExprColonExpr(
  357. nnkIdent("pragma"), # this is always first when declaring a new pragma
  358. nnkIdent("cdeclRename") # the name of the pragma
  359. ),
  360. nnkIdent("cdecl")
  361. )
  362. Statements
  363. ==========
  364. If statement
  365. ------------
  366. The representation of the if statement is subtle, but easy to traverse. If
  367. there is no ``else`` branch, no ``nnkElse`` child exists.
  368. Concrete syntax:
  369. .. code-block:: nim
  370. if cond1:
  371. stmt1
  372. elif cond2:
  373. stmt2
  374. elif cond3:
  375. stmt3
  376. else:
  377. stmt4
  378. AST:
  379. .. code-block:: nim
  380. nnkIfStmt(
  381. nnkElifBranch(cond1, stmt1),
  382. nnkElifBranch(cond2, stmt2),
  383. nnkElifBranch(cond3, stmt3),
  384. nnkElse(stmt4)
  385. )
  386. When statement
  387. --------------
  388. Like the ``if`` statement, but the root has the kind ``nnkWhenStmt``.
  389. Assignment
  390. ----------
  391. Concrete syntax:
  392. .. code-block:: nim
  393. x = 42
  394. AST:
  395. .. code-block:: nim
  396. nnkAsgn(nnkIdent("x"), nnkIntLit(42))
  397. This is not the syntax for assignment when combined with ``var``, ``let``,
  398. or ``const``.
  399. Statement list
  400. --------------
  401. Concrete syntax:
  402. .. code-block:: nim
  403. stmt1
  404. stmt2
  405. stmt3
  406. AST:
  407. .. code-block:: nim
  408. nnkStmtList(stmt1, stmt2, stmt3)
  409. Case statement
  410. --------------
  411. Concrete syntax:
  412. .. code-block:: nim
  413. case expr1
  414. of expr2, expr3..expr4:
  415. stmt1
  416. of expr5:
  417. stmt2
  418. elif cond1:
  419. stmt3
  420. else:
  421. stmt4
  422. AST:
  423. .. code-block:: nim
  424. nnkCaseStmt(
  425. expr1,
  426. nnkOfBranch(expr2, nnkRange(expr3, expr4), stmt1),
  427. nnkOfBranch(expr5, stmt2),
  428. nnkElifBranch(cond1, stmt3),
  429. nnkElse(stmt4)
  430. )
  431. The ``nnkElifBranch`` and ``nnkElse`` parts may be missing.
  432. While statement
  433. ---------------
  434. Concrete syntax:
  435. .. code-block:: nim
  436. while expr1:
  437. stmt1
  438. AST:
  439. .. code-block:: nim
  440. nnkWhileStmt(expr1, stmt1)
  441. For statement
  442. -------------
  443. Concrete syntax:
  444. .. code-block:: nim
  445. for ident1, ident2 in expr1:
  446. stmt1
  447. AST:
  448. .. code-block:: nim
  449. nnkForStmt(ident1, ident2, expr1, stmt1)
  450. Try statement
  451. -------------
  452. Concrete syntax:
  453. .. code-block:: nim
  454. try:
  455. stmt1
  456. except e1, e2:
  457. stmt2
  458. except e3:
  459. stmt3
  460. except:
  461. stmt4
  462. finally:
  463. stmt5
  464. AST:
  465. .. code-block:: nim
  466. nnkTryStmt(
  467. stmt1,
  468. nnkExceptBranch(e1, e2, stmt2),
  469. nnkExceptBranch(e3, stmt3),
  470. nnkExceptBranch(stmt4),
  471. nnkFinally(stmt5)
  472. )
  473. Return statement
  474. ----------------
  475. Concrete syntax:
  476. .. code-block:: nim
  477. return expr1
  478. AST:
  479. .. code-block:: nim
  480. nnkReturnStmt(expr1)
  481. Yield statement
  482. ---------------
  483. Like ``return``, but with ``nnkYieldStmt`` kind.
  484. .. code-block:: nim
  485. nnkYieldStmt(expr1)
  486. Discard statement
  487. -----------------
  488. Like ``return``, but with ``nnkDiscardStmt`` kind.
  489. .. code-block:: nim
  490. nnkDiscardStmt(expr1)
  491. Continue statement
  492. ------------------
  493. Concrete syntax:
  494. .. code-block:: nim
  495. continue
  496. AST:
  497. .. code-block:: nim
  498. nnkContinueStmt()
  499. Break statement
  500. ---------------
  501. Concrete syntax:
  502. .. code-block:: nim
  503. break otherLocation
  504. AST:
  505. .. code-block:: nim
  506. nnkBreakStmt(nnkIdent("otherLocation"))
  507. If ``break`` is used without a jump-to location, ``nnkEmpty`` replaces ``nnkIdent``.
  508. Block statement
  509. ---------------
  510. Concrete syntax:
  511. .. code-block:: nim
  512. block name:
  513. AST:
  514. .. code-block:: nim
  515. nnkBlockStmt(nnkIdent("name"), nnkStmtList(...))
  516. A ``block`` doesn't need an name, in which case ``nnkEmpty`` is used.
  517. Asm statement
  518. -------------
  519. Concrete syntax:
  520. .. code-block:: nim
  521. asm """
  522. some asm
  523. """
  524. AST:
  525. .. code-block:: nim
  526. nnkAsmStmt(
  527. nnkEmpty(), # for pragmas
  528. nnkTripleStrLit("some asm"),
  529. )
  530. Import section
  531. --------------
  532. Nim's ``import`` statement actually takes different variations depending
  533. on what keywords are present. Let's start with the simplest form.
  534. Concrete syntax:
  535. .. code-block:: nim
  536. import math
  537. AST:
  538. .. code-block:: nim
  539. nnkImportStmt(nnkIdent("math"))
  540. With ``except``, we get ``nnkImportExceptStmt``.
  541. Concrete syntax:
  542. .. code-block:: nim
  543. import math except pow
  544. AST:
  545. .. code-block:: nim
  546. nnkImportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
  547. Note that ``import math as m`` does not use a different node; rather,
  548. we use ``nnkImportStmt`` with ``as`` as an infix operator.
  549. Concrete syntax:
  550. .. code-block:: nim
  551. import strutils as su
  552. AST:
  553. .. code-block:: nim
  554. nnkImportStmt(
  555. nnkInfix(
  556. nnkIdent("as"),
  557. nnkIdent("strutils"),
  558. nnkIdent("su")
  559. )
  560. )
  561. From statement
  562. --------------
  563. If we use ``from ... import``, the result is different, too.
  564. Concrete syntax:
  565. .. code-block:: nim
  566. from math import pow
  567. AST:
  568. .. code-block:: nim
  569. nnkFromStmt(nnkIdent("math"), nnkIdent("pow"))
  570. Using ``from math as m import pow`` works identically to the ``as`` modifier
  571. with the ``import`` statement, but wrapped in ``nnkFromStmt``.
  572. Export statement
  573. ----------------
  574. When you are making an imported module accessible by modules that import yours,
  575. the ``export`` syntax is pretty straightforward.
  576. Concrete syntax:
  577. .. code-block:: nim
  578. export unsigned
  579. AST:
  580. .. code-block:: nim
  581. nnkExportStmt(nnkIdent("unsigned"))
  582. Similar to the ``import`` statement, the AST is different for
  583. ``export ... except``.
  584. Concrete syntax:
  585. .. code-block:: nim
  586. export math except pow # we're going to implement our own exponentiation
  587. AST:
  588. .. code-block:: nim
  589. nnkExportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
  590. Include statement
  591. -----------------
  592. Like a plain ``import`` statement but with ``nnkIncludeStmt``.
  593. Concrete syntax:
  594. .. code-block:: nim
  595. include blocks
  596. AST:
  597. .. code-block:: nim
  598. nnkIncludeStmt(nnkIdent("blocks"))
  599. Var section
  600. -----------
  601. Concrete syntax:
  602. .. code-block:: nim
  603. var a = 3
  604. AST:
  605. .. code-block:: nim
  606. nnkVarSection(
  607. nnkIdentDefs(
  608. nnkIdent("a"),
  609. nnkEmpty(), # or nnkIdent(...) if the variable declares the type
  610. nnkIntLit(3),
  611. )
  612. )
  613. Note that either the second or third (or both) parameters above must exist,
  614. as the compiler needs to know the type somehow (which it can infer from
  615. the given assignment).
  616. This is not the same AST for all uses of ``var``. See
  617. [Procedure declaration](http://nim-lang.org/docs/macros.html#statements-procedure-declaration)
  618. for details.
  619. Let section
  620. -----------
  621. This is equivalent to ``var``, but with ``nnkLetSection`` rather than
  622. ``nnkVarSection``.
  623. Concrete syntax:
  624. .. code-block:: nim
  625. let a = 3
  626. AST:
  627. .. code-block:: nim
  628. nnkLetSection(
  629. nnkIdentDefs(
  630. nnkIdent("a"),
  631. nnkEmpty(), # or nnkIdent(...) for the type
  632. nnkIntLit(3),
  633. )
  634. )
  635. Const section
  636. -------------
  637. Concrete syntax:
  638. .. code-block:: nim
  639. const a = 3
  640. AST:
  641. .. code-block:: nim
  642. nnkConstSection(
  643. nnkConstDef( # not nnkConstDefs!
  644. nnkIdent("a"),
  645. nnkEmpty(), # or nnkIdent(...) if the variable declares the type
  646. nnkIntLit(3), # required in a const declaration!
  647. )
  648. )
  649. Type section
  650. ------------
  651. Starting with the simplest case, a ``type`` section appears much like ``var``
  652. and ``const``.
  653. Concrete syntax:
  654. .. code-block:: nim
  655. type A = int
  656. AST:
  657. .. code-block:: nim
  658. nnkTypeSection(
  659. nnkTypeDef(
  660. nnkIdent("A"),
  661. nnkEmpty(),
  662. nnkIdent("int")
  663. )
  664. )
  665. Declaring ``distinct`` types is similar, with the last ``nnkIdent`` wrapped
  666. in ``nnkDistinctTy``.
  667. Concrete syntax:
  668. .. code-block:: nim
  669. type MyInt = distinct int
  670. AST:
  671. .. code-block:: nim
  672. # ...
  673. nnkTypeDef(
  674. nnkIdent("MyInt"),
  675. nnkEmpty(),
  676. nnkDistinctTy(
  677. nnkIdent("int")
  678. )
  679. )
  680. If a type section uses generic parameters, they are treated here:
  681. Concrete syntax:
  682. .. code-block:: nim
  683. type A[T] = expr1
  684. AST:
  685. .. code-block:: nim
  686. nnkTypeSection(
  687. nnkTypeDef(
  688. nnkIdent("A"),
  689. nnkGenericParams(
  690. nnkIdentDefs(
  691. nnkIdent("T"),
  692. nnkEmpty(), # if the type is declared with options, like
  693. # ``[T: SomeInteger]``, they are given here
  694. nnkEmpty(),
  695. )
  696. )
  697. expr1,
  698. )
  699. )
  700. Note that not all ``nnkTypeDef`` utilize ``nnkIdent`` as their
  701. their parameter. One of the most common uses of type declarations
  702. is to work with objects.
  703. Concrete syntax:
  704. .. code-block:: nim
  705. type IO = object of RootObj
  706. AST:
  707. .. code-block:: nim
  708. # ...
  709. nnkTypeDef(
  710. nnkIdent("IO"),
  711. nnkEmpty(),
  712. nnkObjectTy(
  713. nnkEmpty(), # no pragmas here
  714. nnkOfInherit(
  715. nnkIdent("RootObj") # inherits from RootObj
  716. )
  717. nnkEmpty()
  718. )
  719. )
  720. Nim's object syntax is rich. Let's take a look at an involved example in
  721. its entirety to see some of the complexities.
  722. Concrete syntax:
  723. .. code-block:: nim
  724. type Obj[T] = object {.inheritable.}
  725. name: string
  726. case isFat: bool
  727. of true:
  728. m: array[100_000, T]
  729. of false:
  730. m: array[10, T]
  731. AST:
  732. .. code-block:: nim
  733. # ...
  734. nnkObjectTy(
  735. nnkPragma(
  736. nnkIdent("inheritable")
  737. ),
  738. nnkEmpty(),
  739. nnkRecList( # list of object parameters
  740. nnkIdentDefs(
  741. nnkIdent("name"),
  742. nnkIdent("string"),
  743. nnkEmpty()
  744. ),
  745. nnkRecCase( # case statement within object (not nnkCaseStmt)
  746. nnkIdentDefs(
  747. nnkIdent("isFat"),
  748. nnkIdent("bool"),
  749. nnkEmpty()
  750. ),
  751. nnkOfBranch(
  752. nnkIdent("true"),
  753. nnkRecList( # again, a list of object parameters
  754. nnkIdentDefs(
  755. nnkIdent("m"),
  756. nnkBracketExpr(
  757. nnkIdent("array"),
  758. nnkIntLit(100000),
  759. nnkIdent("T")
  760. ),
  761. nnkEmpty()
  762. )
  763. ),
  764. nnkOfBranch(
  765. nnkIdent("false"),
  766. nnkRecList(
  767. nnkIdentDefs(
  768. nnkIdent("m"),
  769. nnkBracketExpr(
  770. nnkIdent("array"),
  771. nnkIntLit(10),
  772. nnkIdent("T")
  773. ),
  774. nnkEmpty()
  775. )
  776. )
  777. )
  778. )
  779. )
  780. )
  781. Using an ``enum`` is similar to using an ``object``.
  782. Concrete syntax:
  783. .. code-block:: nim
  784. type X = enum
  785. First
  786. AST:
  787. .. code-block:: nim
  788. # ...
  789. nnkEnumTy(
  790. nnkEmpty(),
  791. nnkIdent("First") # you need at least one nnkIdent or the compiler complains
  792. )
  793. The usage of ``concept`` (experimental) is similar to objects.
  794. Concrete syntax:
  795. .. code-block:: nim
  796. type Con = concept x,y,z
  797. (x & y & z) is string
  798. AST:
  799. .. code-block:: nim
  800. # ...
  801. nnkTypeClassTy( # note this isn't nnkConceptTy!
  802. nnkArglist(
  803. # ... idents for x, y, z
  804. )
  805. # ...
  806. )
  807. Static types, like ``static[int]``, use ``nnkIdent`` wrapped in
  808. ``nnkStaticTy``.
  809. Concrete syntax:
  810. .. code-block:: nim
  811. type A[T: static[int]] = object
  812. AST:
  813. .. code-block:: nim
  814. # ... within nnkGenericParams
  815. nnkIdentDefs(
  816. nnkIdent("T"),
  817. nnkStaticTy(
  818. nnkIdent("int")
  819. ),
  820. nnkEmpty()
  821. )
  822. # ...
  823. In general, declaring types mirrors this syntax (i.e., ``nnkStaticTy`` for
  824. ``static``, etc.). Examples follow (exceptions marked by ``*``):
  825. ------------- ---------------------------------------------
  826. Nim type Corresponding AST
  827. ------------- ---------------------------------------------
  828. ``static`` ``nnkStaticTy``
  829. ``tuple`` ``nnkTupleTy``
  830. ``var`` ``nnkVarTy``
  831. ``ptr`` ``nnkPtrTy``
  832. ``ref`` ``nnkRefTy``
  833. ``distinct`` ``nnkDistinctTy``
  834. ``enum`` ``nnkEnumTy``
  835. ``concept`` ``nnkTypeClassTy``\*
  836. ``array`` ``nnkBracketExpr(nnkIdent("array"),...``\*
  837. ``proc`` ``nnkProcTy``
  838. ``iterator`` ``nnkIteratorTy``
  839. ``object`` ``nnkObjectTy``
  840. ------------- ---------------------------------------------
  841. Take special care when declaring types as ``proc``. The behavior is similar
  842. to ``Procedure declaration``, below, but does not treat ``nnkGenericParams``.
  843. Generic parameters are treated in the type, not the ``proc`` itself.
  844. Concrete syntax:
  845. .. code-block:: nim
  846. type MyProc[T] = proc(x: T)
  847. AST:
  848. .. code-block:: nim
  849. # ...
  850. nnkTypeDef(
  851. nnkIdent("MyProc"),
  852. nnkGenericParams( # here, not with the proc
  853. # ...
  854. )
  855. nnkProcTy( # behaves like a procedure declaration from here on
  856. nnkFormalParams(
  857. # ...
  858. )
  859. )
  860. )
  861. The same syntax applies to ``iterator`` (with ``nnkIteratorTy``), but
  862. *does not* apply to ``converter`` or ``template``.
  863. Mixin statement
  864. ---------------
  865. Concrete syntax:
  866. .. code-block:: nim
  867. mixin x
  868. AST:
  869. .. code-block:: nim
  870. nnkMixinStmt(nnkIdent("x"))
  871. Bind statement
  872. --------------
  873. Concrete syntax:
  874. .. code-block:: nim
  875. bind x
  876. AST:
  877. .. code-block:: nim
  878. nnkBindStmt(nnkIdent("x"))
  879. Procedure declaration
  880. ---------------------
  881. Let's take a look at a procedure with a lot of interesting aspects to get
  882. a feel for how procedure calls are broken down.
  883. Concrete syntax:
  884. .. code-block:: nim
  885. proc hello*[T: SomeInteger](x: int = 3, y: float32): int {.inline.} = discard
  886. AST:
  887. .. code-block:: nim
  888. nnkProcDef(
  889. nnkPostfix(nnkIdent("*"), nnkIdent("hello")), # the exported proc name
  890. nnkEmpty(), # patterns for term rewriting in templates and macros (not procs)
  891. nnkGenericParams( # generic type parameters, like with type declaration
  892. nnkIdentDefs(
  893. nnkIdent("T"), nnkIdent("SomeInteger")
  894. )
  895. ),
  896. nnkFormalParams(
  897. nnkIdent("int"), # the first FormalParam is the return type. nnkEmpty() if there is none
  898. nnkIdentDefs(
  899. nnkIdent("x"),
  900. nnkIdent("int"), # type type (required for procs, not for templates)
  901. nnkIntLit(3) # a default value
  902. ),
  903. nnkIdentDefs(
  904. nnkIdent("y"),
  905. nnkIdent("float32"),
  906. nnkEmpty()
  907. )
  908. ),
  909. nnkPragma(nnkIdent("inline")),
  910. nnkEmpty(), # reserved slot for future use
  911. nnkStmtList(nnkDiscardStmt(nnkEmpty())) # the meat of the proc
  912. )
  913. There is another consideration. Nim has flexible type identification for
  914. its procs. Even though ``proc(a: int, b: int)`` and ``proc(a, b: int)``
  915. are equivalent in the code, the AST is a little different for the latter.
  916. Concrete syntax:
  917. .. code-block:: nim
  918. proc(a, b: int)
  919. AST:
  920. .. code-block:: nim
  921. # ...AST as above...
  922. nnkFormalParams(
  923. nnkEmpty(), # no return here
  924. nnkIdentDefs(
  925. nnkIdent("a"), # the first parameter
  926. nnkIdent("b"), # directly to the second parameter
  927. nnkIdent("int"), # their shared type identifier
  928. nnkEmpty(), # default value would go here
  929. )
  930. ),
  931. # ...
  932. When a procedure uses the special ``var`` type return variable, the result
  933. is different from that of a var section.
  934. Concrete syntax:
  935. .. code-block:: nim
  936. proc hello(): var int
  937. AST:
  938. .. code-block:: nim
  939. # ...
  940. nnkFormalParams(
  941. nnkVarTy(
  942. nnkIdent("int")
  943. )
  944. )
  945. Iterator declaration
  946. --------------------
  947. The syntax for iterators is similar to procs, but with ``nnkIteratorDef``
  948. replacing ``nnkProcDef``.
  949. Concrete syntax:
  950. .. code-block:: nim
  951. iterator nonsense[T](x: seq[T]): float {.closure.} = ...
  952. AST:
  953. .. code-block:: nim
  954. nnkIteratorDef(
  955. nnkIdent("nonsense"),
  956. nnkEmpty(),
  957. ...
  958. )
  959. Converter declaration
  960. ---------------------
  961. A converter is similar to a proc.
  962. Concrete syntax:
  963. .. code-block:: nim
  964. converter toBool(x: float): bool
  965. AST:
  966. .. code-block:: nim
  967. nnkConverterDef(
  968. nnkIdent("toBool"),
  969. # ...
  970. )
  971. Template declaration
  972. --------------------
  973. Templates (as well as macros, as we'll see) have a slightly expanded AST when
  974. compared to procs and iterators. The reason for this is [term-rewriting
  975. macros](http://nim-lang.org/docs/manual.html#term-rewriting-macros). Notice
  976. the ``nnkEmpty()`` as the second argument to ``nnkProcDef`` and
  977. ``nnkIteratorDef`` above? That's where the term-rewriting macros go.
  978. Concrete syntax:
  979. .. code-block:: nim
  980. template optOpt{expr1}(a: int): int
  981. AST:
  982. .. code-block:: nim
  983. nnkTemplateDef(
  984. nnkIdent("optOpt"),
  985. nnkStmtList( # instead of nnkEmpty()
  986. expr1
  987. ),
  988. # follows like a proc or iterator
  989. )
  990. If the template does not have types for its parameters, the type identifiers
  991. inside ``nnkFormalParams`` just becomes ``nnkEmpty``.
  992. Macro declaration
  993. -----------------
  994. Macros behave like templates, but ``nnkTemplateDef`` is replaced with
  995. ``nnkMacroDef``.
  996. Special node kinds
  997. ==================
  998. There are several node kinds that are used for semantic checking or code
  999. generation. These are accessible from this module, but should not be used.
  1000. Other node kinds are especially designed to make AST manipulations easier.
  1001. These are explained here.
  1002. To be written.