version 0.8.6

This commit is contained in:
Andreas Rumpf 2009-12-22 01:28:20 +01:00
commit 2169fd63bd
34 changed files with 748 additions and 776 deletions

3
contributors.txt Normal file → Executable file
View file

@ -1,4 +1,5 @@
Mario Ray Mahardhika Mario Ray Mahardhika
Philippe Lhoste Philippe Lhoste
Alexander R¿dseth Alexander Rødseth
Jonathan Plona Jonathan Plona

View file

@ -1111,7 +1111,7 @@ algorithm (in pseudo-code) determines type equality:
.. code-block:: nimrod .. code-block:: nimrod
proc typeEqualsAux(a, b: PType, proc typeEqualsAux(a, b: PType,
s: var set[tuple[PType, PType]]): bool = s: var set[PType * PType]): bool =
if (a,b) in s: return true if (a,b) in s: return true
incl(s, (a,b)) incl(s, (a,b))
if a.kind == b.kind: if a.kind == b.kind:
@ -1140,7 +1140,7 @@ algorithm (in pseudo-code) determines type equality:
a.callingConvention == b.callingConvention a.callingConvention == b.callingConvention
proc typeEquals(a, b: PType): bool = proc typeEquals(a, b: PType): bool =
var s: set[tuple[PType, PType]] = {} var s: set[PType * PType] = {}
result = typeEqualsAux(a, b, s) result = typeEqualsAux(a, b, s)
Since types are graphs which can have cycles, the above algorithm needs an Since types are graphs which can have cycles, the above algorithm needs an
@ -1216,8 +1216,8 @@ algorithm returns true:
return false return false
Assignment compability Assignment compatibility
~~~~~~~~~~~~~~~~~~~~~~ ~~~~~~~~~~~~~~~~~~~~~~~~
An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an An expression ``b`` can be assigned to an expression ``a`` iff ``a`` is an
`l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds. `l-value` and ``isImplicitlyConvertible(b.typ, a.typ)`` holds.
@ -1727,23 +1727,26 @@ Procedures
What most programming languages call `methods`:idx: or `functions`:idx: are What most programming languages call `methods`:idx: or `functions`:idx: are
called `procedures`:idx: in Nimrod (which is the correct terminology). A called `procedures`:idx: in Nimrod (which is the correct terminology). A
procedure declaration defines an identifier and associates it with a block procedure declaration defines an identifier and associates it with a block
of code. A procedure may call itself recursively. The syntax is:: of code.
A procedure may call itself recursively. A parameter may be given a default
value that is used if the caller does not provide a value for this parameter.
The syntax is::
param ::= symbol (comma symbol)* [comma] ':' typeDesc param ::= symbol (comma symbol)* (':' typeDesc ['=' expr] | '=' expr)
paramList ::= ['(' [param (comma param)* [comma]] ')'] [':' typeDesc] paramList ::= ['(' [param (comma param)*] optPar ')'] [':' typeDesc]
genericParam ::= symbol [':' typeDesc] genericParam ::= symbol [':' typeDesc] ['=' expr]
genericParams ::= '[' genericParam (comma genericParam)* [comma] ']' genericParams ::= '[' genericParam (comma genericParam)* optPar ']'
routineDecl := symbol ['*'] [genericParams] paramList [pragma] ['=' stmt]
procDecl ::= 'proc' routineDecl
procDecl ::= 'proc' symbol ['*'] [genericParams] paramList [pragma]
['=' stmt]
If the ``= stmt`` part is missing, it is a `forward`:idx: declaration. If If the ``= stmt`` part is missing, it is a `forward`:idx: declaration. If
the proc returns a value, the procedure body can access an implicit declared the proc returns a value, the procedure body can access an implicitly declared
variable named `result`:idx: that represents the return value. Procs can be variable named `result`:idx: that represents the return value. Procs can be
overloaded. The overloading resolution algorithm tries to find the proc that is overloaded. The overloading resolution algorithm tries to find the proc that is
the best match for the arguments. A parameter may be given a default value that the best match for the arguments. Example:
is used if the caller does not provide a value for this parameter. Example:
.. code-block:: nimrod .. code-block:: nimrod
@ -1785,7 +1788,7 @@ type `var`).
Operators with one parameter are prefix operators, operators with two Operators with one parameter are prefix operators, operators with two
parameters are infix operators. (However, the parser distinguishes these from parameters are infix operators. (However, the parser distinguishes these from
the operators position within an expression.) There is no way to declare the operator's position within an expression.) There is no way to declare
postfix operators: all postfix operators are built-in and handled by the postfix operators: all postfix operators are built-in and handled by the
grammar explicitly. grammar explicitly.

File diff suppressed because it is too large Load diff

View file

@ -79,7 +79,6 @@ const
bootOptions = "" # options to pass to the bootstrap process bootOptions = "" # options to pass to the bootstrap process
proc findStartNimrod: string = proc findStartNimrod: string =
const buildScript = "build.sh"
# we try several things before giving up: # we try several things before giving up:
# * bin/nimrod # * bin/nimrod
# * $PATH/nimrod # * $PATH/nimrod
@ -95,6 +94,7 @@ proc findStartNimrod: string =
result = "bin" / "nim".exe result = "bin" / "nim".exe
if ExistsFile(result): return if ExistsFile(result): return
when defined(Posix): when defined(Posix):
const buildScript = "build.sh"
if ExistsFile(buildScript): if ExistsFile(buildScript):
if tryExec("./" & buildScript): return "bin" / nimrod if tryExec("./" & buildScript): return "bin" / nimrod
@ -102,16 +102,20 @@ proc findStartNimrod: string =
echo("Found no nimrod compiler and every attempt to build one failed!") echo("Found no nimrod compiler and every attempt to build one failed!")
quit("FAILURE") quit("FAILURE")
proc safeRemove(filename: string) =
if existsFile(filename): removeFile(filename)
proc bootIteration(args: string): bool = proc bootIteration(args: string): bool =
var nimrod1 = "rod" / "nimrod1".exe var nimrod1 = "rod" / "nimrod1".exe
moveFile nimrod1, "rod" / "nimrod".exe safeRemove(nimrod1)
moveFile(nimrod1, "rod" / "nimrod".exe)
exec "rod" / "nimrod1 cc $# $# rod/nimrod.nim" % [bootOptions, args] exec "rod" / "nimrod1 cc $# $# rod/nimrod.nim" % [bootOptions, args]
# Nimrod does not produce an executable again if nothing changed. That's ok: # Nimrod does not produce an executable again if nothing changed. That's ok:
result = sameFileContent("rod" / "nimrod".exe, nimrod1) result = sameFileContent("rod" / "nimrod".exe, nimrod1)
if result: safeRemove("bin" / "nimrod".exe)
moveFile "bin" / "nimrod".exe, "rod" / "nimrod".exe copyFile("bin" / "nimrod".exe, "rod" / "nimrod".exe)
echo "executables are equal: SUCCESS!" safeRemove(nimrod1)
removeFile nimrod1 if result: echo "executables are equal: SUCCESS!"
proc boot(args: string) = proc boot(args: string) =
echo "iteration: 1" echo "iteration: 1"

View file

@ -370,6 +370,6 @@ proc getCookie*(name: string): string =
proc existsCookie*(name: string): bool = proc existsCookie*(name: string): bool =
## Checks if a cookie of `name` exists. ## Checks if a cookie of `name` exists.
if cookies == nil: cookies = parseCookies(getHttpCookie()) if cookies == nil: cookies = parseCookies(getHttpCookie())
result = hasKey(cookies) result = hasKey(cookies, name)

View file

@ -370,6 +370,7 @@ begin
while x <> nil do begin while x <> nil do begin
if sfResult in sym.flags then begin if sfResult in sym.flags then begin
result := x.params[0]; result := x.params[0];
if result = nil then result := emptyNode;
exit exit
end; end;
result := IdNodeTableGet(x.mapping, sym); result := IdNodeTableGet(x.mapping, sym);

7
rod/ast.nim Normal file → Executable file
View file

@ -355,8 +355,6 @@ type
sym*: PSym sym*: PSym
of nkIdent: of nkIdent:
ident*: PIdent ident*: PIdent
of nkMetaNode:
nodePtr*: PNodePtr
else: else:
sons*: TNodeSeq sons*: TNodeSeq
@ -885,7 +883,6 @@ proc copyNode(src: PNode): PNode =
of nkSym: result.sym = src.sym of nkSym: result.sym = src.sym
of nkIdent: result.ident = src.ident of nkIdent: result.ident = src.ident
of nkStrLit..nkTripleStrLit: result.strVal = src.strVal of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
of nkMetaNode: result.nodePtr = src.nodePtr
else: nil else: nil
proc copyTree(src: PNode): PNode = proc copyTree(src: PNode): PNode =
@ -902,7 +899,6 @@ proc copyTree(src: PNode): PNode =
of nkSym: result.sym = src.sym of nkSym: result.sym = src.sym
of nkIdent: result.ident = src.ident of nkIdent: result.ident = src.ident
of nkStrLit..nkTripleStrLit: result.strVal = src.strVal of nkStrLit..nkTripleStrLit: result.strVal = src.strVal
of nkMetaNode: result.nodePtr = src.nodePtr
else: else:
result.sons = nil result.sons = nil
newSons(result, sonsLen(src)) newSons(result, sonsLen(src))
@ -1018,8 +1014,7 @@ proc IntSetEnlarge(t: var TIntSet) =
swap(t.data, n) swap(t.data, n)
proc IntSetPut(t: var TIntSet, key: int): PTrunk = proc IntSetPut(t: var TIntSet, key: int): PTrunk =
var h: int var h = key and t.max
h = key and t.max
while t.data[h] != nil: while t.data[h] != nil:
if t.data[h].key == key: if t.data[h].key == key:
return t.data[h] return t.data[h]

0
rod/ccgexprs.nim Normal file → Executable file
View file

0
rod/cgen.nim Normal file → Executable file
View file

0
rod/condsyms.nim Normal file → Executable file
View file

209
rod/evals.nim Normal file → Executable file
View file

@ -84,7 +84,10 @@ proc stackTrace(c: PEvalContext, n: PNode, msg: TMsgKind, arg: string = "") =
liMessage(n.info, msg, arg) liMessage(n.info, msg, arg)
proc isSpecial(n: PNode): bool = proc isSpecial(n: PNode): bool =
result = (n.kind == nkExceptBranch) or (n.kind == nkEmpty) result = (n.kind == nkExceptBranch)
# or (n.kind == nkEmpty)
# XXX this does not work yet! Better to compile too much than to compile to
# few programs
proc evalIf(c: PEvalContext, n: PNode): PNode = proc evalIf(c: PEvalContext, n: PNode): PNode =
var i = 0 var i = 0
@ -131,7 +134,7 @@ proc evalWhile(c: PEvalContext, n: PNode): PNode =
if result.sons[0] == nil: if result.sons[0] == nil:
result = emptyNode # consume ``break`` token result = emptyNode # consume ``break`` token
break break
of nkExceptBranch, nkReturnToken, nkEmpty: of nkExceptBranch, nkReturnToken:
break break
else: else:
nil nil
@ -247,7 +250,7 @@ proc evalCall(c: PEvalContext, n: PNode): PNode =
if n.typ != nil: d.params[0] = getNullValue(n.typ, n.info) if n.typ != nil: d.params[0] = getNullValue(n.typ, n.info)
pushStackFrame(c, d) pushStackFrame(c, d)
result = evalAux(c, prc) result = evalAux(c, prc)
if isSpecial(result): return if result.kind == nkExceptBranch: return
if n.typ != nil: result = d.params[0] if n.typ != nil: result = d.params[0]
popStackFrame(c) popStackFrame(c)
@ -257,7 +260,9 @@ proc evalVariable(c: PStackFrame, sym: PSym): PNode =
var x = c var x = c
while x != nil: while x != nil:
if sfResult in sym.flags: if sfResult in sym.flags:
return x.params[0] result = x.params[0]
if result == nil: result = emptyNode
return
result = IdNodeTableGet(x.mapping, sym) result = IdNodeTableGet(x.mapping, sym)
if result != nil: return if result != nil: return
x = x.next x = x.next
@ -289,14 +294,11 @@ proc evalFieldAccess(c: PEvalContext, n: PNode): PNode =
# a real field access; proc calls have already been # a real field access; proc calls have already been
# transformed # transformed
# XXX: field checks! # XXX: field checks!
var
x: PNode
field: PSym
result = evalAux(c, n.sons[0]) result = evalAux(c, n.sons[0])
if isSpecial(result): return if isSpecial(result): return
x = result var x = result
if x.kind != nkPar: InternalError(n.info, "evalFieldAccess") if x.kind != nkPar: InternalError(n.info, "evalFieldAccess")
field = n.sons[1].sym var field = n.sons[1].sym
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
if x.sons[i].kind != nkExprColonExpr: if x.sons[i].kind != nkExprColonExpr:
InternalError(n.info, "evalFieldAccess") InternalError(n.info, "evalFieldAccess")
@ -306,10 +308,9 @@ proc evalFieldAccess(c: PEvalContext, n: PNode): PNode =
result = emptyNode result = emptyNode
proc evalAsgn(c: PEvalContext, n: PNode): PNode = proc evalAsgn(c: PEvalContext, n: PNode): PNode =
var x: PNode
result = evalAux(c, n.sons[0]) result = evalAux(c, n.sons[0])
if isSpecial(result): return if isSpecial(result): return
x = result var x = result
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
x.kind = result.kind x.kind = result.kind
@ -328,15 +329,9 @@ proc evalAsgn(c: PEvalContext, n: PNode): PNode =
result = emptyNode result = emptyNode
proc evalSwap(c: PEvalContext, n: PNode): PNode = proc evalSwap(c: PEvalContext, n: PNode): PNode =
var
x: PNode
tmpi: biggestInt
tmpf: biggestFloat
tmps: string
tmpn: PNode
result = evalAux(c, n.sons[0]) result = evalAux(c, n.sons[0])
if isSpecial(result): return if isSpecial(result): return
x = result var x = result
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
if (x.kind != result.kind): if (x.kind != result.kind):
@ -344,19 +339,19 @@ proc evalSwap(c: PEvalContext, n: PNode): PNode =
else: else:
case x.kind case x.kind
of nkCharLit..nkInt64Lit: of nkCharLit..nkInt64Lit:
tmpi = x.intVal var tmpi = x.intVal
x.intVal = result.intVal x.intVal = result.intVal
result.intVal = tmpi result.intVal = tmpi
of nkFloatLit..nkFloat64Lit: of nkFloatLit..nkFloat64Lit:
tmpf = x.floatVal var tmpf = x.floatVal
x.floatVal = result.floatVal x.floatVal = result.floatVal
result.floatVal = tmpf result.floatVal = tmpf
of nkStrLit..nkTripleStrLit: of nkStrLit..nkTripleStrLit:
tmps = x.strVal var tmps = x.strVal
x.strVal = result.strVal x.strVal = result.strVal
result.strVal = tmps result.strVal = tmps
else: else:
tmpn = copyTree(x) var tmpn = copyTree(x)
discardSons(x) discardSons(x)
for i in countup(0, sonsLen(result) - 1): addSon(x, result.sons[i]) for i in countup(0, sonsLen(result) - 1): addSon(x, result.sons[i])
discardSons(result) discardSons(result)
@ -375,13 +370,12 @@ proc evalSym(c: PEvalContext, n: PNode): PNode =
if result == nil: stackTrace(c, n, errCannotInterpretNodeX, n.sym.name.s) if result == nil: stackTrace(c, n, errCannotInterpretNodeX, n.sym.name.s)
proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode = proc evalIncDec(c: PEvalContext, n: PNode, sign: biggestInt): PNode =
var a, b: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
case a.kind case a.kind
of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b) of nkCharLit..nkInt64Lit: a.intval = a.intVal + sign * getOrdValue(b)
else: internalError(n.info, "evalIncDec") else: internalError(n.info, "evalIncDec")
@ -466,16 +460,15 @@ proc evalUpConv(c: PEvalContext, n: PNode): PNode =
stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src)) stackTrace(c, n, errInvalidConversionFromTypeX, typeToString(src))
proc evalRangeChck(c: PEvalContext, n: PNode): PNode = proc evalRangeChck(c: PEvalContext, n: PNode): PNode =
var x, a, b: PNode
result = evalAux(c, n.sons[0]) result = evalAux(c, n.sons[0])
if isSpecial(result): return if isSpecial(result): return
x = result var x = result
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
if leValueConv(a, x) and leValueConv(x, b): if leValueConv(a, x) and leValueConv(x, b):
result = x # a <= x and x <= b result = x # a <= x and x <= b
result.typ = n.typ result.typ = n.typ
@ -494,11 +487,10 @@ proc evalConvCStrToStr(c: PEvalContext, n: PNode): PNode =
result.typ = n.typ result.typ = n.typ
proc evalRaise(c: PEvalContext, n: PNode): PNode = proc evalRaise(c: PEvalContext, n: PNode): PNode =
var a: PNode
if n.sons[0] != nil: if n.sons[0] != nil:
result = evalAux(c, n.sons[0]) result = evalAux(c, n.sons[0])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkExceptBranch, n.info, a.typ) result = newNodeIT(nkExceptBranch, n.info, a.typ)
addSon(result, a) addSon(result, a)
c.lastException = result c.lastException = result
@ -516,14 +508,18 @@ proc evalReturn(c: PEvalContext, n: PNode): PNode =
result = newNodeIT(nkReturnToken, n.info, nil) result = newNodeIT(nkReturnToken, n.info, nil)
proc evalProc(c: PEvalContext, n: PNode): PNode = proc evalProc(c: PEvalContext, n: PNode): PNode =
var v: PSym
if n.sons[genericParamsPos] == nil: if n.sons[genericParamsPos] == nil:
if (resultPos < sonsLen(n)) and (n.sons[resultPos] != nil): if (resultPos < sonsLen(n)) and (n.sons[resultPos] != nil):
v = n.sons[resultPos].sym var v = n.sons[resultPos].sym
result = getNullValue(v.typ, n.info) result = getNullValue(v.typ, n.info)
IdNodeTablePut(c.tos.mapping, v, result) IdNodeTablePut(c.tos.mapping, v, result)
result = evalAux(c, n.sons[codePos]) result = evalAux(c, n.sons[codePos])
if result.kind == nkReturnToken: result = IdNodeTableGet(c.tos.mapping, v) if result.kind == nkReturnToken:
result = IdNodeTableGet(c.tos.mapping, v)
else:
result = evalAux(c, n.sons[codePos])
if result.kind == nkReturnToken:
result = emptyNode
else: else:
result = emptyNode result = emptyNode
@ -541,51 +537,42 @@ proc evalIs(c: PEvalContext, n: PNode): PNode =
result = newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n) result = newIntNodeT(ord(inheritanceDiff(result.typ, n.sons[2].typ) >= 0), n)
proc evalSetLengthStr(c: PEvalContext, n: PNode): PNode = proc evalSetLengthStr(c: PEvalContext, n: PNode): PNode =
var
a, b: PNode
oldLen, newLen: int
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
case a.kind case a.kind
of nkStrLit..nkTripleStrLit: of nkStrLit..nkTripleStrLit:
newLen = int(getOrdValue(b)) var newLen = int(getOrdValue(b))
setlen(a.strVal, newLen) setlen(a.strVal, newLen)
else: InternalError(n.info, "evalSetLengthStr") else: InternalError(n.info, "evalSetLengthStr")
result = emptyNode result = emptyNode
proc evalSetLengthSeq(c: PEvalContext, n: PNode): PNode = proc evalSetLengthSeq(c: PEvalContext, n: PNode): PNode =
var
a, b: PNode
newLen, oldLen: int
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
if a.kind != nkBracket: InternalError(n.info, "evalSetLengthSeq") if a.kind != nkBracket: InternalError(n.info, "evalSetLengthSeq")
newLen = int(getOrdValue(b)) var newLen = int(getOrdValue(b))
oldLen = sonsLen(a) var oldLen = sonsLen(a)
setlen(a.sons, newLen) setlen(a.sons, newLen)
for i in countup(oldLen, newLen - 1): for i in countup(oldLen, newLen - 1):
a.sons[i] = getNullValue(skipTypes(n.sons[1].typ, abstractVar), n.info) a.sons[i] = getNullValue(skipTypes(n.sons[1].typ, abstractVar), n.info)
result = emptyNode result = emptyNode
proc evalNewSeq(c: PEvalContext, n: PNode): PNode = proc evalNewSeq(c: PEvalContext, n: PNode): PNode =
var
a, b: PNode
t: PType
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
t = skipTypes(n.sons[1].typ, abstractVar) var t = skipTypes(n.sons[1].typ, abstractVar)
if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty") if a.kind == nkEmpty: InternalError(n.info, "first parameter is empty")
a.kind = nkBracket a.kind = nkBracket
a.info = n.info a.info = n.info
@ -601,38 +588,35 @@ proc evalAssert(c: PEvalContext, n: PNode): PNode =
else: stackTrace(c, n, errAssertionFailed) else: stackTrace(c, n, errAssertionFailed)
proc evalIncl(c: PEvalContext, n: PNode): PNode = proc evalIncl(c: PEvalContext, n: PNode): PNode =
var a, b: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
if not inSet(a, b): addSon(a, copyTree(b)) if not inSet(a, b): addSon(a, copyTree(b))
result = emptyNode result = emptyNode
proc evalExcl(c: PEvalContext, n: PNode): PNode = proc evalExcl(c: PEvalContext, n: PNode): PNode =
var a, b, r: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = newNodeIT(nkCurly, n.info, n.sons[1].typ) var b = newNodeIT(nkCurly, n.info, n.sons[1].typ)
addSon(b, result) addSon(b, result)
r = diffSets(a, b) var r = diffSets(a, b)
discardSons(a) discardSons(a)
for i in countup(0, sonsLen(r) - 1): addSon(a, r.sons[i]) for i in countup(0, sonsLen(r) - 1): addSon(a, r.sons[i])
result = emptyNode result = emptyNode
proc evalAppendStrCh(c: PEvalContext, n: PNode): PNode = proc evalAppendStrCh(c: PEvalContext, n: PNode): PNode =
var a, b: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
case a.kind case a.kind
of nkStrLit..nkTripleStrLit: add(a.strVal, chr(int(getOrdValue(b)))) of nkStrLit..nkTripleStrLit: add(a.strVal, chr(int(getOrdValue(b))))
else: InternalError(n.info, "evalAppendStrCh") else: InternalError(n.info, "evalAppendStrCh")
@ -640,10 +624,9 @@ proc evalAppendStrCh(c: PEvalContext, n: PNode): PNode =
proc evalConStrStr(c: PEvalContext, n: PNode): PNode = proc evalConStrStr(c: PEvalContext, n: PNode): PNode =
# we cannot use ``evalOp`` for this as we can here have more than 2 arguments # we cannot use ``evalOp`` for this as we can here have more than 2 arguments
var a: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
for i in countup(2, sonsLen(n) - 1): for i in countup(2, sonsLen(n) - 1):
result = evalAux(c, n.sons[i]) result = evalAux(c, n.sons[i])
if isSpecial(result): return if isSpecial(result): return
@ -651,26 +634,24 @@ proc evalConStrStr(c: PEvalContext, n: PNode): PNode =
result = a result = a
proc evalAppendStrStr(c: PEvalContext, n: PNode): PNode = proc evalAppendStrStr(c: PEvalContext, n: PNode): PNode =
var a, b: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
case a.kind case a.kind
of nkStrLit..nkTripleStrLit: a.strVal = a.strVal & getStrValue(b) of nkStrLit..nkTripleStrLit: a.strVal = a.strVal & getStrValue(b)
else: InternalError(n.info, "evalAppendStrStr") else: InternalError(n.info, "evalAppendStrStr")
result = emptyNode result = emptyNode
proc evalAppendSeqElem(c: PEvalContext, n: PNode): PNode = proc evalAppendSeqElem(c: PEvalContext, n: PNode): PNode =
var a, b: PNode
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
if a.kind == nkBracket: addSon(a, copyTree(b)) if a.kind == nkBracket: addSon(a, copyTree(b))
else: InternalError(n.info, "evalAppendSeqElem") else: InternalError(n.info, "evalAppendSeqElem")
result = emptyNode result = emptyNode
@ -684,11 +665,7 @@ proc isEmpty(n: PNode): bool =
result = (n != nil) and (n.kind == nkEmpty) result = (n != nil) and (n.kind == nkEmpty)
proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode = proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
var var m = getMagic(n)
m: TMagic
a, b, cc: PNode
k: biggestInt
m = getMagic(n)
case m case m
of mNone: result = evalCall(c, n) of mNone: result = evalCall(c, n)
of mIs: result = evalIs(c, n) of mIs: result = evalIs(c, n)
@ -714,7 +691,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNLen: of mNLen:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkIntLit, n.info, n.typ) result = newNodeIT(nkIntLit, n.info, n.typ)
case a.kind case a.kind
of nkEmpty..nkNilLit: of nkEmpty..nkNilLit:
@ -723,10 +700,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNChild: of mNChild:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
k = getOrdValue(result) var k = getOrdValue(result)
if not (a.kind in {nkEmpty..nkNilLit}) and (k >= 0) and (k < sonsLen(a)): if not (a.kind in {nkEmpty..nkNilLit}) and (k >= 0) and (k < sonsLen(a)):
result = a.sons[int(k)] result = a.sons[int(k)]
if result == nil: result = newNode(nkEmpty) if result == nil: result = newNode(nkEmpty)
@ -736,13 +713,13 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetChild: of mNSetChild:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
result = evalAux(c, n.sons[3]) result = evalAux(c, n.sons[3])
if isSpecial(result): return if isSpecial(result): return
k = getOrdValue(b) var k = getOrdValue(b)
if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}): if (k >= 0) and (k < sonsLen(a)) and not (a.kind in {nkEmpty..nkNilLit}):
if result.kind == nkEmpty: a.sons[int(k)] = nil if result.kind == nkEmpty: a.sons[int(k)] = nil
else: a.sons[int(k)] = result else: a.sons[int(k)] = result
@ -752,7 +729,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNAdd: of mNAdd:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
addSon(a, result) addSon(a, result)
@ -760,7 +737,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNAddMultiple: of mNAddMultiple:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i]) for i in countup(0, sonsLen(result) - 1): addSon(a, result.sons[i])
@ -768,10 +745,10 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNDel: of mNDel:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
result = evalAux(c, n.sons[3]) result = evalAux(c, n.sons[3])
if isSpecial(result): return if isSpecial(result): return
for i in countup(0, int(getOrdValue(result)) - 1): for i in countup(0, int(getOrdValue(result)) - 1):
@ -780,13 +757,13 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNKind: of mNKind:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkIntLit, n.info, n.typ) result = newNodeIT(nkIntLit, n.info, n.typ)
result.intVal = ord(a.kind) result.intVal = ord(a.kind)
of mNIntVal: of mNIntVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkIntLit, n.info, n.typ) result = newNodeIT(nkIntLit, n.info, n.typ)
case a.kind case a.kind
of nkCharLit..nkInt64Lit: result.intVal = a.intVal of nkCharLit..nkInt64Lit: result.intVal = a.intVal
@ -794,7 +771,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNFloatVal: of mNFloatVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkFloatLit, n.info, n.typ) result = newNodeIT(nkFloatLit, n.info, n.typ)
case a.kind case a.kind
of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal of nkFloatLit..nkFloat64Lit: result.floatVal = a.floatVal
@ -811,7 +788,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNStrVal: of mNStrVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkStrLit, n.info, n.typ) result = newNodeIT(nkStrLit, n.info, n.typ)
case a.kind case a.kind
of nkStrLit..nkTripleStrLit: result.strVal = a.strVal of nkStrLit..nkTripleStrLit: result.strVal = a.strVal
@ -819,7 +796,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetIntVal: of mNSetIntVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.intVal = result.intVal # XXX: exception handling? a.intVal = result.intVal # XXX: exception handling?
@ -827,7 +804,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetFloatVal: of mNSetFloatVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.floatVal = result.floatVal # XXX: exception handling? a.floatVal = result.floatVal # XXX: exception handling?
@ -835,7 +812,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetSymbol: of mNSetSymbol:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.sym = result.sym # XXX: exception handling? a.sym = result.sym # XXX: exception handling?
@ -843,7 +820,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetIdent: of mNSetIdent:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.ident = result.ident # XXX: exception handling? a.ident = result.ident # XXX: exception handling?
@ -851,7 +828,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetType: of mNSetType:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.typ = result.typ # XXX: exception handling? a.typ = result.typ # XXX: exception handling?
@ -859,7 +836,7 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNSetStrVal: of mNSetStrVal:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
a.strVal = result.strVal # XXX: exception handling? a.strVal = result.strVal # XXX: exception handling?
@ -867,14 +844,14 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNNewNimNode: of mNNewNimNode:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
k = getOrdValue(result) var k = getOrdValue(result)
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if result.kind == nkExceptBranch: return
a = result var a = result
if (k < 0) or (k > ord(high(TNodeKind))): if (k < 0) or (k > ord(high(TNodeKind))):
internalError(n.info, "request to create a NimNode with invalid kind") internalError(n.info, "request to create a NimNode with invalid kind")
if a.kind == nkNilLit: result = newNodeI(TNodeKind(int(k)), n.info) result = newNodeI(TNodeKind(int(k)),
else: result = newNodeI(TNodeKind(int(k)), a.info) if a.kind == nkNilLit: n.info else: a.info)
of mNCopyNimNode: of mNCopyNimNode:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
@ -888,33 +865,33 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
if isSpecial(result): return if isSpecial(result): return
if not (result.kind in {nkStrLit..nkTripleStrLit}): if not (result.kind in {nkStrLit..nkTripleStrLit}):
InternalError(n.info, "no string node") InternalError(n.info, "no string node")
a = result var a = result
result = newNodeIT(nkIdent, n.info, n.typ) result = newNodeIT(nkIdent, n.info, n.typ)
result.ident = getIdent(a.strVal) result.ident = getIdent(a.strVal)
of mIdentToStr: of mIdentToStr:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
if result.kind != nkIdent: InternalError(n.info, "no ident node") if result.kind != nkIdent: InternalError(n.info, "no ident node")
a = result var a = result
result = newNodeIT(nkStrLit, n.info, n.typ) result = newNodeIT(nkStrLit, n.info, n.typ)
result.strVal = a.ident.s result.strVal = a.ident.s
of mEqIdent: of mEqIdent:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
result = newNodeIT(nkIntLit, n.info, n.typ) result = newNodeIT(nkIntLit, n.info, n.typ)
if (a.kind == nkIdent) and (b.kind == nkIdent): if (a.kind == nkIdent) and (b.kind == nkIdent):
if a.ident.id == b.ident.id: result.intVal = 1 if a.ident.id == b.ident.id: result.intVal = 1
of mEqNimrodNode: of mEqNimrodNode:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
b = result var b = result
result = newNodeIT(nkIntLit, n.info, n.typ) result = newNodeIT(nkIntLit, n.info, n.typ)
if (a == b) or if (a == b) or
(b.kind in {nkNilLit, nkEmpty}) and (a.kind in {nkNilLit, nkEmpty}): (b.kind in {nkNilLit, nkEmpty}) and (a.kind in {nkNilLit, nkEmpty}):
@ -941,15 +918,15 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
of mNewString: of mNewString:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
result = newNodeIT(nkStrLit, n.info, n.typ) result = newNodeIT(nkStrLit, n.info, n.typ)
result.strVal = newString(int(getOrdValue(a))) result.strVal = newString(int(getOrdValue(a)))
else: else:
result = evalAux(c, n.sons[1]) result = evalAux(c, n.sons[1])
if isSpecial(result): return if isSpecial(result): return
a = result var a = result
b = nil var b: PNode = nil
cc = nil var cc: PNode = nil
if sonsLen(n) > 2: if sonsLen(n) > 2:
result = evalAux(c, n.sons[2]) result = evalAux(c, n.sons[2])
if isSpecial(result): return if isSpecial(result): return
@ -962,7 +939,6 @@ proc evalMagicOrCall(c: PEvalContext, n: PNode): PNode =
else: result = evalOp(m, n, a, b, cc) else: result = evalOp(m, n, a, b, cc)
proc evalAux(c: PEvalContext, n: PNode): PNode = proc evalAux(c: PEvalContext, n: PNode): PNode =
var a: PNode
result = emptyNode result = emptyNode
dec(gNestedEvals) dec(gNestedEvals)
if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations) if gNestedEvals <= 0: stackTrace(c, n, errTooManyIterations)
@ -974,14 +950,14 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit: of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit:
result = evalMagicOrCall(c, n) result = evalMagicOrCall(c, n)
of nkCurly, nkBracket, nkRange: of nkCurly, nkBracket, nkRange:
a = copyNode(n) var a = copyNode(n)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = evalAux(c, n.sons[i]) result = evalAux(c, n.sons[i])
if isSpecial(result): return if isSpecial(result): return
addSon(a, result) addSon(a, result)
result = a result = a
of nkPar: of nkPar:
a = copyTree(n) var a = copyTree(n)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = evalAux(c, n.sons[i].sons[1]) result = evalAux(c, n.sons[i].sons[1])
if isSpecial(result): return if isSpecial(result): return
@ -1015,8 +991,7 @@ proc evalAux(c: PEvalContext, n: PNode): PNode =
result = evalAux(c, n.sons[i]) result = evalAux(c, n.sons[i])
case result.kind case result.kind
of nkExceptBranch, nkReturnToken, nkBreakStmt: break of nkExceptBranch, nkReturnToken, nkBreakStmt: break
else: else: nil
nil
of nkProcDef, nkMethodDef, nkMacroDef, nkCommentStmt, nkPragma, nkTypeSection, of nkProcDef, nkMethodDef, nkMacroDef, nkCommentStmt, nkPragma, nkTypeSection,
nkTemplateDef, nkConstSection, nkIteratorDef, nkConverterDef, nkTemplateDef, nkConstSection, nkIteratorDef, nkConverterDef,
nkIncludeStmt, nkImportStmt, nkFromStmt: nkIncludeStmt, nkImportStmt, nkFromStmt:

View file

@ -39,6 +39,7 @@ Files: "*.nim"
Files: "rod/readme.txt" Files: "rod/readme.txt"
Files: "rod/nimrod.ini" Files: "rod/nimrod.ini"
Files: "rod/nimrod.cfg" Files: "rod/nimrod.cfg"
Files: "rod/*.nim"
Files: "build/empty.txt" Files: "build/empty.txt"
Files: "bin/empty.txt" Files: "bin/empty.txt"
Files: "nim/*.*" Files: "nim/*.*"

0
rod/nimrod.nim Normal file → Executable file
View file

View file

@ -15,6 +15,6 @@ const
defaultAsmMarkerSymbol* = '!' defaultAsmMarkerSymbol* = '!'
VersionMajor* = 0 VersionMajor* = 0
VersionMinor* = 8 VersionMinor* = 8
VersionPatch* = 5 VersionPatch* = 6
VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch VersionAsString* = $VersionMajor & "." & $VersionMinor & "." & $VersionPatch

0
rod/options.nim Normal file → Executable file
View file

0
rod/pbraces.nim Normal file → Executable file
View file

0
rod/pnimsyn.nim Normal file → Executable file
View file

0
rod/pragmas.nim Normal file → Executable file
View file

0
rod/rodread.nim Normal file → Executable file
View file

0
rod/rodwrite.nim Normal file → Executable file
View file

0
rod/sem.nim Normal file → Executable file
View file

0
rod/semdata.nim Normal file → Executable file
View file

0
rod/semfold.nim Normal file → Executable file
View file

View file

@ -28,16 +28,16 @@ proc semWhen(c: PContext, n: PNode): PNode =
result = semStmt(c, it.sons[0]) # do not open a new scope! result = semStmt(c, it.sons[0]) # do not open a new scope!
else: illFormedAst(n) else: illFormedAst(n)
if result == nil: if result == nil:
result = newNodeI(nkNilLit, n.info) # The ``when`` statement implements the mechanism for platform dependant result = newNodeI(nkNilLit, n.info)
# code. Thus we try to ensure here consistent ID allocation after the # The ``when`` statement implements the mechanism for platform dependant
# ``when`` statement. # code. Thus we try to ensure here consistent ID allocation after the
# ``when`` statement.
IDsynchronizationPoint(200) IDsynchronizationPoint(200)
proc semIf(c: PContext, n: PNode): PNode = proc semIf(c: PContext, n: PNode): PNode =
var it: PNode
result = n result = n
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
it = n.sons[i] var it = n.sons[i]
if it == nil: illFormedAst(n) if it == nil: illFormedAst(n)
case it.kind case it.kind
of nkElifBranch: of nkElifBranch:
@ -58,19 +58,17 @@ proc semDiscard(c: PContext, n: PNode): PNode =
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
if n.sons[0].typ == nil: liMessage(n.info, errInvalidDiscard) if n.sons[0].typ == nil: liMessage(n.info, errInvalidDiscard)
proc semBreakOrContinue(c: PContext, n: PNode): PNode = proc semBreakOrContinue(c: PContext, n: PNode): PNode =
var
s: PSym
x: PNode
result = n result = n
checkSonsLen(n, 1) checkSonsLen(n, 1)
if n.sons[0] != nil: if n.sons[0] != nil:
var s: PSym
case n.sons[0].kind case n.sons[0].kind
of nkIdent: s = lookUp(c, n.sons[0]) of nkIdent: s = lookUp(c, n.sons[0])
of nkSym: s = n.sons[0].sym of nkSym: s = n.sons[0].sym
else: illFormedAst(n) else: illFormedAst(n)
if (s.kind == skLabel) and (s.owner.id == c.p.owner.id): if (s.kind == skLabel) and (s.owner.id == c.p.owner.id):
x = newSymNode(s) var x = newSymNode(s)
x.info = n.info x.info = n.info
incl(s.flags, sfUsed) incl(s.flags, sfUsed)
n.sons[0] = x n.sons[0] = x
@ -80,13 +78,12 @@ proc semBreakOrContinue(c: PContext, n: PNode): PNode =
liMessage(n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments})) liMessage(n.info, errInvalidControlFlowX, renderTree(n, {renderNoComments}))
proc semBlock(c: PContext, n: PNode): PNode = proc semBlock(c: PContext, n: PNode): PNode =
var labl: PSym
result = n result = n
Inc(c.p.nestedBlockCounter) Inc(c.p.nestedBlockCounter)
checkSonsLen(n, 2) checkSonsLen(n, 2)
openScope(c.tab) # BUGFIX: label is in the scope of block! openScope(c.tab) # BUGFIX: label is in the scope of block!
if n.sons[0] != nil: if n.sons[0] != nil:
labl = newSymS(skLabel, n.sons[0], c) var labl = newSymS(skLabel, n.sons[0], c)
addDecl(c, labl) addDecl(c, labl)
n.sons[0] = newSymNode(labl) # BUGFIX n.sons[0] = newSymNode(labl) # BUGFIX
n.sons[1] = semStmt(c, n.sons[1]) n.sons[1] = semStmt(c, n.sons[1])
@ -109,7 +106,8 @@ proc semAsm(con: PContext, n: PNode): PNode =
result = copyNode(n) result = copyNode(n)
str = n.sons[1].strVal str = n.sons[1].strVal
if str == "": if str == "":
liMessage(n.info, errEmptyAsm) # now parse the string literal and substitute symbols: liMessage(n.info, errEmptyAsm)
# now parse the string literal and substitute symbols:
a = 0 a = 0
while true: while true:
b = strutils.find(str, marker, a) b = strutils.find(str, marker, a)
@ -143,18 +141,13 @@ proc semWhile(c: PContext, n: PNode): PNode =
closeScope(c.tab) closeScope(c.tab)
proc semCase(c: PContext, n: PNode): PNode = proc semCase(c: PContext, n: PNode): PNode =
var
length: int
covered: biggestint # for some types we count to check if all cases have been covered
chckCovered: bool
x: PNode
# check selector: # check selector:
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
openScope(c.tab) openScope(c.tab)
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
chckCovered = false var chckCovered = false
covered = 0 var covered: biggestint = 0
case skipTypes(n.sons[0].Typ, abstractVarRange).Kind case skipTypes(n.sons[0].Typ, abstractVarRange).Kind
of tyInt..tyInt64, tyChar, tyEnum: of tyInt..tyInt64, tyChar, tyEnum:
chckCovered = true chckCovered = true
@ -162,12 +155,12 @@ proc semCase(c: PContext, n: PNode): PNode =
nil nil
else: liMessage(n.info, errSelectorMustBeOfCertainTypes) else: liMessage(n.info, errSelectorMustBeOfCertainTypes)
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
x = n.sons[i] var x = n.sons[i]
case x.kind case x.kind
of nkOfBranch: of nkOfBranch:
checkMinSonsLen(x, 2) checkMinSonsLen(x, 2)
semCaseBranch(c, n, x, i, covered) semCaseBranch(c, n, x, i, covered)
length = sonsLen(x) var length = sonsLen(x)
x.sons[length - 1] = semStmtScope(c, x.sons[length - 1]) x.sons[length - 1] = semStmtScope(c, x.sons[length - 1])
of nkElifBranch: of nkElifBranch:
chckCovered = false chckCovered = false
@ -313,8 +306,9 @@ proc semVar(c: PContext, n: PNode): PNode =
if a.sons[length - 2] != nil: typ = semTypeNode(c, a.sons[length - 2], nil) if a.sons[length - 2] != nil: typ = semTypeNode(c, a.sons[length - 2], nil)
else: typ = nil else: typ = nil
if a.sons[length - 1] != nil: if a.sons[length - 1] != nil:
def = semExprWithType(c, a.sons[length - 1]) # BUGFIX: ``fitNode`` is needed here! def = semExprWithType(c, a.sons[length - 1])
# check type compability between def.typ and typ: # BUGFIX: ``fitNode`` is needed here!
# check type compability between def.typ and typ:
if (typ != nil): def = fitNode(c, typ, def) if (typ != nil): def = fitNode(c, typ, def)
else: typ = def.typ else: typ = def.typ
else: else:
@ -369,7 +363,8 @@ proc semConst(c: PContext, n: PNode): PNode =
v = semIdentWithPragma(c, skConst, a.sons[0], {}) v = semIdentWithPragma(c, skConst, a.sons[0], {})
if a.sons[1] != nil: typ = semTypeNode(c, a.sons[1], nil) if a.sons[1] != nil: typ = semTypeNode(c, a.sons[1], nil)
else: typ = nil else: typ = nil
def = semAndEvalConstExpr(c, a.sons[2]) # check type compability between def.typ and typ: def = semAndEvalConstExpr(c, a.sons[2])
# check type compability between def.typ and typ:
if (typ != nil): if (typ != nil):
def = fitRemoveHiddenConv(c, typ, def) def = fitRemoveHiddenConv(c, typ, def)
else: else:
@ -397,7 +392,8 @@ proc semFor(c: PContext, n: PNode): PNode =
length = sonsLen(n) length = sonsLen(n)
openScope(c.tab) openScope(c.tab)
if n.sons[length - 2].kind == nkRange: if n.sons[length - 2].kind == nkRange:
checkSonsLen(n.sons[length - 2], 2) # convert ``in 3..5`` to ``in countup(3, 5)`` checkSonsLen(n.sons[length - 2], 2)
# convert ``in 3..5`` to ``in countup(3, 5)``
countupNode = newNodeI(nkCall, n.sons[length - 2].info) countupNode = newNodeI(nkCall, n.sons[length - 2].info)
countUp = StrTableGet(magicsys.systemModule.Tab, getIdent("countup")) countUp = StrTableGet(magicsys.systemModule.Tab, getIdent("countup"))
if (countUp == nil): liMessage(countupNode.info, errSystemNeeds, "countup") if (countUp == nil): liMessage(countupNode.info, errSystemNeeds, "countup")
@ -431,32 +427,27 @@ proc semFor(c: PContext, n: PNode): PNode =
Dec(c.p.nestedLoopCounter) Dec(c.p.nestedLoopCounter)
proc semRaise(c: PContext, n: PNode): PNode = proc semRaise(c: PContext, n: PNode): PNode =
var typ: PType
result = n result = n
checkSonsLen(n, 1) checkSonsLen(n, 1)
if n.sons[0] != nil: if n.sons[0] != nil:
n.sons[0] = semExprWithType(c, n.sons[0]) n.sons[0] = semExprWithType(c, n.sons[0])
typ = n.sons[0].typ var typ = n.sons[0].typ
if (typ.kind != tyRef) or (typ.sons[0].kind != tyObject): if (typ.kind != tyRef) or (typ.sons[0].kind != tyObject):
liMessage(n.info, errExprCannotBeRaised) liMessage(n.info, errExprCannotBeRaised)
proc semTry(c: PContext, n: PNode): PNode = proc semTry(c: PContext, n: PNode): PNode =
var var check: TIntSet
length: int
a: PNode
typ: PType
check: TIntSet
result = n result = n
checkMinSonsLen(n, 2) checkMinSonsLen(n, 2)
n.sons[0] = semStmtScope(c, n.sons[0]) n.sons[0] = semStmtScope(c, n.sons[0])
IntSetInit(check) IntSetInit(check)
for i in countup(1, sonsLen(n) - 1): for i in countup(1, sonsLen(n) - 1):
a = n.sons[i] var a = n.sons[i]
checkMinSonsLen(a, 1) checkMinSonsLen(a, 1)
length = sonsLen(a) var length = sonsLen(a)
if a.kind == nkExceptBranch: if a.kind == nkExceptBranch:
for j in countup(0, length - 2): for j in countup(0, length - 2):
typ = semTypeNode(c, a.sons[j], nil) var typ = semTypeNode(c, a.sons[j], nil)
if typ.kind == tyRef: typ = typ.sons[0] if typ.kind == tyRef: typ = typ.sons[0]
if (typ.kind != tyObject): if (typ.kind != tyObject):
liMessage(a.sons[j].info, errExprCannotBeRaised) liMessage(a.sons[j].info, errExprCannotBeRaised)
@ -465,26 +456,24 @@ proc semTry(c: PContext, n: PNode): PNode =
if IntSetContainsOrIncl(check, typ.id): if IntSetContainsOrIncl(check, typ.id):
liMessage(a.sons[j].info, errExceptionAlreadyHandled) liMessage(a.sons[j].info, errExceptionAlreadyHandled)
elif a.kind != nkFinally: elif a.kind != nkFinally:
illFormedAst(n) # last child of an nkExcept/nkFinally branch is a statement: illFormedAst(n)
# last child of an nkExcept/nkFinally branch is a statement:
a.sons[length - 1] = semStmtScope(c, a.sons[length - 1]) a.sons[length - 1] = semStmtScope(c, a.sons[length - 1])
proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode = proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
var
L: int
s: PSym
a, def: PNode
typ: PType
result = copyNode(n) result = copyNode(n)
if n.kind != nkGenericParams: InternalError(n.info, "semGenericParamList") if n.kind != nkGenericParams: InternalError(n.info, "semGenericParamList")
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
a = n.sons[i] var a = n.sons[i]
if a.kind != nkIdentDefs: illFormedAst(n) if a.kind != nkIdentDefs: illFormedAst(n)
L = sonsLen(a) var L = sonsLen(a)
def = a.sons[L - 1] var def = a.sons[L - 1]
var typ: PType
if a.sons[L - 2] != nil: typ = semTypeNode(c, a.sons[L - 2], nil) if a.sons[L - 2] != nil: typ = semTypeNode(c, a.sons[L - 2], nil)
elif def != nil: typ = newTypeS(tyExpr, c) elif def != nil: typ = newTypeS(tyExpr, c)
else: typ = nil else: typ = nil
for j in countup(0, L - 3): for j in countup(0, L - 3):
var s: PSym
if (typ == nil) or (typ.kind == tyTypeDesc): if (typ == nil) or (typ.kind == tyTypeDesc):
s = newSymS(skType, a.sons[j], c) s = newSymS(skType, a.sons[j], c)
s.typ = newTypeS(tyGenericParam, c) s.typ = newTypeS(tyGenericParam, c)
@ -499,11 +488,10 @@ proc semGenericParamList(c: PContext, n: PNode, father: PType = nil): PNode =
addDecl(c, s) addDecl(c, s)
proc addGenericParamListToScope(c: PContext, n: PNode) = proc addGenericParamListToScope(c: PContext, n: PNode) =
var a: PNode
if n.kind != nkGenericParams: if n.kind != nkGenericParams:
InternalError(n.info, "addGenericParamListToScope") InternalError(n.info, "addGenericParamListToScope")
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
a = n.sons[i] var a = n.sons[i]
if a.kind != nkSym: internalError(a.info, "addGenericParamListToScope") if a.kind != nkSym: internalError(a.info, "addGenericParamListToScope")
addDecl(c, a.sym) addDecl(c, a.sym)
@ -512,8 +500,9 @@ proc SemTypeSection(c: PContext, n: PNode): PNode =
s: PSym s: PSym
t, body: PType t, body: PType
a: PNode a: PNode
result = n # process the symbols on the left side for the whole type section, before result = n
# we even look at the type definitions on the right # process the symbols on the left side for the whole type section, before
# we even look at the type definitions on the right
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
a = n.sons[i] a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
@ -528,7 +517,8 @@ proc SemTypeSection(c: PContext, n: PNode): PNode =
s.typ = newTypeS(tyForward, c) s.typ = newTypeS(tyForward, c)
s.typ.sym = s # process pragmas: s.typ.sym = s # process pragmas:
if a.sons[0].kind == nkPragmaExpr: if a.sons[0].kind == nkPragmaExpr:
pragma(c, s, a.sons[0].sons[1], typePragmas) # add it here, so that recursive types are possible: pragma(c, s, a.sons[0].sons[1], typePragmas)
# add it here, so that recursive types are possible:
addInterfaceDecl(c, s) addInterfaceDecl(c, s)
a.sons[0] = newSymNode(s) a.sons[0] = newSymNode(s)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
@ -571,7 +561,8 @@ proc SemTypeSection(c: PContext, n: PNode): PNode =
a = n.sons[i] a = n.sons[i]
if a.kind == nkCommentStmt: continue if a.kind == nkCommentStmt: continue
if (a.sons[0].kind != nkSym): IllFormedAst(a) if (a.sons[0].kind != nkSym): IllFormedAst(a)
s = a.sons[0].sym # compute the type's size and check for illegal recursions: s = a.sons[0].sym
# compute the type's size and check for illegal recursions:
if a.sons[1] == nil: if a.sons[1] == nil:
if (a.sons[2] != nil) and if (a.sons[2] != nil) and
(a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}): (a.sons[2].kind in {nkSym, nkIdent, nkAccQuoted}):
@ -592,9 +583,8 @@ proc addParams(c: PContext, n: PNode) =
addDecl(c, n.sons[i].sym) addDecl(c, n.sons[i].sym)
proc semBorrow(c: PContext, n: PNode, s: PSym) = proc semBorrow(c: PContext, n: PNode, s: PSym) =
var b: PSym
# search for the correct alias: # search for the correct alias:
b = SearchForBorrowProc(c, s, c.tab.tos - 2) var b = SearchForBorrowProc(c, s, c.tab.tos - 2)
if b == nil: if b == nil:
liMessage(n.info, errNoSymbolToBorrowFromFound) # store the alias: liMessage(n.info, errNoSymbolToBorrowFromFound) # store the alias:
n.sons[codePos] = newSymNode(b) n.sons[codePos] = newSymNode(b)
@ -605,9 +595,8 @@ proc sideEffectsCheck(c: PContext, s: PSym) =
liMessage(s.info, errXhasSideEffects, s.name.s) liMessage(s.info, errXhasSideEffects, s.name.s)
proc addResult(c: PContext, t: PType, info: TLineInfo) = proc addResult(c: PContext, t: PType, info: TLineInfo) =
var s: PSym
if t != nil: if t != nil:
s = newSym(skVar, getIdent("result"), getCurrOwner()) var s = newSym(skVar, getIdent("result"), getCurrOwner())
s.info = info s.info = info
s.typ = t s.typ = t
incl(s.flags, sfResult) incl(s.flags, sfResult)
@ -619,14 +608,11 @@ proc addResultNode(c: PContext, n: PNode) =
if c.p.resultSym != nil: addSon(n, newSymNode(c.p.resultSym)) if c.p.resultSym != nil: addSon(n, newSymNode(c.p.resultSym))
proc semLambda(c: PContext, n: PNode): PNode = proc semLambda(c: PContext, n: PNode): PNode =
var
s: PSym
oldP: PProcCon
result = n result = n
checkSonsLen(n, codePos + 1) checkSonsLen(n, codePos + 1)
s = newSym(skProc, getIdent(":anonymous"), getCurrOwner()) var s = newSym(skProc, getIdent(":anonymous"), getCurrOwner())
s.info = n.info s.info = n.info
oldP = c.p # restore later var oldP = c.p # restore later
s.ast = n s.ast = n
n.sons[namePos] = newSymNode(s) n.sons[namePos] = newSymNode(s)
pushOwner(s) pushOwner(s)
@ -660,7 +646,6 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
validPragmas: TSpecialWords): PNode = validPragmas: TSpecialWords): PNode =
var var
s, proto: PSym s, proto: PSym
oldP: PProcCon
gp: PNode gp: PNode
result = n result = n
checkSonsLen(n, codePos + 1) checkSonsLen(n, codePos + 1)
@ -670,7 +655,7 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
else: else:
s = semIdentVis(c, kind, n.sons[0], {}) s = semIdentVis(c, kind, n.sons[0], {})
n.sons[namePos] = newSymNode(s) n.sons[namePos] = newSymNode(s)
oldP = c.p # restore later var oldP = c.p # restore later
if sfStar in s.flags: incl(s.flags, sfInInterface) if sfStar in s.flags: incl(s.flags, sfInInterface)
s.ast = n s.ast = n
pushOwner(s) pushOwner(s)
@ -693,8 +678,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
if oldP.owner.kind != skModule: if oldP.owner.kind != skModule:
s.typ.callConv = ccClosure s.typ.callConv = ccClosure
else: else:
s.typ.callConv = lastOptionEntry(c).defaultCC # add it here, so that recursive procs are possible: s.typ.callConv = lastOptionEntry(c).defaultCC
# -2 because we have a scope open for parameters # add it here, so that recursive procs are possible:
# -2 because we have a scope open for parameters
if kind in OverloadableSyms: if kind in OverloadableSyms:
addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2) addInterfaceOverloadableSymAt(c, s, c.tab.tos - 2)
else: else:
@ -745,12 +731,9 @@ proc semProcAux(c: PContext, n: PNode, kind: TSymKind,
c.p = oldP # restore c.p = oldP # restore
proc semIterator(c: PContext, n: PNode): PNode = proc semIterator(c: PContext, n: PNode): PNode =
var
t: PType
s: PSym
result = semProcAux(c, n, skIterator, iteratorPragmas) result = semProcAux(c, n, skIterator, iteratorPragmas)
s = result.sons[namePos].sym var s = result.sons[namePos].sym
t = s.typ var t = s.typ
if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "iterator") if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "iterator")
if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s) if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s)
@ -762,43 +745,34 @@ proc semMethod(c: PContext, n: PNode): PNode =
result = semProcAux(c, n, skMethod, methodPragmas) result = semProcAux(c, n, skMethod, methodPragmas)
proc semConverterDef(c: PContext, n: PNode): PNode = proc semConverterDef(c: PContext, n: PNode): PNode =
var
t: PType
s: PSym
if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "converter") if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "converter")
checkSonsLen(n, codePos + 1) checkSonsLen(n, codePos + 1)
if n.sons[genericParamsPos] != nil: if n.sons[genericParamsPos] != nil:
liMessage(n.info, errNoGenericParamsAllowedForX, "converter") liMessage(n.info, errNoGenericParamsAllowedForX, "converter")
result = semProcAux(c, n, skConverter, converterPragmas) result = semProcAux(c, n, skConverter, converterPragmas)
s = result.sons[namePos].sym var s = result.sons[namePos].sym
t = s.typ var t = s.typ
if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "converter") if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "converter")
if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "converter") if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "converter")
addConverter(c, s) addConverter(c, s)
proc semMacroDef(c: PContext, n: PNode): PNode = proc semMacroDef(c: PContext, n: PNode): PNode =
var
t: PType
s: PSym
checkSonsLen(n, codePos + 1) checkSonsLen(n, codePos + 1)
if n.sons[genericParamsPos] != nil: if n.sons[genericParamsPos] != nil:
liMessage(n.info, errNoGenericParamsAllowedForX, "macro") liMessage(n.info, errNoGenericParamsAllowedForX, "macro")
result = semProcAux(c, n, skMacro, macroPragmas) result = semProcAux(c, n, skMacro, macroPragmas)
s = result.sons[namePos].sym var s = result.sons[namePos].sym
t = s.typ var t = s.typ
if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "macro") if t.sons[0] == nil: liMessage(n.info, errXNeedsReturnType, "macro")
if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "macro") if sonsLen(t) != 2: liMessage(n.info, errXRequiresOneArgument, "macro")
if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s) if n.sons[codePos] == nil: liMessage(n.info, errImplOfXexpected, s.name.s)
proc evalInclude(c: PContext, n: PNode): PNode = proc evalInclude(c: PContext, n: PNode): PNode =
var
fileIndex: int
f: string
result = newNodeI(nkStmtList, n.info) result = newNodeI(nkStmtList, n.info)
addSon(result, n) # the rodwriter needs include information! addSon(result, n) # the rodwriter needs include information!
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
f = getModuleFile(n.sons[i]) var f = getModuleFile(n.sons[i])
fileIndex = includeFilename(f) var fileIndex = includeFilename(f)
if IntSetContainsOrIncl(c.includedFiles, fileIndex): if IntSetContainsOrIncl(c.includedFiles, fileIndex):
liMessage(n.info, errRecursiveDependencyX, f) liMessage(n.info, errRecursiveDependencyX, f)
addSon(result, semStmt(c, gIncludeFile(f))) addSon(result, semStmt(c, gIncludeFile(f)))
@ -806,26 +780,23 @@ proc evalInclude(c: PContext, n: PNode): PNode =
proc semCommand(c: PContext, n: PNode): PNode = proc semCommand(c: PContext, n: PNode): PNode =
result = semExpr(c, n) result = semExpr(c, n)
if result.typ != nil: liMessage(n.info, errDiscardValue) if result.typ != nil and result.typ.kind != tyStmt:
liMessage(n.info, errDiscardValue)
proc SemStmt(c: PContext, n: PNode): PNode = proc SemStmt(c: PContext, n: PNode): PNode =
const # must be last statements in a block: const # must be last statements in a block:
LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt} LastBlockStmts = {nkRaiseStmt, nkReturnStmt, nkBreakStmt, nkContinueStmt}
var length: int
result = n result = n
if n == nil: return if n == nil: return
if nfSem in n.flags: return if nfSem in n.flags: return
case n.kind case n.kind
of nkAsgn: of nkAsgn: result = semAsgn(c, n)
result = semAsgn(c, n)
of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkMacroStmt, nkCallStrLit: of nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkMacroStmt, nkCallStrLit:
result = semCommand(c, n) result = semCommand(c, n)
of nkEmpty, nkCommentStmt, nkNilLit: of nkEmpty, nkCommentStmt, nkNilLit: nil
nil of nkBlockStmt: result = semBlock(c, n)
of nkBlockStmt:
result = semBlock(c, n)
of nkStmtList: of nkStmtList:
length = sonsLen(n) var length = sonsLen(n)
for i in countup(0, length - 1): for i in countup(0, length - 1):
n.sons[i] = semStmt(c, n.sons[i]) n.sons[i] = semStmt(c, n.sons[i])
if (n.sons[i].kind in LastBlockStmts): if (n.sons[i].kind in LastBlockStmts):
@ -834,50 +805,28 @@ proc SemStmt(c: PContext, n: PNode): PNode =
of nkPragma, nkCommentStmt, nkNilLit, nkEmpty: of nkPragma, nkCommentStmt, nkNilLit, nkEmpty:
nil nil
else: liMessage(n.sons[j].info, errStmtInvalidAfterReturn) else: liMessage(n.sons[j].info, errStmtInvalidAfterReturn)
of nkRaiseStmt: of nkRaiseStmt: result = semRaise(c, n)
result = semRaise(c, n) of nkVarSection: result = semVar(c, n)
of nkVarSection: of nkConstSection: result = semConst(c, n)
result = semVar(c, n) of nkTypeSection: result = SemTypeSection(c, n)
of nkConstSection: of nkIfStmt: result = SemIf(c, n)
result = semConst(c, n) of nkWhenStmt: result = semWhen(c, n)
of nkTypeSection: of nkDiscardStmt: result = semDiscard(c, n)
result = SemTypeSection(c, n) of nkWhileStmt: result = semWhile(c, n)
of nkIfStmt: of nkTryStmt: result = semTry(c, n)
result = SemIf(c, n) of nkBreakStmt, nkContinueStmt: result = semBreakOrContinue(c, n)
of nkWhenStmt: of nkForStmt: result = semFor(c, n)
result = semWhen(c, n) of nkCaseStmt: result = semCase(c, n)
of nkDiscardStmt: of nkReturnStmt: result = semReturn(c, n)
result = semDiscard(c, n) of nkAsmStmt: result = semAsm(c, n)
of nkWhileStmt: of nkYieldStmt: result = semYield(c, n)
result = semWhile(c, n) of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)
of nkTryStmt: of nkIteratorDef: result = semIterator(c, n)
result = semTry(c, n) of nkProcDef: result = semProc(c, n)
of nkBreakStmt, nkContinueStmt: of nkMethodDef: result = semMethod(c, n)
result = semBreakOrContinue(c, n) of nkConverterDef: result = semConverterDef(c, n)
of nkForStmt: of nkMacroDef: result = semMacroDef(c, n)
result = semFor(c, n) of nkTemplateDef: result = semTemplateDef(c, n)
of nkCaseStmt:
result = semCase(c, n)
of nkReturnStmt:
result = semReturn(c, n)
of nkAsmStmt:
result = semAsm(c, n)
of nkYieldStmt:
result = semYield(c, n)
of nkPragma:
pragma(c, c.p.owner, n, stmtPragmas)
of nkIteratorDef:
result = semIterator(c, n)
of nkProcDef:
result = semProc(c, n)
of nkMethodDef:
result = semMethod(c, n)
of nkConverterDef:
result = semConverterDef(c, n)
of nkMacroDef:
result = semMacroDef(c, n)
of nkTemplateDef:
result = semTemplateDef(c, n)
of nkImportStmt: of nkImportStmt:
if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "import") if not isTopLevel(c): liMessage(n.info, errXOnlyAtModuleScope, "import")
result = evalImport(c, n) result = evalImport(c, n)

0
rod/transf.nim Normal file → Executable file
View file

0
rod/trees.nim Normal file → Executable file
View file

View file

@ -12,8 +12,8 @@ var
proc testA() = proc testA() =
var p = 0 var p = 0
map(myData, lambda (x: int): int = map(myData, proc (x: int): int =
result = x + 1 shl (lambda (y: int): int = result = x + 1 shl (proc (y: int): int =
return y + p return y + p
)(0) )(0)
inc(p)) inc(p))

View file

@ -1,3 +1,4 @@
import strutils
const const
HelpText = """ HelpText = """
@ -9,7 +10,7 @@ const
Compiled at: $2, $3 Compiled at: $2, $3
Usage: Usage:
koch.py [options] command [options for command] koch [options] command [options for command]
Options: Options:
--force, -f, -B, -b forces rebuild --force, -f, -B, -b forces rebuild
--help, -h shows this help and quits --help, -h shows this help and quits
@ -23,4 +24,5 @@ Possible Commands:
""" % [NimrodVersion & repeatChar(44-len(NimrodVersion)), """ % [NimrodVersion & repeatChar(44-len(NimrodVersion)),
CompileDate, CompileTime] CompileDate, CompileTime]
echo helpText

View file

@ -1,10 +0,0 @@
type
TCardPts = enum
North, West, South, East
TCardPts2 = enum of TCardPts
N, W, S, E
# If I do:
var y = W
echo($y & "=" & $ord(y)) #OUT W=5

View file

@ -61,11 +61,15 @@ for x, y in items([(1, 2), (3, 4), (6, 1), (5, 2)]):
echo x echo x
echo y echo y
proc simpleConst(): int = return 34
# test constant evaluation: # test constant evaluation:
const const
constEval3 = simpleConst()
constEval = "abc".contains('b') constEval = "abc".contains('b')
constEval2 = fac(7) constEval2 = fac(7)
echo(constEval3)
echo(constEval) echo(constEval)
echo(constEval2) echo(constEval2)
echo(1.`+`(2)) echo(1.`+`(2))

View file

@ -1,4 +1,6 @@
# Test method call syntax for iterators: # Test method call syntax for iterators:
import strutils
const lines = """abc xyz""" const lines = """abc xyz"""
for x in lines.split(): for x in lines.split():

View file

@ -3,8 +3,8 @@
Here you can download the latest version of the Nimrod Compiler. Here you can download the latest version of the Nimrod Compiler.
Please choose your platform: Please choose your platform:
* source-based installation: `<download/nimrod_0.8.2.zip>`_ * source-based installation: `<download/nimrod_0.8.6.zip>`_
* installer for Windows XP/Vista (i386): `<download/nimrod_0.8.2.exe>`_ * installer for Windows XP/Vista (i386): `<download/nimrod_0.8.6.exe>`_
(includes GCC and everything else you need) (includes GCC and everything else you need)
The source-based installation has been tested on these systems: The source-based installation has been tested on these systems:

View file

@ -3,7 +3,7 @@ News
==== ====
2009-XX-XX Version 0.8.6 released 2009-12-21 Version 0.8.6 released
================================= =================================
Version 0.8.6 has been released! Get it `here <download.html>`_. The version Version 0.8.6 has been released! Get it `here <download.html>`_. The version
@ -15,8 +15,6 @@ Bugfixes
-------- --------
- The pragmas ``hint[X]:off`` and ``warning[X]:off`` now work. - The pragmas ``hint[X]:off`` and ``warning[X]:off`` now work.
- Method call syntax for iterators works again (``for x in lines.split()``). - Method call syntax for iterators works again (``for x in lines.split()``).
- Many bugfixes concerning macro evaluation.
- Many bugfixes concerning compile-time evaluation.
- Fixed a typo in ``removeDir`` for POSIX that lead to an infinite recursion. - Fixed a typo in ``removeDir`` for POSIX that lead to an infinite recursion.
- The compiler now checks that module filenames are valid identifiers. - The compiler now checks that module filenames are valid identifiers.
- Empty patterns for the ``dynlib`` pragma are now possible. - Empty patterns for the ``dynlib`` pragma are now possible.
@ -34,11 +32,12 @@ Additions
- Grammar/parser: ``SAD|IND`` is allowed before any kind of closing bracket. - Grammar/parser: ``SAD|IND`` is allowed before any kind of closing bracket.
This allows for more flexible source code formating. This allows for more flexible source code formating.
- The compiler now uses a *bind* table for symbol lookup within a ``bind`` - The compiler now uses a *bind* table for symbol lookup within a ``bind``
context. (See `<manual/#templates>`_ for details.) context. (See `<manual.html#templates>`_ for details.)
- ``discard """my long comment"""`` is now optimized away. - ``discard """my long comment"""`` is now optimized away.
- New ``--floatChecks: on|off`` switches and pragmas for better debugging - New ``--floatChecks: on|off`` switches and pragmas for better debugging
of floating point operations. (See of floating point operations. (See
`<manual/#pre-defined-floating-point-types>`_ for details.) `<manual.html#pre-defined-floating-point-types>`_ for details.)
- The manual has been improved. (Many thanks to Philippe Lhoste!)
Changes affecting backwards compatibility Changes affecting backwards compatibility

View file

@ -1,6 +1,9 @@
| `2009-12-21`:newsdate:
| Nimrod version 0.8.6 has been released!
Get it `here <./download.html>`_. Merry Christmas!
| `2009-10-21`:newsdate: | `2009-10-21`:newsdate:
| Nimrod version 0.8.2 has been released! | Nimrod version 0.8.2 has been released!
Get it `here <./download.html>`_.
| `2009-09-12`:newsdate: | `2009-09-12`:newsdate:
| Nimrod version 0.8.0 has been released! | Nimrod version 0.8.0 has been released!