Skip to content

Commit

Permalink
Merge branch 'devel' of https://github.com/Araq/Nimrod into devel
Browse files Browse the repository at this point in the history
  • Loading branch information
Araq committed Apr 20, 2014
2 parents e3fab47 + 5cf8c05 commit 2c97242
Show file tree
Hide file tree
Showing 13 changed files with 373 additions and 63 deletions.
2 changes: 1 addition & 1 deletion compiler/semfold.nim
Original file line number Diff line number Diff line change
Expand Up @@ -404,7 +404,7 @@ proc evalOp(m: TMagic, n, a, b, c: PNode): PNode =
mExit, mInc, ast.mDec, mEcho, mSwap, mAppendStrCh,
mAppendStrStr, mAppendSeqElem, mSetLengthStr, mSetLengthSeq,
mParseExprToAst, mParseStmtToAst, mExpandToAst, mTypeTrait,
mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym:
mNLen..mNError, mEqRef, mSlurp, mStaticExec, mNGenSym, mSpawn:
discard
of mRand:
result = newIntNodeT(math.random(a.getInt.int), n)
Expand Down
1 change: 1 addition & 0 deletions compiler/suggest.nim
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,7 @@ proc findUsages(node: PNode, s: PSym) =
lastLineInfo = node.info

proc findDefinition(node: PNode, s: PSym) =
if node.isNil or s.isNil: return
if isTracked(node.info, s.name.s.len):
suggestWriteln(symToStr(s, isLocal=false, sectionDef))
suggestQuit()
Expand Down
8 changes: 7 additions & 1 deletion compiler/vm.nim
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,11 @@ template handleJmpBack() {.dirty.} =
globalError(c.debug[pc], errTooManyIterations)
dec(c.loopIterations)

proc skipColon(n: PNode): PNode =
result = n
if n.kind == nkExprColonExpr:
result = n.sons[1]

proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
var pc = start
var tos = tos
Expand Down Expand Up @@ -454,7 +459,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
decodeBC(rkNode)
let src = regs[rb].node
if src.kind notin {nkEmpty..nkNilLit}:
let n = src.sons[rc]
let n = src.sons[rc].skipColon
regs[ra].node = n
else:
stackTrace(c, tos, pc, errNilAccess)
Expand Down Expand Up @@ -1099,6 +1104,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): TFullReg =
c.module)
of opcGorge:
decodeBC(rkNode)
createStr regs[ra]
regs[ra].node.strVal = opGorge(regs[rb].node.strVal,
regs[rc].node.strVal)
of opcNError:
Expand Down
20 changes: 11 additions & 9 deletions compiler/vmgen.nim
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,9 @@ proc echoCode*(c: PCtx, start=0) {.deprecated.} =
echo buf

proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
## Takes the registers `b` and `c`, applies the operation `opc` to them, and
## stores the result into register `a`
## The node is needed for debug information
assert opc.ord < 255
let ins = (opc.uint32 or (a.uint32 shl 8'u32) or
(b.uint32 shl 16'u32) or
Expand All @@ -78,13 +81,20 @@ proc gABC(ctx: PCtx; n: PNode; opc: TOpcode; a, b, c: TRegister = 0) =
ctx.debug.add(n.info)

proc gABI(c: PCtx; n: PNode; opc: TOpcode; a, b: TRegister; imm: BiggestInt) =
# Takes the `b` register and the immediate `imm`, appies the operation `opc`,
# and stores the output value into `a`.
# `imm` is signed and must be within [-127, 128]
assert(imm >= -127 and imm <= 128)
let ins = (opc.uint32 or (a.uint32 shl 8'u32) or
(b.uint32 shl 16'u32) or
(imm+byteExcess).uint32 shl 24'u32).TInstr
c.code.add(ins)
c.debug.add(n.info)

proc gABx(c: PCtx; n: PNode; opc: TOpcode; a: TRegister = 0; bx: int) =
# Applies `opc` to `bx` and stores it into register `a`
# `bx` must be signed and in the range [-32767, 32768]
assert(bx >= -32767 and bx <= 32768)
let ins = (opc.uint32 or a.uint32 shl 8'u32 or
(bx+wordExcess).uint32 shl 16'u32).TInstr
c.code.add(ins)
Expand Down Expand Up @@ -316,15 +326,7 @@ proc genAndOr(c: PCtx; n: PNode; opc: TOpcode; dest: var TDest) =
c.patch(L1)

proc canonValue*(n: PNode): PNode =
if n.kind == nkExprColonExpr:
result = n.sons[1]
elif n.hasSubnodeWith(nkExprColonExpr):
result = n.copyNode
newSeq(result.sons, n.len)
for i in 0.. <n.len:
result.sons[i] = canonValue(n.sons[i])
else:
result = n
result = n

proc rawGenLiteral(c: PCtx; n: PNode): int =
result = c.constants.len
Expand Down
74 changes: 54 additions & 20 deletions doc/tut1.txt
Original file line number Diff line number Diff line change
Expand Up @@ -132,7 +132,7 @@ a backslash:
TMyObject {.final, pure, acyclic.} = object # comment continues: \
# we have lots of space here to comment 'TMyObject'.
# This line belongs to the comment as it's properly aligned.


Comments are tokens; they are only allowed at certain places in the input file
as they belong to the syntax tree! This feature enables perfect source-to-source
Expand All @@ -150,6 +150,18 @@ the syntax, watch their indentation:
**Note**: To comment out a large piece of code, it is often better to use a
``when false:`` statement.

.. code-block:: nimrod
when false:
brokenCode()

Another option is to use the `discard`_ statement together with
*long string literals* to create block comments:

.. code-block:: nimrod
discard """ You can have any nimrod code text commented
out inside this with no indentation restrictions.
yes("May I ask a pointless question?") """


Numbers
-------
Expand Down Expand Up @@ -575,27 +587,46 @@ Some terminology: in the example ``question`` is called a (formal) *parameter*,

Result variable
---------------
A procedure that returns a value has an implicit ``result`` variable that
represents the return value. A ``return`` statement with no expression is a
shorthand for ``return result``. So all three code snippets are equivalent:

.. code-block:: nimrod
return 42

.. code-block:: nimrod
result = 42
return

.. code-block:: nimrod
result = 42
return result


A procedure that returns a value has an implicit ``result`` variable declared
that represents the return value. A ``return`` statement with no expression is a
shorthand for ``return result``. The ``result`` value is always returned
automatically at the end a procedure if there is no ``return`` statement at
the exit.

.. code-block:: nimrod
proc sumTillNegative(x: varargs[int]): int =
for i in x:
if i < 0:
return
result = result + i

echo sumTillNegative() # echos 0
echo sumTillNegative(3, 4, 5) # echos 12
echo sumTillNegative(3, 4 , -1 , 6) # echos 7

The ``result`` variable is already implicitly declared at the start of the
function, so declaring it again with 'var result', for example, would shadow it
with a normal variable of the same name. The result variable is also already
initialised with the type's default value. Note that referential data types will
be ``nil`` at the start of the procedure, and thus may require manual
initialisation.


Parameters
----------
Parameters are constant in the procedure body. Their value cannot be changed
because this allows the compiler to implement parameter passing in the most
efficient way. If the procedure needs to modify the argument for the
Parameters are constant in the procedure body. By default, their value cannot be
changed because this allows the compiler to implement parameter passing in the
most efficient way. If a mutable variable is needed inside the procedure, it has
to be declared with ``var`` in the procedure body. Shadowing the parameter name
is possible, and actually an idiom:

.. code-block:: nimrod
proc printSeq(s: seq, nprinted: int = -1) =
var nprinted = if nprinted == -1: s.len else: min(nprinted, s.len)
for i in 0 .. <nprinted:
echo s[i]

If the procedure needs to modify the argument for the
caller, a ``var`` parameter can be used:

.. code-block:: nimrod
Expand Down Expand Up @@ -634,6 +665,9 @@ been declared with the ``discardable`` pragma:

p(3, 4) # now valid

The discard statement can also be used to create block comments as described
in the `Comments`_.


Named arguments
---------------
Expand Down
15 changes: 11 additions & 4 deletions lib/pure/future.nim
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,15 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
for i in 0 .. <p.len:
let ident = p[i]
var identDefs = newNimNode(nnkIdentDefs)
identDefs.add newIdentNode("i" & $i)
identDefs.add(ident)
case ident.kind
of nnkExprColonExpr:
identDefs.add ident[0]
identDefs.add ident[1]
of nnkIdent:
identDefs.add newIdentNode("i" & $i)
identDefs.add(ident)
else:
error("Incorrect type list in proc type declaration.")
identDefs.add newEmptyNode()
formalParams.add identDefs
of nnkIdent:
Expand All @@ -47,7 +54,7 @@ proc createProcType(p, b: PNimrodNode): PNimrodNode {.compileTime.} =
macro `=>`*(p, b: expr): expr {.immediate.} =
## Syntax sugar for anonymous procedures.
##
## ..code-block:: nimrod
## .. code-block:: nimrod
##
## proc passTwoAndTwo(f: (int, int) -> int): int =
## f(2, 2)
Expand Down Expand Up @@ -98,7 +105,7 @@ macro `=>`*(p, b: expr): expr {.immediate.} =
macro `->`*(p, b: expr): expr {.immediate.} =
## Syntax sugar for procedure types.
##
## ..code-block:: nimrod
## .. code-block:: nimrod
##
## proc pass2(f: (float, float) -> float): float =
## f(2, 2)
Expand Down
Loading

0 comments on commit 2c97242

Please sign in to comment.