astspec.txt 28 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462
  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](#callsslashexpressions-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](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 use the ``nnkPar`` node.
  236. Concrete syntax:
  237. .. code-block:: nim
  238. (a + b) * c
  239. AST:
  240. .. code-block:: nim
  241. nnkInfix(nnkIdent("*"),
  242. nnkPar(
  243. nnkInfix(nnkIdent("+"), nnkIdent("a"), nnkIdent("b"))),
  244. nnkIdent("c"))
  245. Tuple Constructors
  246. ------------------
  247. Nodes for tuple construction are built with the ``nnkTupleConstr`` node.
  248. Concrete syntax:
  249. .. code-block:: nim
  250. (1, 2, 3)
  251. (a: 1, b: 2, c: 3)
  252. ()
  253. AST:
  254. .. code-block:: nim
  255. nnkTupleConstr(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
  256. nnkTupleConstr(
  257. nnkExprColonExpr(nnkIdent("a"), nnkIntLit(1)),
  258. nnkExprColonExpr(nnkIdent("b"), nnkIntLit(2)),
  259. nnkExprColonExpr(nnkIdent("c"), nnkIntLit(3)))
  260. nnkTupleConstr()
  261. Since the one tuple would be syntactically identical to parentheses
  262. with an expression in them, the parser expects a trailing comma for
  263. them. For tuple constructors with field names, this is not necessary.
  264. .. code-block:: nim
  265. (1,)
  266. (a: 1)
  267. AST:
  268. .. code-block:: nim
  269. nnkTupleConstr(nnkIntLit(1))
  270. nnkTupleConstr(
  271. nnkExprColonExpr(nnkIdent("a"), nnkIntLit(1)))
  272. Curly braces
  273. ------------
  274. Curly braces are used as the set constructor.
  275. Concrete syntax:
  276. .. code-block:: nim
  277. {1, 2, 3}
  278. AST:
  279. .. code-block:: nim
  280. nnkCurly(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
  281. When used as a table constructor, the syntax is different.
  282. Concrete syntax:
  283. .. code-block:: nim
  284. {a: 3, b: 5}
  285. AST:
  286. .. code-block:: nim
  287. nnkTableConstr(
  288. nnkExprColonExpr(nnkIdent("a"), nnkIntLit(3)),
  289. nnkExprColonExpr(nnkIdent("b"), nnkIntLit(5))
  290. )
  291. Brackets
  292. --------
  293. Brackets are used as the array constructor.
  294. Concrete syntax:
  295. .. code-block:: nim
  296. [1, 2, 3]
  297. AST:
  298. .. code-block:: nim
  299. nnkBracket(nnkIntLit(1), nnkIntLit(2), nnkIntLit(3))
  300. Ranges
  301. ------
  302. Ranges occur in set constructors, case statement branches, or array slices.
  303. Internally, the node kind ``nnkRange`` is used, but when constructing the
  304. AST, construction with ``..`` as an infix operator should be used instead.
  305. Concrete syntax:
  306. .. code-block:: nim
  307. 1..3
  308. AST:
  309. .. code-block:: nim
  310. nnkInfix(
  311. nnkIdent(".."),
  312. nnkIntLit(1),
  313. nnkIntLit(3)
  314. )
  315. Example code:
  316. .. code-block:: nim
  317. macro genRepeatEcho() =
  318. result = newNimNode(nnkStmtList)
  319. var forStmt = newNimNode(nnkForStmt) # generate a for statement
  320. forStmt.add(ident("i")) # use the variable `i` for iteration
  321. var rangeDef = newNimNode(nnkInfix).add(
  322. ident("..")).add(
  323. newIntLitNode(3),newIntLitNode(5)) # iterate over the range 3..5
  324. forStmt.add(rangeDef)
  325. forStmt.add(newCall(ident("echo"), newIntLitNode(3))) # meat of the loop
  326. result.add(forStmt)
  327. genRepeatEcho() # gives:
  328. # 3
  329. # 3
  330. # 3
  331. If expression
  332. -------------
  333. The representation of the ``if`` expression is subtle, but easy to traverse.
  334. Concrete syntax:
  335. .. code-block:: nim
  336. if cond1: expr1 elif cond2: expr2 else: expr3
  337. AST:
  338. .. code-block:: nim
  339. nnkIfExpr(
  340. nnkElifExpr(cond1, expr1),
  341. nnkElifExpr(cond2, expr2),
  342. nnkElseExpr(expr3)
  343. )
  344. Documentation Comments
  345. ----------------------
  346. Double-hash (``##``) comments in the code actually have their own format,
  347. using ``strVal`` to get and set the comment text. Single-hash (``#``)
  348. comments are ignored.
  349. Concrete syntax:
  350. .. code-block:: nim
  351. ## This is a comment
  352. ## This is part of the first comment
  353. stmt1
  354. ## Yet another
  355. AST:
  356. .. code-block:: nim
  357. nnkCommentStmt() # only appears once for the first two lines!
  358. stmt1
  359. nnkCommentStmt() # another nnkCommentStmt because there is another comment
  360. # (separate from the first)
  361. Pragmas
  362. -------
  363. One of Nim's cool features is pragmas, which allow fine-tuning of various
  364. aspects of the language. They come in all types, such as adorning procs and
  365. objects, but the standalone ``emit`` pragma shows the basics with the AST.
  366. Concrete syntax:
  367. .. code-block:: nim
  368. {.emit: "#include <stdio.h>".}
  369. AST:
  370. .. code-block:: nim
  371. nnkPragma(
  372. nnkExprColonExpr(
  373. nnkIdent("emit"),
  374. nnkStrLit("#include <stdio.h>") # the "argument"
  375. )
  376. )
  377. As many ``nnkIdent`` appear as there are pragmas between ``{..}``. Note that
  378. the declaration of new pragmas is essentially the same:
  379. Concrete syntax:
  380. .. code-block:: nim
  381. {.pragma: cdeclRename, cdecl.}
  382. AST:
  383. .. code-block:: nim
  384. nnkPragma(
  385. nnkExprColonExpr(
  386. nnkIdent("pragma"), # this is always first when declaring a new pragma
  387. nnkIdent("cdeclRename") # the name of the pragma
  388. ),
  389. nnkIdent("cdecl")
  390. )
  391. Statements
  392. ==========
  393. If statement
  394. ------------
  395. The representation of the if statement is subtle, but easy to traverse. If
  396. there is no ``else`` branch, no ``nnkElse`` child exists.
  397. Concrete syntax:
  398. .. code-block:: nim
  399. if cond1:
  400. stmt1
  401. elif cond2:
  402. stmt2
  403. elif cond3:
  404. stmt3
  405. else:
  406. stmt4
  407. AST:
  408. .. code-block:: nim
  409. nnkIfStmt(
  410. nnkElifBranch(cond1, stmt1),
  411. nnkElifBranch(cond2, stmt2),
  412. nnkElifBranch(cond3, stmt3),
  413. nnkElse(stmt4)
  414. )
  415. When statement
  416. --------------
  417. Like the ``if`` statement, but the root has the kind ``nnkWhenStmt``.
  418. Assignment
  419. ----------
  420. Concrete syntax:
  421. .. code-block:: nim
  422. x = 42
  423. AST:
  424. .. code-block:: nim
  425. nnkAsgn(nnkIdent("x"), nnkIntLit(42))
  426. This is not the syntax for assignment when combined with ``var``, ``let``,
  427. or ``const``.
  428. Statement list
  429. --------------
  430. Concrete syntax:
  431. .. code-block:: nim
  432. stmt1
  433. stmt2
  434. stmt3
  435. AST:
  436. .. code-block:: nim
  437. nnkStmtList(stmt1, stmt2, stmt3)
  438. Case statement
  439. --------------
  440. Concrete syntax:
  441. .. code-block:: nim
  442. case expr1
  443. of expr2, expr3..expr4:
  444. stmt1
  445. of expr5:
  446. stmt2
  447. elif cond1:
  448. stmt3
  449. else:
  450. stmt4
  451. AST:
  452. .. code-block:: nim
  453. nnkCaseStmt(
  454. expr1,
  455. nnkOfBranch(expr2, nnkRange(expr3, expr4), stmt1),
  456. nnkOfBranch(expr5, stmt2),
  457. nnkElifBranch(cond1, stmt3),
  458. nnkElse(stmt4)
  459. )
  460. The ``nnkElifBranch`` and ``nnkElse`` parts may be missing.
  461. While statement
  462. ---------------
  463. Concrete syntax:
  464. .. code-block:: nim
  465. while expr1:
  466. stmt1
  467. AST:
  468. .. code-block:: nim
  469. nnkWhileStmt(expr1, stmt1)
  470. For statement
  471. -------------
  472. Concrete syntax:
  473. .. code-block:: nim
  474. for ident1, ident2 in expr1:
  475. stmt1
  476. AST:
  477. .. code-block:: nim
  478. nnkForStmt(ident1, ident2, expr1, stmt1)
  479. Try statement
  480. -------------
  481. Concrete syntax:
  482. .. code-block:: nim
  483. try:
  484. stmt1
  485. except e1, e2:
  486. stmt2
  487. except e3:
  488. stmt3
  489. except:
  490. stmt4
  491. finally:
  492. stmt5
  493. AST:
  494. .. code-block:: nim
  495. nnkTryStmt(
  496. stmt1,
  497. nnkExceptBranch(e1, e2, stmt2),
  498. nnkExceptBranch(e3, stmt3),
  499. nnkExceptBranch(stmt4),
  500. nnkFinally(stmt5)
  501. )
  502. Return statement
  503. ----------------
  504. Concrete syntax:
  505. .. code-block:: nim
  506. return expr1
  507. AST:
  508. .. code-block:: nim
  509. nnkReturnStmt(expr1)
  510. Yield statement
  511. ---------------
  512. Like ``return``, but with ``nnkYieldStmt`` kind.
  513. .. code-block:: nim
  514. nnkYieldStmt(expr1)
  515. Discard statement
  516. -----------------
  517. Like ``return``, but with ``nnkDiscardStmt`` kind.
  518. .. code-block:: nim
  519. nnkDiscardStmt(expr1)
  520. Continue statement
  521. ------------------
  522. Concrete syntax:
  523. .. code-block:: nim
  524. continue
  525. AST:
  526. .. code-block:: nim
  527. nnkContinueStmt()
  528. Break statement
  529. ---------------
  530. Concrete syntax:
  531. .. code-block:: nim
  532. break otherLocation
  533. AST:
  534. .. code-block:: nim
  535. nnkBreakStmt(nnkIdent("otherLocation"))
  536. If ``break`` is used without a jump-to location, ``nnkEmpty`` replaces ``nnkIdent``.
  537. Block statement
  538. ---------------
  539. Concrete syntax:
  540. .. code-block:: nim
  541. block name:
  542. AST:
  543. .. code-block:: nim
  544. nnkBlockStmt(nnkIdent("name"), nnkStmtList(...))
  545. A ``block`` doesn't need an name, in which case ``nnkEmpty`` is used.
  546. Asm statement
  547. -------------
  548. Concrete syntax:
  549. .. code-block:: nim
  550. asm """
  551. some asm
  552. """
  553. AST:
  554. .. code-block:: nim
  555. nnkAsmStmt(
  556. nnkEmpty(), # for pragmas
  557. nnkTripleStrLit("some asm"),
  558. )
  559. Import section
  560. --------------
  561. Nim's ``import`` statement actually takes different variations depending
  562. on what keywords are present. Let's start with the simplest form.
  563. Concrete syntax:
  564. .. code-block:: nim
  565. import math
  566. AST:
  567. .. code-block:: nim
  568. nnkImportStmt(nnkIdent("math"))
  569. With ``except``, we get ``nnkImportExceptStmt``.
  570. Concrete syntax:
  571. .. code-block:: nim
  572. import math except pow
  573. AST:
  574. .. code-block:: nim
  575. nnkImportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
  576. Note that ``import math as m`` does not use a different node; rather,
  577. we use ``nnkImportStmt`` with ``as`` as an infix operator.
  578. Concrete syntax:
  579. .. code-block:: nim
  580. import strutils as su
  581. AST:
  582. .. code-block:: nim
  583. nnkImportStmt(
  584. nnkInfix(
  585. nnkIdent("as"),
  586. nnkIdent("strutils"),
  587. nnkIdent("su")
  588. )
  589. )
  590. From statement
  591. --------------
  592. If we use ``from ... import``, the result is different, too.
  593. Concrete syntax:
  594. .. code-block:: nim
  595. from math import pow
  596. AST:
  597. .. code-block:: nim
  598. nnkFromStmt(nnkIdent("math"), nnkIdent("pow"))
  599. Using ``from math as m import pow`` works identically to the ``as`` modifier
  600. with the ``import`` statement, but wrapped in ``nnkFromStmt``.
  601. Export statement
  602. ----------------
  603. When you are making an imported module accessible by modules that import yours,
  604. the ``export`` syntax is pretty straightforward.
  605. Concrete syntax:
  606. .. code-block:: nim
  607. export unsigned
  608. AST:
  609. .. code-block:: nim
  610. nnkExportStmt(nnkIdent("unsigned"))
  611. Similar to the ``import`` statement, the AST is different for
  612. ``export ... except``.
  613. Concrete syntax:
  614. .. code-block:: nim
  615. export math except pow # we're going to implement our own exponentiation
  616. AST:
  617. .. code-block:: nim
  618. nnkExportExceptStmt(nnkIdent("math"),nnkIdent("pow"))
  619. Include statement
  620. -----------------
  621. Like a plain ``import`` statement but with ``nnkIncludeStmt``.
  622. Concrete syntax:
  623. .. code-block:: nim
  624. include blocks
  625. AST:
  626. .. code-block:: nim
  627. nnkIncludeStmt(nnkIdent("blocks"))
  628. Var section
  629. -----------
  630. Concrete syntax:
  631. .. code-block:: nim
  632. var a = 3
  633. AST:
  634. .. code-block:: nim
  635. nnkVarSection(
  636. nnkIdentDefs(
  637. nnkIdent("a"),
  638. nnkEmpty(), # or nnkIdent(...) if the variable declares the type
  639. nnkIntLit(3),
  640. )
  641. )
  642. Note that either the second or third (or both) parameters above must exist,
  643. as the compiler needs to know the type somehow (which it can infer from
  644. the given assignment).
  645. This is not the same AST for all uses of ``var``. See
  646. [Procedure declaration](macros.html#statements-procedure-declaration)
  647. for details.
  648. Let section
  649. -----------
  650. This is equivalent to ``var``, but with ``nnkLetSection`` rather than
  651. ``nnkVarSection``.
  652. Concrete syntax:
  653. .. code-block:: nim
  654. let a = 3
  655. AST:
  656. .. code-block:: nim
  657. nnkLetSection(
  658. nnkIdentDefs(
  659. nnkIdent("a"),
  660. nnkEmpty(), # or nnkIdent(...) for the type
  661. nnkIntLit(3),
  662. )
  663. )
  664. Const section
  665. -------------
  666. Concrete syntax:
  667. .. code-block:: nim
  668. const a = 3
  669. AST:
  670. .. code-block:: nim
  671. nnkConstSection(
  672. nnkConstDef( # not nnkConstDefs!
  673. nnkIdent("a"),
  674. nnkEmpty(), # or nnkIdent(...) if the variable declares the type
  675. nnkIntLit(3), # required in a const declaration!
  676. )
  677. )
  678. Type section
  679. ------------
  680. Starting with the simplest case, a ``type`` section appears much like ``var``
  681. and ``const``.
  682. Concrete syntax:
  683. .. code-block:: nim
  684. type A = int
  685. AST:
  686. .. code-block:: nim
  687. nnkTypeSection(
  688. nnkTypeDef(
  689. nnkIdent("A"),
  690. nnkEmpty(),
  691. nnkIdent("int")
  692. )
  693. )
  694. Declaring ``distinct`` types is similar, with the last ``nnkIdent`` wrapped
  695. in ``nnkDistinctTy``.
  696. Concrete syntax:
  697. .. code-block:: nim
  698. type MyInt = distinct int
  699. AST:
  700. .. code-block:: nim
  701. # ...
  702. nnkTypeDef(
  703. nnkIdent("MyInt"),
  704. nnkEmpty(),
  705. nnkDistinctTy(
  706. nnkIdent("int")
  707. )
  708. )
  709. If a type section uses generic parameters, they are treated here:
  710. Concrete syntax:
  711. .. code-block:: nim
  712. type A[T] = expr1
  713. AST:
  714. .. code-block:: nim
  715. nnkTypeSection(
  716. nnkTypeDef(
  717. nnkIdent("A"),
  718. nnkGenericParams(
  719. nnkIdentDefs(
  720. nnkIdent("T"),
  721. nnkEmpty(), # if the type is declared with options, like
  722. # ``[T: SomeInteger]``, they are given here
  723. nnkEmpty(),
  724. )
  725. )
  726. expr1,
  727. )
  728. )
  729. Note that not all ``nnkTypeDef`` utilize ``nnkIdent`` as their
  730. parameter. One of the most common uses of type declarations
  731. is to work with objects.
  732. Concrete syntax:
  733. .. code-block:: nim
  734. type IO = object of RootObj
  735. AST:
  736. .. code-block:: nim
  737. # ...
  738. nnkTypeDef(
  739. nnkIdent("IO"),
  740. nnkEmpty(),
  741. nnkObjectTy(
  742. nnkEmpty(), # no pragmas here
  743. nnkOfInherit(
  744. nnkIdent("RootObj") # inherits from RootObj
  745. ),
  746. nnkEmpty()
  747. )
  748. )
  749. Nim's object syntax is rich. Let's take a look at an involved example in
  750. its entirety to see some of the complexities.
  751. Concrete syntax:
  752. .. code-block:: nim
  753. type Obj[T] {.inheritable.} = object
  754. name: string
  755. case isFat: bool
  756. of true:
  757. m: array[100_000, T]
  758. of false:
  759. m: array[10, T]
  760. AST:
  761. .. code-block:: nim
  762. # ...
  763. nnkPragmaExpr(
  764. nnkIdent("Obj"),
  765. nnkPragma(nnkIdent("inheritable"))
  766. ),
  767. nnkGenericParams(
  768. nnkIdentDefs(
  769. nnkIdent("T"),
  770. nnkEmpty(),
  771. nnkEmpty())
  772. ),
  773. nnkObjectTy(
  774. nnkEmpty(),
  775. nnkEmpty(),
  776. nnkRecList( # list of object parameters
  777. nnkIdentDefs(
  778. nnkIdent("name"),
  779. nnkIdent("string"),
  780. nnkEmpty()
  781. ),
  782. nnkRecCase( # case statement within object (not nnkCaseStmt)
  783. nnkIdentDefs(
  784. nnkIdent("isFat"),
  785. nnkIdent("bool"),
  786. nnkEmpty()
  787. ),
  788. nnkOfBranch(
  789. nnkIdent("true"),
  790. nnkRecList( # again, a list of object parameters
  791. nnkIdentDefs(
  792. nnkIdent("m"),
  793. nnkBracketExpr(
  794. nnkIdent("array"),
  795. nnkIntLit(100000),
  796. nnkIdent("T")
  797. ),
  798. nnkEmpty()
  799. )
  800. ),
  801. nnkOfBranch(
  802. nnkIdent("false"),
  803. nnkRecList(
  804. nnkIdentDefs(
  805. nnkIdent("m"),
  806. nnkBracketExpr(
  807. nnkIdent("array"),
  808. nnkIntLit(10),
  809. nnkIdent("T")
  810. ),
  811. nnkEmpty()
  812. )
  813. )
  814. )
  815. )
  816. )
  817. )
  818. Using an ``enum`` is similar to using an ``object``.
  819. Concrete syntax:
  820. .. code-block:: nim
  821. type X = enum
  822. First
  823. AST:
  824. .. code-block:: nim
  825. # ...
  826. nnkEnumTy(
  827. nnkEmpty(),
  828. nnkIdent("First") # you need at least one nnkIdent or the compiler complains
  829. )
  830. The usage of ``concept`` (experimental) is similar to objects.
  831. Concrete syntax:
  832. .. code-block:: nim
  833. type Con = concept x,y,z
  834. (x & y & z) is string
  835. AST:
  836. .. code-block:: nim
  837. # ...
  838. nnkTypeClassTy( # note this isn't nnkConceptTy!
  839. nnkArgList(
  840. # ... idents for x, y, z
  841. )
  842. # ...
  843. )
  844. Static types, like ``static[int]``, use ``nnkIdent`` wrapped in
  845. ``nnkStaticTy``.
  846. Concrete syntax:
  847. .. code-block:: nim
  848. type A[T: static[int]] = object
  849. AST:
  850. .. code-block:: nim
  851. # ... within nnkGenericParams
  852. nnkIdentDefs(
  853. nnkIdent("T"),
  854. nnkStaticTy(
  855. nnkIdent("int")
  856. ),
  857. nnkEmpty()
  858. )
  859. # ...
  860. In general, declaring types mirrors this syntax (i.e., ``nnkStaticTy`` for
  861. ``static``, etc.). Examples follow (exceptions marked by ``*``):
  862. ------------- ---------------------------------------------
  863. Nim type Corresponding AST
  864. ------------- ---------------------------------------------
  865. ``static`` ``nnkStaticTy``
  866. ``tuple`` ``nnkTupleTy``
  867. ``var`` ``nnkVarTy``
  868. ``ptr`` ``nnkPtrTy``
  869. ``ref`` ``nnkRefTy``
  870. ``distinct`` ``nnkDistinctTy``
  871. ``enum`` ``nnkEnumTy``
  872. ``concept`` ``nnkTypeClassTy``\*
  873. ``array`` ``nnkBracketExpr(nnkIdent("array"),...``\*
  874. ``proc`` ``nnkProcTy``
  875. ``iterator`` ``nnkIteratorTy``
  876. ``object`` ``nnkObjectTy``
  877. ------------- ---------------------------------------------
  878. Take special care when declaring types as ``proc``. The behavior is similar
  879. to ``Procedure declaration``, below, but does not treat ``nnkGenericParams``.
  880. Generic parameters are treated in the type, not the ``proc`` itself.
  881. Concrete syntax:
  882. .. code-block:: nim
  883. type MyProc[T] = proc(x: T)
  884. AST:
  885. .. code-block:: nim
  886. # ...
  887. nnkTypeDef(
  888. nnkIdent("MyProc"),
  889. nnkGenericParams( # here, not with the proc
  890. # ...
  891. )
  892. nnkProcTy( # behaves like a procedure declaration from here on
  893. nnkFormalParams(
  894. # ...
  895. )
  896. )
  897. )
  898. The same syntax applies to ``iterator`` (with ``nnkIteratorTy``), but
  899. *does not* apply to ``converter`` or ``template``.
  900. Mixin statement
  901. ---------------
  902. Concrete syntax:
  903. .. code-block:: nim
  904. mixin x
  905. AST:
  906. .. code-block:: nim
  907. nnkMixinStmt(nnkIdent("x"))
  908. Bind statement
  909. --------------
  910. Concrete syntax:
  911. .. code-block:: nim
  912. bind x
  913. AST:
  914. .. code-block:: nim
  915. nnkBindStmt(nnkIdent("x"))
  916. Procedure declaration
  917. ---------------------
  918. Let's take a look at a procedure with a lot of interesting aspects to get
  919. a feel for how procedure calls are broken down.
  920. Concrete syntax:
  921. .. code-block:: nim
  922. proc hello*[T: SomeInteger](x: int = 3, y: float32): int {.inline.} = discard
  923. AST:
  924. .. code-block:: nim
  925. nnkProcDef(
  926. nnkPostfix(nnkIdent("*"), nnkIdent("hello")), # the exported proc name
  927. nnkEmpty(), # patterns for term rewriting in templates and macros (not procs)
  928. nnkGenericParams( # generic type parameters, like with type declaration
  929. nnkIdentDefs(
  930. nnkIdent("T"),
  931. nnkIdent("SomeInteger"),
  932. nnkEmpty()
  933. )
  934. ),
  935. nnkFormalParams(
  936. nnkIdent("int"), # the first FormalParam is the return type. nnkEmpty() if there is none
  937. nnkIdentDefs(
  938. nnkIdent("x"),
  939. nnkIdent("int"), # type type (required for procs, not for templates)
  940. nnkIntLit(3) # a default value
  941. ),
  942. nnkIdentDefs(
  943. nnkIdent("y"),
  944. nnkIdent("float32"),
  945. nnkEmpty()
  946. )
  947. ),
  948. nnkPragma(nnkIdent("inline")),
  949. nnkEmpty(), # reserved slot for future use
  950. nnkStmtList(nnkDiscardStmt(nnkEmpty())) # the meat of the proc
  951. )
  952. There is another consideration. Nim has flexible type identification for
  953. its procs. Even though ``proc(a: int, b: int)`` and ``proc(a, b: int)``
  954. are equivalent in the code, the AST is a little different for the latter.
  955. Concrete syntax:
  956. .. code-block:: nim
  957. proc(a, b: int)
  958. AST:
  959. .. code-block:: nim
  960. # ...AST as above...
  961. nnkFormalParams(
  962. nnkEmpty(), # no return here
  963. nnkIdentDefs(
  964. nnkIdent("a"), # the first parameter
  965. nnkIdent("b"), # directly to the second parameter
  966. nnkIdent("int"), # their shared type identifier
  967. nnkEmpty(), # default value would go here
  968. )
  969. ),
  970. # ...
  971. When a procedure uses the special ``var`` type return variable, the result
  972. is different from that of a var section.
  973. Concrete syntax:
  974. .. code-block:: nim
  975. proc hello(): var int
  976. AST:
  977. .. code-block:: nim
  978. # ...
  979. nnkFormalParams(
  980. nnkVarTy(
  981. nnkIdent("int")
  982. )
  983. )
  984. Iterator declaration
  985. --------------------
  986. The syntax for iterators is similar to procs, but with ``nnkIteratorDef``
  987. replacing ``nnkProcDef``.
  988. Concrete syntax:
  989. .. code-block:: nim
  990. iterator nonsense[T](x: seq[T]): float {.closure.} = ...
  991. AST:
  992. .. code-block:: nim
  993. nnkIteratorDef(
  994. nnkIdent("nonsense"),
  995. nnkEmpty(),
  996. ...
  997. )
  998. Converter declaration
  999. ---------------------
  1000. A converter is similar to a proc.
  1001. Concrete syntax:
  1002. .. code-block:: nim
  1003. converter toBool(x: float): bool
  1004. AST:
  1005. .. code-block:: nim
  1006. nnkConverterDef(
  1007. nnkIdent("toBool"),
  1008. # ...
  1009. )
  1010. Template declaration
  1011. --------------------
  1012. Templates (as well as macros, as we'll see) have a slightly expanded AST when
  1013. compared to procs and iterators. The reason for this is [term-rewriting
  1014. macros](manual.html#term-rewriting-macros). Notice
  1015. the ``nnkEmpty()`` as the second argument to ``nnkProcDef`` and
  1016. ``nnkIteratorDef`` above? That's where the term-rewriting macros go.
  1017. Concrete syntax:
  1018. .. code-block:: nim
  1019. template optOpt{expr1}(a: int): int
  1020. AST:
  1021. .. code-block:: nim
  1022. nnkTemplateDef(
  1023. nnkIdent("optOpt"),
  1024. nnkStmtList( # instead of nnkEmpty()
  1025. expr1
  1026. ),
  1027. # follows like a proc or iterator
  1028. )
  1029. If the template does not have types for its parameters, the type identifiers
  1030. inside ``nnkFormalParams`` just becomes ``nnkEmpty``.
  1031. Macro declaration
  1032. -----------------
  1033. Macros behave like templates, but ``nnkTemplateDef`` is replaced with
  1034. ``nnkMacroDef``.
  1035. Hidden Standard Conversion
  1036. --------------------------
  1037. .. code-block:: nim
  1038. var f: float = 1
  1039. The type of "f" is ``float`` but the type of "1" is actually ``int``. Inserting
  1040. ``int`` into a ``float`` is a type error. Nim inserts the ``nnkHiddenStdConv``
  1041. node around the ``nnkIntLit`` node so that the new node has the correct type of
  1042. ``float``. This works for any auto converted nodes and makes the conversion
  1043. explicit.
  1044. Special node kinds
  1045. ==================
  1046. There are several node kinds that are used for semantic checking or code
  1047. generation. These are accessible from this module, but should not be used.
  1048. Other node kinds are especially designed to make AST manipulations easier.
  1049. These are explained here.
  1050. To be written.