astspec.txt 28 KB

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