astspec.txt 27 KB

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