mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-31 18:32:11 +00:00
Merge branch 'master' of github.com:Araq/Nimrod
This commit is contained in:
@@ -112,7 +112,7 @@ proc `[]`*(n: PNimrodNode, i: int): PNimrodNode {.magic: "NChild".}
|
||||
proc `[]=`*(n: PNimrodNode, i: int, child: PNimrodNode) {.magic: "NSetChild".}
|
||||
## set `n`'s `i`'th child to `child`.
|
||||
|
||||
proc `!`*(s: string): TNimrodIdent {.magic: "StrToIdent".}
|
||||
proc `!`*(s: string): TNimrodIdent {.magic: "StrToIdent", deprecated.}
|
||||
## constructs an identifier from the string `s`
|
||||
|
||||
proc `$`*(i: TNimrodIdent): string {.magic: "IdentToStr".}
|
||||
@@ -410,3 +410,240 @@ macro dumpTreeImm*(s: stmt): stmt {.immediate.} = echo s.treeRepr
|
||||
macro dumpLispImm*(s: stmt): stmt {.immediate.} = echo s.lispRepr
|
||||
## The ``immediate`` version of `dumpLisp`.
|
||||
|
||||
|
||||
proc newEmptyNode*(): PNimrodNode {.compileTime, noSideEffect.} =
|
||||
## Create a new empty node
|
||||
result = newNimNode(nnkEmpty)
|
||||
|
||||
proc newStmtList*(stmts: varargs[PNimrodNode]): PNimrodNode {.compileTime.}=
|
||||
## Create a new statement list
|
||||
result = newNimNode(nnkStmtList).add(stmts)
|
||||
|
||||
proc newBlockStmt*(label: PNimrodNode; body: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
## Create a new block statement with label
|
||||
return newNimNode(nnkBlockStmt).add(label, body)
|
||||
proc newBlockStmt*(body: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||
## Create a new block: stmt
|
||||
return newNimNode(nnkBlockStmt).add(newEmptyNode(), body)
|
||||
|
||||
proc newLetStmt*(name, value: PNimrodNode): PNimrodNode{.compiletime.} =
|
||||
## Create a new let stmt
|
||||
return newNimNode(nnkLetSection).add(
|
||||
newNimNode(nnkIdentDefs).add(name, newNimNode(nnkEmpty), value))
|
||||
|
||||
proc newAssignment*(lhs, rhs: PNimrodNode): PNimrodNode {.compileTime, inline.} =
|
||||
return newNimNode(nnkAsgn).add(lhs, rhs)
|
||||
|
||||
proc newDotExpr* (a, b: PNimrodNode): PNimrodNode {.compileTime, inline.} =
|
||||
## Create new dot expression
|
||||
## a.dot(b) -> `a.b`
|
||||
return newNimNode(nnkDotExpr).add(a, b)
|
||||
|
||||
|
||||
proc newIdentDefs*(name, kind: PNimrodNode; default = newEmptyNode()): PNimrodNode{.
|
||||
compileTime.} = newNimNode(nnkIdentDefs).add(name, kind, default)
|
||||
|
||||
proc newNilLit*(): PNimrodNode {.compileTime.} =
|
||||
## New nil literal shortcut
|
||||
result = newNimNode(nnkNilLit)
|
||||
|
||||
|
||||
proc high*(node: PNimrodNode): int {.compileTime.} = len(node) - 1
|
||||
## Return the highest index available for a node
|
||||
proc last*(node: PNimrodNode): PNimrodNode {.compileTime.} = node[node.high]
|
||||
## Return the last item in nodes children. Same as `node[node.high()]`
|
||||
|
||||
|
||||
const
|
||||
RoutineNodes* = {
|
||||
nnkProcDef, nnkMethodDef, nnkDo, nnkLambda }
|
||||
AtomicNodes* = {
|
||||
nnkNone .. nnkNilLit }
|
||||
CallNodes* = {
|
||||
nnkCall, nnkInfix, nnkPrefix, nnkPostfix, nnkCommand,
|
||||
nnkCallStrLit, nnkHiddenCallConv}
|
||||
|
||||
|
||||
from strutils import cmpIgnoreStyle, format
|
||||
|
||||
proc ExpectKind*(n: PNimrodNode; k: set[TNimrodNodeKind]) {.compileTime.} =
|
||||
assert n.kind in k, "Expected one of $1, got $2".format(k, n.kind)
|
||||
|
||||
proc newProc*(name = newEmptyNode(); params: openarray[PNimrodNode] = [];
|
||||
body: PNimrodNode = newStmtList(), procType = nnkProcDef): PNimrodNode {.compileTime.} =
|
||||
## shortcut for creating a new proc
|
||||
assert procType in RoutineNodes
|
||||
result = newNimNode(procType).add(
|
||||
name,
|
||||
newEmptyNode(),
|
||||
newEmptyNode(),
|
||||
newNimNode(nnkFormalParams).add(params), ##params
|
||||
newEmptyNode(), ## pragmas
|
||||
newEmptyNode(),
|
||||
body)
|
||||
|
||||
proc copyChildrenTo*(src, dest: PNimrodNode) {.compileTime.}=
|
||||
## Copy all children from `src` to `dest`
|
||||
for i in 0 .. < src.len:
|
||||
dest.add src[i].copyNimTree
|
||||
|
||||
template expectRoutine(node: PNimrodNode): stmt =
|
||||
expectKind(node, routineNodes)
|
||||
|
||||
proc name*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
someProc.expectRoutine
|
||||
result = someProc[0]
|
||||
proc `name=`*(someProc: PNimrodNode; val: PNimrodNode) {.compileTime.} =
|
||||
someProc.expectRoutine
|
||||
someProc[0] = val
|
||||
|
||||
proc params*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
someProc.expectRoutine
|
||||
result = someProc[3]
|
||||
proc `params=`* (someProc: PNimrodNode; params: PNimrodNode) {.compileTime.}=
|
||||
someProc.expectRoutine
|
||||
assert params.kind == nnkFormalParams
|
||||
someProc[3] = params
|
||||
|
||||
proc pragma*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
## Get the pragma of a proc type
|
||||
## These will be expanded
|
||||
someProc.expectRoutine
|
||||
result = someProc[4]
|
||||
proc `pragma=`*(someProc: PNimrodNode; val: PNimrodNode){.compileTime.}=
|
||||
## Set the pragma of a proc type
|
||||
someProc.expectRoutine
|
||||
assert val.kind in {nnkEmpty, nnkPragma}
|
||||
someProc[4] = val
|
||||
|
||||
|
||||
template badnodekind(k; f): stmt{.immediate.} =
|
||||
assert false, "Invalid node kind $# for macros.`$2`".format(k, f)
|
||||
|
||||
proc body*(someProc: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
case someProc.kind:
|
||||
of routineNodes:
|
||||
return someProc[6]
|
||||
of nnkBlockStmt, nnkWhileStmt:
|
||||
return someproc[1]
|
||||
of nnkForStmt:
|
||||
return someProc.last
|
||||
else:
|
||||
badNodeKind someproc.kind, "body"
|
||||
|
||||
proc `body=`*(someProc: PNimrodNode, val: PNimrodNode) {.compileTime.} =
|
||||
case someProc.kind
|
||||
of routineNodes:
|
||||
someProc[6] = val
|
||||
of nnkBlockStmt, nnkWhileStmt:
|
||||
someProc[1] = val
|
||||
of nnkForStmt:
|
||||
someProc[high(someProc)] = val
|
||||
else:
|
||||
badNodeKind someProc.kind, "body="
|
||||
|
||||
|
||||
proc `$`*(node: PNimrodNode): string {.compileTime.} =
|
||||
## Get the string of an identifier node
|
||||
case node.kind
|
||||
of nnkIdent:
|
||||
result = $node.ident
|
||||
of nnkStrLit:
|
||||
result = node.strval
|
||||
else:
|
||||
badNodeKind node.kind, "$"
|
||||
|
||||
proc ident*(name: string): PNimrodNode {.compileTime,inline.} = newIdentNode(name)
|
||||
## Create a new ident node from a string
|
||||
|
||||
iterator children*(n: PNimrodNode): PNimrodNode {.inline.}=
|
||||
for i in 0 .. high(n):
|
||||
yield n[i]
|
||||
|
||||
template findChild*(n: PNimrodNode; cond: expr): PNimrodNode {.immediate, dirty.} =
|
||||
## Find the first child node matching condition (or nil)
|
||||
## var res = findChild(n, it.kind == nnkPostfix and it.basename.ident == !"foo")
|
||||
|
||||
block:
|
||||
var result: PNimrodNode
|
||||
for it in n.children:
|
||||
if cond:
|
||||
result = it
|
||||
break
|
||||
result
|
||||
|
||||
proc insert*(a: PNimrodNOde; pos: int; b: PNimrodNode) {.compileTime.} =
|
||||
## Insert node B into A at pos
|
||||
if high(a) < pos:
|
||||
## add some empty nodes first
|
||||
for i in high(a)..pos-2:
|
||||
a.add newEmptyNode()
|
||||
a.add b
|
||||
else:
|
||||
## push the last item onto the list again
|
||||
## and shift each item down to pos up one
|
||||
a.add(a[a.high])
|
||||
for i in countdown(high(a) - 2, pos):
|
||||
a[i + 1] = a[i]
|
||||
a[pos] = b
|
||||
|
||||
proc basename*(a: PNimrodNode): PNimrodNode {.compiletime.} =
|
||||
## Pull an identifier from prefix/postfix expressions
|
||||
case a.kind
|
||||
of nnkIdent: return a
|
||||
of nnkPostfix, nnkPrefix: return a[1]
|
||||
else:
|
||||
quit "Do not know how to get basename of ("& treerepr(a) &")\n"& repr(a)
|
||||
proc `basename=`*(a: PNimrodNode; val: string) {.compileTime.}=
|
||||
case a.kind
|
||||
of nnkIdent: macros.`ident=`(a, !val)
|
||||
of nnkPostfix, nnkPrefix: a[1] = ident(val)
|
||||
else:
|
||||
quit "Do not know how to get basename of ("& treerepr(a)& ")\n"& repr(a)
|
||||
|
||||
proc postfix*(node: PNimrodNode; op: string): PNimrodNode {.
|
||||
compileTime.} = newNimNode(nnkPostfix).add(ident(op), node)
|
||||
proc prefix*(node: PNimrodNode; op: string): PNimrodNode {.
|
||||
compileTime.} = newNimNode(nnkPrefix).add(ident(op), node)
|
||||
proc infix*(a: PNimrodNode; op: string; b: PNimrodNode): PNimrodNode {.
|
||||
compileTime.} = newNimNode(nnkInfix).add(ident(op), a, b)
|
||||
|
||||
proc unpackPostfix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
|
||||
compileTime.} =
|
||||
node.expectKind nnkPostfix
|
||||
result = (node[0], $node[1])
|
||||
proc unpackPrefix*(node: PNimrodNode): tuple[node: PNimrodNode; op: string] {.
|
||||
compileTime.} =
|
||||
node.expectKind nnkPrefix
|
||||
result = (node[0], $node[1])
|
||||
proc unpackInfix*(node: PNimrodNode): tuple[left: PNimrodNode; op: string; right: PNimrodNode] {.
|
||||
compileTime.} =
|
||||
assert node.kind == nnkInfix
|
||||
result = (node[0], $node[1], node[2])
|
||||
|
||||
proc copy*(node: PNimrodNode): PNimrodNode {.compileTime.} =
|
||||
## An alias for copyNimTree()
|
||||
return node.copyNimTree()
|
||||
|
||||
proc eqIdent* (a, b: string): bool = cmpIgnoreStyle(a, b) == 0
|
||||
## Check if two idents are identical
|
||||
|
||||
proc hasArgOfName* (params: PNimrodNode; name: string): bool {.compiletime.}=
|
||||
## Search nnkFormalParams for an argument
|
||||
assert params.kind == nnkFormalParams
|
||||
for i in 1 .. <params.len:
|
||||
template node: expr = params[i]
|
||||
if name.eqIdent( $ node[0]):
|
||||
return true
|
||||
|
||||
proc addIdentIfAbsent* (dest: PNimrodNode, ident: string) {.compiletime.} =
|
||||
## Add ident to dest if it is not present. This is intended for use with pragmas
|
||||
for node in dest.children:
|
||||
case node.kind
|
||||
of nnkIdent:
|
||||
if ident.eqIdent($node): return
|
||||
of nnkExprColonExpr:
|
||||
if ident.eqIdent($ node[0]): return
|
||||
else: nil
|
||||
dest.add(ident(ident))
|
||||
|
||||
|
||||
@@ -6,5 +6,47 @@ Wiki: http://github.com/Araq/Nimrod/wiki.
|
||||
|
||||
Bug reports: http://github.com/Araq/Nimrod/issues.
|
||||
|
||||
For quickest feedback, join our IRC channel: irc://freenode/nimrod
|
||||
For quickest feedback, join our IRC channel: irc://irc.freenode.net/nimrod
|
||||
|
||||
How to help
|
||||
===========
|
||||
|
||||
There are always many things to be done in the main
|
||||
`Nimrod repository <https://github.com/Araq/Nimrod>`_, check out the
|
||||
`issues <https://github.com/Araq/Nimrod/issues>`_ for
|
||||
things to do; pull requests are always welcome. You can
|
||||
also contribute to the many other projects hosted by the
|
||||
`nimrod-code <https://github.com/nimrod-code>`_ organisation on github. If you
|
||||
can't find anything you fancy doing, you can always ask for inspiration on IRC
|
||||
(irc.freenode.net #nimrod) or on the `Nimrod forums <http://forum.nimrod-code.org>`_.
|
||||
|
||||
Donations
|
||||
---------
|
||||
|
||||
If you love what we do and are feeling generous then you can always donate:
|
||||
|
||||
Gittip
|
||||
``````
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<iframe style="border: 0; margin: 0; padding: 0;"
|
||||
src="https://www.gittip.com/Araq/widget.html"
|
||||
width="48pt" height="22pt"></iframe>
|
||||
|
||||
Paypal
|
||||
``````
|
||||
|
||||
.. raw:: html
|
||||
|
||||
<form action="https://www.paypal.com/cgi-bin/webscr" method="post" target="_top">
|
||||
<input type="hidden" name="cmd" value="_s-xclick">
|
||||
<input type="hidden" name="hosted_button_id" value="ZQC6CVEEYNTLN">
|
||||
<input type="image" src="https://www.paypalobjects.com/en_US/i/btn/btn_donateCC_LG.gif" border="0" name="submit" alt="PayPal - The safer, easier way to pay online!">
|
||||
<img alt="" border="0" src="https://www.paypalobjects.com/de_DE/i/scr/pixel.gif" width="1" height="1">
|
||||
</form>
|
||||
|
||||
Bitcoin
|
||||
```````
|
||||
|
||||
Bitcoin address: 1BXfuKM2uvoD6mbx4g5xM3eQhLzkCK77tJ
|
||||
19
web/news.txt
19
web/news.txt
@@ -2,7 +2,7 @@
|
||||
News
|
||||
====
|
||||
|
||||
New website design!
|
||||
2013-05-20 New website design!
|
||||
===================
|
||||
|
||||
A brand new website is now live. All thanks go to Philip Witte and
|
||||
@@ -15,7 +15,22 @@ agree that Philip's design is beautiful.
|
||||
2013-05-20 Version 0.9.2 released
|
||||
=================================
|
||||
|
||||
Version 0.9.2 has been released! Get it `here <download.html>`_.
|
||||
We are pleased to announce that version 0.9.2 of the Nimrod compiler has been
|
||||
released. This release has attracted by far the most contributions in comparison
|
||||
to any other release.
|
||||
|
||||
This release can be downloaded from `here <download.html>`_.
|
||||
|
||||
This release brings with it many new features and bug fixes, a list of which
|
||||
can be seen later. One of the major new features is the effect system together
|
||||
with exception tracking which allows for checked exceptions and more,
|
||||
for further details check out the `manual <manual.html#effect-system>`_.
|
||||
Another major new feature is the introduction of statement list expressions,
|
||||
more details on these can be found `here <manual.html#statement-list-expression>`_.
|
||||
The ability to exclude symbols from modules has also been
|
||||
implemented, this feature can be used like so: ``import module except symbol``.
|
||||
|
||||
Thanks to all `contributors <https://github.com/Araq/Nimrod/contributors>`_!
|
||||
|
||||
Bugfixes
|
||||
--------
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
<a class="news" href="news.html#new-website-design">
|
||||
<h3>May 20, 2013</h3>
|
||||
<p>New website design!</p>
|
||||
</a>
|
||||
|
||||
<a class="news" href="news.html#Z2013-05-20-version-0-9-2-released">
|
||||
<h3>May 20, 2013</h3>
|
||||
<p>Nimrod version 0.9.2 has been released!</p>
|
||||
|
||||
Reference in New Issue
Block a user