compiler: Trim .nim files trailing whitespace

via OSX: find . -name '*.nim' -exec sed -i '' -E 's/[[:space:]]+$//' {} +
This commit is contained in:
Adam Strzelecki
2015-09-04 23:02:43 +02:00
parent 37fe21b64a
commit d681812465
32 changed files with 570 additions and 570 deletions

View File

@@ -11,7 +11,7 @@
import
ast, astalgo, types, trees, intsets, msgs
type
TAnalysisResult* = enum
arNo, arMaybe, arYes
@@ -21,42 +21,42 @@ proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult
proc isPartOfAux(n: PNode, b: PType, marker: var IntSet): TAnalysisResult =
result = arNo
case n.kind
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
of nkRecList:
for i in countup(0, sonsLen(n) - 1):
result = isPartOfAux(n.sons[i], b, marker)
if result == arYes: return
of nkRecCase:
assert(n.sons[0].kind == nkSym)
result = isPartOfAux(n.sons[0], b, marker)
if result == arYes: return
for i in countup(1, sonsLen(n) - 1):
for i in countup(1, sonsLen(n) - 1):
case n.sons[i].kind
of nkOfBranch, nkElse:
of nkOfBranch, nkElse:
result = isPartOfAux(lastSon(n.sons[i]), b, marker)
if result == arYes: return
else: internalError("isPartOfAux(record case branch)")
of nkSym:
result = isPartOfAux(n.sym.typ, b, marker)
else: internalError(n.info, "isPartOfAux()")
proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
proc isPartOfAux(a, b: PType, marker: var IntSet): TAnalysisResult =
result = arNo
if a == nil or b == nil: return
if containsOrIncl(marker, a.id): return
if a == nil or b == nil: return
if containsOrIncl(marker, a.id): return
if compareTypes(a, b, dcEqIgnoreDistinct): return arYes
case a.kind
of tyObject:
of tyObject:
result = isPartOfAux(a.sons[0], b, marker)
if result == arNo: result = isPartOfAux(a.n, b, marker)
of tyGenericInst, tyDistinct:
result = isPartOfAux(lastSon(a), b, marker)
of tyArray, tyArrayConstr, tySet, tyTuple:
for i in countup(0, sonsLen(a) - 1):
of tyArray, tyArrayConstr, tySet, tyTuple:
for i in countup(0, sonsLen(a) - 1):
result = isPartOfAux(a.sons[i], b, marker)
if result == arYes: return
if result == arYes: return
else: discard
proc isPartOf(a, b: PType): TAnalysisResult =
proc isPartOf(a, b: PType): TAnalysisResult =
## checks iff 'a' can be part of 'b'. Iterates over VALUE types!
var marker = initIntSet()
# watch out: parameters reversed because I'm too lazy to change the code...
@@ -70,14 +70,14 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
## type. Since however type analysis is more expensive, we perform it only
## if necessary.
##
## cases:
## cases:
##
## YES-cases:
## x <| x # for general trees
## x[] <| x
## x[i] <| x
## x.f <| x
##
##
## NO-cases:
## x !<| y # depending on type and symbol kind
## x[constA] !<| x[constB]
@@ -88,16 +88,16 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
##
## x[] ?<| y[] iff compatible type
##
##
##
## x[] ?<| y depending on type
##
##
if a.kind == b.kind:
case a.kind
of nkSym:
const varKinds = {skVar, skTemp, skProc}
# same symbol: aliasing:
if a.sym.id == b.sym.id: result = arYes
elif a.sym.kind in varKinds or b.sym.kind in varKinds:
elif a.sym.kind in varKinds or b.sym.kind in varKinds:
# actually, a param could alias a var but we know that cannot happen
# here. XXX make this more generic
result = arNo
@@ -110,11 +110,11 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
if len(a) >= 2 and len(b) >= 2:
# array accesses:
if result == arYes and isDeepConstExpr(a[1]) and isDeepConstExpr(b[1]):
# we know it's the same array and we have 2 constant indexes;
# if they are
# we know it's the same array and we have 2 constant indexes;
# if they are
var x = if a[1].kind == nkHiddenStdConv: a[1][1] else: a[1]
var y = if b[1].kind == nkHiddenStdConv: b[1][1] else: b[1]
if sameValue(x, y): result = arYes
else: result = arNo
# else: maybe and no are accurate
@@ -122,7 +122,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
# pointer derefs:
if result != arYes:
if isPartOf(a.typ, b.typ) != arNo: result = arMaybe
of nkDotExpr:
result = isPartOf(a[0], b[0])
if result != arNo:
@@ -135,7 +135,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
# weaken because of indirection:
if result != arYes:
if isPartOf(a.typ, b.typ) != arNo: result = arMaybe
of nkHiddenStdConv, nkHiddenSubConv, nkConv:
result = isPartOf(a[1], b[1])
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
@@ -144,7 +144,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
# Calls return a new location, so a default of ``arNo`` is fine.
else:
# go down recursively; this is quite demanding:
const
const
Ix0Kinds = {nkDotExpr, nkBracketExpr, nkObjUpConv, nkObjDownConv,
nkCheckedFieldExpr}
Ix1Kinds = {nkHiddenStdConv, nkHiddenSubConv, nkConv}
@@ -153,17 +153,17 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
of Ix0Kinds:
# a* !<| b.f iff a* !<| b
result = isPartOf(a, b[0])
of DerefKinds:
# a* !<| b[] iff
# a* !<| b[] iff
if isPartOf(a.typ, b.typ) != arNo:
result = isPartOf(a, b[0])
if result == arNo: result = arMaybe
of Ix1Kinds:
# a* !<| T(b) iff a* !<| b
result = isPartOf(a, b[1])
of nkSym:
# b is an atom, so we have to check a:
case a.kind
@@ -172,7 +172,7 @@ proc isPartOf*(a, b: PNode): TAnalysisResult =
result = isPartOf(a[0], b)
of Ix1Kinds:
result = isPartOf(a[1], b)
of DerefKinds:
if isPartOf(a.typ, b.typ) != arNo:
result = isPartOf(a[0], b)

View File

@@ -10,12 +10,12 @@
# this unit handles Nim sets; it implements bit sets
# the code here should be reused in the Nim standard library
type
type
TBitSet* = seq[int8] # we use byte here to avoid issues with
# cross-compiling; uint would be more efficient
# however
const
const
ElemSize* = sizeof(int8) * 8
proc bitSetInit*(b: var TBitSet, length: int)
@@ -30,42 +30,42 @@ proc bitSetEquals*(x, y: TBitSet): bool
proc bitSetContains*(x, y: TBitSet): bool
# implementation
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
proc bitSetIn(x: TBitSet, e: BiggestInt): bool =
result = (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) !=
toU8(0)
proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
assert(elem >= 0)
x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or
toU8(int(1 shl (elem mod ElemSize)))
proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
proc bitSetExcl(x: var TBitSet, elem: BiggestInt) =
x[int(elem div ElemSize)] = x[int(elem div ElemSize)] and
not toU8(int(1 shl (elem mod ElemSize)))
proc bitSetInit(b: var TBitSet, length: int) =
proc bitSetInit(b: var TBitSet, length: int) =
newSeq(b, length)
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
proc bitSetUnion(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] or y[i]
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
proc bitSetDiff(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] and not y[i]
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
proc bitSetSymDiff(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] xor y[i]
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
proc bitSetIntersect(x: var TBitSet, y: TBitSet) =
for i in countup(0, high(x)): x[i] = x[i] and y[i]
proc bitSetEquals(x, y: TBitSet): bool =
for i in countup(0, high(x)):
if x[i] != y[i]:
proc bitSetEquals(x, y: TBitSet): bool =
for i in countup(0, high(x)):
if x[i] != y[i]:
return false
result = true
proc bitSetContains(x, y: TBitSet): bool =
for i in countup(0, high(x)):
if (x[i] and not y[i]) != int8(0):
proc bitSetContains(x, y: TBitSet): bool =
for i in countup(0, high(x)):
if (x[i] and not y[i]) != int8(0):
return false
result = true

View File

@@ -30,39 +30,39 @@ type
#
# This is a good compromise between correctness and brevity. ;-)
const
const
cb64 = [
"A", "B", "C", "D", "E", "F", "G", "H", "I", "J", "K", "L", "M", "N",
"O", "P", "Q", "R", "S", "T" "U", "V", "W", "X", "Y", "Z",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"O", "P", "Q", "R", "S", "T" "U", "V", "W", "X", "Y", "Z",
"a", "b", "c", "d", "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
"o", "p", "q", "r", "s", "t", "u", "v", "w", "x", "y", "z",
"0", "1", "2", "3", "4", "5", "6", "7", "8", "9",
"_A", "_B"]
proc toBase64a(s: cstring, len: int): string =
## encodes `s` into base64 representation. After `lineLen` characters, a
## `newline` is added.
result = newStringOfCap(((len + 2) div 3) * 4)
var i = 0
while i < s.len - 2:
let a = ord(s[i])
let b = ord(s[i+1])
let c = ord(s[i+2])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)]
result.add cb64[c and 0x3F]
inc(i, 3)
if i < s.len-1:
let a = ord(s[i])
let b = ord(s[i+1])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2)]
elif i < s.len:
let a = ord(s[i])
result.add cb64[a shr 2]
result.add cb64[(a and 3) shl 4]
"_A", "_B"]
proc toBase64a(s: cstring, len: int): string =
## encodes `s` into base64 representation. After `lineLen` characters, a
## `newline` is added.
result = newStringOfCap(((len + 2) div 3) * 4)
var i = 0
while i < s.len - 2:
let a = ord(s[i])
let b = ord(s[i+1])
let c = ord(s[i+2])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2) or ((c and 0xC0) shr 6)]
result.add cb64[c and 0x3F]
inc(i, 3)
if i < s.len-1:
let a = ord(s[i])
let b = ord(s[i+1])
result.add cb64[a shr 2]
result.add cb64[((a and 3) shl 4) or ((b and 0xF0) shr 4)]
result.add cb64[((b and 0x0F) shl 2)]
elif i < s.len:
let a = ord(s[i])
result.add cb64[a shr 2]
result.add cb64[(a and 3) shl 4]
proc toBase64a(u: TUid): string = toBase64a(cast[cstring](u), sizeof(u))
@@ -73,7 +73,7 @@ proc hashSym(c: var MD5Context, s: PSym) =
c &= ":anon"
else:
var it = s.owner
while it != nil:
while it != nil:
hashSym(c, it)
c &= "."
it = s.owner
@@ -106,18 +106,18 @@ proc hashTree(c: var MD5Context, n: PNode) =
proc hashType(c: var MD5Context, t: PType) =
# modelled after 'typeToString'
if t == nil:
if t == nil:
c &= "\254"
return
var k = t.kind
md5Update(c, cast[cstring](addr(k)), 1)
if t.sym != nil and sfAnon notin t.sym.flags:
# t.n for literals, but not for e.g. objects!
if t.kind in {tyFloat, tyInt}: c.hashNode(t.n)
c.hashSym(t.sym)
case t.kind
of tyGenericBody, tyGenericInst, tyGenericInvocation:
for i in countup(0, sonsLen(t) -1 -ord(t.kind != tyGenericInvocation)):
@@ -135,10 +135,10 @@ proc hashType(c: var MD5Context, t: PType) =
of tyArrayConstr:
c.hashTree(t.sons[0].n)
c.hashType(t.sons[1])
of tyTuple:
of tyTuple:
if t.n != nil:
assert(sonsLen(t.n) == sonsLen(t))
for i in countup(0, sonsLen(t.n) - 1):
for i in countup(0, sonsLen(t.n) - 1):
assert(t.n.sons[i].kind == nkSym)
c &= t.n.sons[i].sym.name.s
c &= ":"
@@ -184,18 +184,18 @@ proc pushSym(w: PRodWriter, s: PSym) =
if iiTableGet(w.index.tab, s.id) == InvalidKey:
w.sstack.add(s)
proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
result: var string) =
if n == nil:
proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
result: var string) =
if n == nil:
# nil nodes have to be stored too:
result.add("()")
return
result.add('(')
encodeVInt(ord(n.kind), result)
encodeVInt(ord(n.kind), result)
# we do not write comments for now
# Line information takes easily 20% or more of the filesize! Therefore we
# omit line information if it is the same as the father's line information:
if fInfo.fileIndex != n.info.fileIndex:
if fInfo.fileIndex != n.info.fileIndex:
result.add('?')
encodeVInt(n.info.col, result)
result.add(',')
@@ -211,7 +211,7 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
result.add('?')
encodeVInt(n.info.col, result)
var f = n.flags * PersistentNodeFlags
if f != {}:
if f != {}:
result.add('$')
encodeVInt(cast[int32](f), result)
if n.typ != nil:
@@ -219,16 +219,16 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
encodeVInt(n.typ.id, result)
pushType(w, n.typ)
case n.kind
of nkCharLit..nkInt64Lit:
of nkCharLit..nkInt64Lit:
if n.intVal != 0:
result.add('!')
encodeVBiggestInt(n.intVal, result)
of nkFloatLit..nkFloat64Lit:
if n.floatVal != 0.0:
of nkFloatLit..nkFloat64Lit:
if n.floatVal != 0.0:
result.add('!')
encodeStr($n.floatVal, result)
of nkStrLit..nkTripleStrLit:
if n.strVal != "":
if n.strVal != "":
result.add('!')
encodeStr(n.strVal, result)
of nkIdent:
@@ -239,7 +239,7 @@ proc encodeNode(w: PRodWriter, fInfo: TLineInfo, n: PNode,
encodeVInt(n.sym.id, result)
pushSym(w, n.sym)
else:
for i in countup(0, sonsLen(n) - 1):
for i in countup(0, sonsLen(n) - 1):
encodeNode(w, n.info, n.sons[i], result)
add(result, ')')
@@ -268,9 +268,9 @@ proc encodeLoc(w: PRodWriter, loc: TLoc, result: var string) =
setLen(result, oldLen)
else:
add(result, '>')
proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t == nil:
proc encodeType(w: PRodWriter, t: PType, result: var string) =
if t == nil:
# nil nodes have to be stored too:
result.add("[]")
return
@@ -282,38 +282,38 @@ proc encodeType(w: PRodWriter, t: PType, result: var string) =
encodeVInt(ord(t.kind), result)
add(result, '+')
encodeVInt(t.id, result)
if t.n != nil:
if t.n != nil:
encodeNode(w, unknownLineInfo(), t.n, result)
if t.flags != {}:
if t.flags != {}:
add(result, '$')
encodeVInt(cast[int32](t.flags), result)
if t.callConv != low(t.callConv):
if t.callConv != low(t.callConv):
add(result, '?')
encodeVInt(ord(t.callConv), result)
if t.owner != nil:
if t.owner != nil:
add(result, '*')
encodeVInt(t.owner.id, result)
pushSym(w, t.owner)
if t.sym != nil:
if t.sym != nil:
add(result, '&')
encodeVInt(t.sym.id, result)
pushSym(w, t.sym)
if t.size != - 1:
if t.size != - 1:
add(result, '/')
encodeVBiggestInt(t.size, result)
if t.align != 2:
if t.align != 2:
add(result, '=')
encodeVInt(t.align, result)
encodeLoc(w, t.loc, result)
for i in countup(0, sonsLen(t) - 1):
if t.sons[i] == nil:
for i in countup(0, sonsLen(t) - 1):
if t.sons[i] == nil:
add(result, "^()")
else:
add(result, '^')
else:
add(result, '^')
encodeVInt(t.sons[i].id, result)
pushType(w, t.sons[i])
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo, result: var string) =
proc encodeLib(w: PRodWriter, lib: PLib, info: TLineInfo, result: var string) =
add(result, '|')
encodeVInt(ord(lib.kind), result)
add(result, '|')
@@ -352,10 +352,10 @@ proc encodeSym(w: PRodWriter, s: PSym, result: var string) =
if s.magic != mNone:
result.add('@')
encodeVInt(ord(s.magic), result)
if s.options != w.options:
if s.options != w.options:
result.add('!')
encodeVInt(cast[int32](s.options), result)
if s.position != 0:
if s.position != 0:
result.add('%')
encodeVInt(s.position, result)
if s.offset != - 1:
@@ -383,7 +383,7 @@ proc createDb() =
fullpath varchar(256) not null,
interfHash varchar(256) not null,
fullHash varchar(256) not null,
created timestamp not null default (DATETIME('now')),
);""")
@@ -397,7 +397,7 @@ proc createDb() =
foreign key (module) references module(id)
);""")
db.exec(sql"""
create table if not exists Type(
id integer primary key,

View File

@@ -9,33 +9,33 @@
## This module implements code generation for multi methods.
import
import
intsets, options, ast, astalgo, msgs, idents, renderer, types, magicsys,
sempass2, strutils
proc genConv(n: PNode, d: PType, downcast: bool): PNode =
proc genConv(n: PNode, d: PType, downcast: bool): PNode =
var dest = skipTypes(d, abstractPtrs)
var source = skipTypes(n.typ, abstractPtrs)
if (source.kind == tyObject) and (dest.kind == tyObject):
if (source.kind == tyObject) and (dest.kind == tyObject):
var diff = inheritanceDiff(dest, source)
if diff == high(int): internalError(n.info, "cgmeth.genConv")
if diff < 0:
if diff < 0:
result = newNodeIT(nkObjUpConv, n.info, d)
addSon(result, n)
if downcast: internalError(n.info, "cgmeth.genConv: no upcast allowed")
elif diff > 0:
elif diff > 0:
result = newNodeIT(nkObjDownConv, n.info, d)
addSon(result, n)
if not downcast:
if not downcast:
internalError(n.info, "cgmeth.genConv: no downcast allowed")
else:
else:
result = n
else:
else:
result = n
proc methodCall*(n: PNode): PNode =
proc methodCall*(n: PNode): PNode =
result = n
# replace ordinary method by dispatcher method:
# replace ordinary method by dispatcher method:
var disp = lastSon(result.sons[0].sym.ast).sym
assert sfDispatcher in disp.flags
result.sons[0].sym = disp
@@ -47,23 +47,23 @@ proc methodCall*(n: PNode): PNode =
var
gMethods: seq[tuple[methods: TSymSeq, dispatcher: PSym]] = @[]
proc sameMethodBucket(a, b: PSym): bool =
proc sameMethodBucket(a, b: PSym): bool =
result = false
if a.name.id != b.name.id: return
if sonsLen(a.typ) != sonsLen(b.typ):
if a.name.id != b.name.id: return
if sonsLen(a.typ) != sonsLen(b.typ):
return # check for return type:
if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]): return
for i in countup(1, sonsLen(a.typ) - 1):
if not sameTypeOrNil(a.typ.sons[0], b.typ.sons[0]): return
for i in countup(1, sonsLen(a.typ) - 1):
var aa = a.typ.sons[i]
var bb = b.typ.sons[i]
while true:
while true:
aa = skipTypes(aa, {tyGenericInst})
bb = skipTypes(bb, {tyGenericInst})
if (aa.kind == bb.kind) and (aa.kind in {tyVar, tyPtr, tyRef}):
if (aa.kind == bb.kind) and (aa.kind in {tyVar, tyPtr, tyRef}):
aa = aa.lastSon
bb = bb.lastSon
else:
break
else:
break
if sameType(aa, bb) or
(aa.kind == tyObject) and (bb.kind == tyObject) and
(inheritanceDiff(bb, aa) < 0):
@@ -140,7 +140,7 @@ proc methodDef*(s: PSym, fromCache: bool) =
attachDispatcher(s, lastSon(disp.ast))
fixupDispatcher(s, disp)
when useEffectSystem: checkMethodEffects(disp, s)
return
return
# create a new dispatcher:
add(gMethods, (methods: @[s], dispatcher: createDispatcher(s)))
if fromCache:
@@ -154,35 +154,35 @@ proc relevantCol(methods: TSymSeq, col: int): bool =
let t2 = skipTypes(methods[i].typ.sons[col], skipPtrs)
if not sameType(t2, t):
return true
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
for col in countup(1, sonsLen(a.typ) - 1):
if contains(relevantCols, col):
proc cmpSignatures(a, b: PSym, relevantCols: IntSet): int =
for col in countup(1, sonsLen(a.typ) - 1):
if contains(relevantCols, col):
var aa = skipTypes(a.typ.sons[col], skipPtrs)
var bb = skipTypes(b.typ.sons[col], skipPtrs)
var d = inheritanceDiff(aa, bb)
if (d != high(int)):
if (d != high(int)):
return d
proc sortBucket(a: var TSymSeq, relevantCols: IntSet) =
proc sortBucket(a: var TSymSeq, relevantCols: IntSet) =
# we use shellsort here; fast and simple
var n = len(a)
var h = 1
while true:
while true:
h = 3 * h + 1
if h > n: break
while true:
if h > n: break
while true:
h = h div 3
for i in countup(h, n - 1):
for i in countup(h, n - 1):
var v = a[i]
var j = i
while cmpSignatures(a[j - h], v, relevantCols) >= 0:
while cmpSignatures(a[j - h], v, relevantCols) >= 0:
a[j] = a[j - h]
j = j - h
if j < h: break
if j < h: break
a[j] = v
if h == 1: break
if h == 1: break
proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
var base = lastSon(methods[0].ast).sym
result = base
@@ -199,7 +199,7 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
addSon(isn, newSymNode(iss))
addSon(isn, newSymNode(base.typ.n.sons[col].sym))
addSon(isn, newNodeIT(nkType, base.info, curr.typ.sons[col]))
if cond != nil:
if cond != nil:
var a = newNodeIT(nkCall, base.info, getSysType(tyBool))
addSon(a, newSymNode(ands))
addSon(a, cond)
@@ -209,8 +209,8 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
cond = isn
var call = newNodeI(nkCall, base.info)
addSon(call, newSymNode(curr))
for col in countup(1, paramLen - 1):
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
for col in countup(1, paramLen - 1):
addSon(call, genConv(newSymNode(base.typ.n.sons[col].sym),
curr.typ.sons[col], false))
var ret: PNode
if base.typ.sons[0] != nil:
@@ -230,11 +230,11 @@ proc genDispatcher(methods: TSymSeq, relevantCols: IntSet): PSym =
disp = ret
result.ast.sons[bodyPos] = disp
proc generateMethodDispatchers*(): PNode =
proc generateMethodDispatchers*(): PNode =
result = newNode(nkStmtList)
for bucket in countup(0, len(gMethods) - 1):
for bucket in countup(0, len(gMethods) - 1):
var relevantCols = initIntSet()
for col in countup(1, sonsLen(gMethods[bucket].methods[0].typ) - 1):
for col in countup(1, sonsLen(gMethods[bucket].methods[0].typ) - 1):
if relevantCol(gMethods[bucket].methods, col): incl(relevantCols, col)
sortBucket(gMethods[bucket].methods, relevantCols)
addSon(result,

View File

@@ -10,10 +10,10 @@
# This module implements a new documentation generator that runs after
# semantic checking.
import
import
os, options, ast, astalgo, msgs, ropes, idents, passes, docgen
type
type
TGen = object of TPassContext
doc: PDoc
module: PSym
@@ -29,12 +29,12 @@ proc close(p: PPassContext, n: PNode): PNode =
except IOError:
discard
proc processNode(c: PPassContext, n: PNode): PNode =
proc processNode(c: PPassContext, n: PNode): PNode =
result = n
var g = PGen(c)
generateDoc(g.doc, n)
proc myOpen(module: PSym): PPassContext =
proc myOpen(module: PSym): PPassContext =
var g: PGen
new(g)
g.module = module
@@ -45,5 +45,5 @@ proc myOpen(module: PSym): PPassContext =
const docgen2Pass* = makePass(open = myOpen, process = processNode, close = close)
proc finishDoc2Pass*(project: string) =
proc finishDoc2Pass*(project: string) =
discard

View File

@@ -31,7 +31,7 @@ proc evalTemplateAux(templ, actual: PNode, c: var TemplCtx, result: PNode) =
for y in items(x): result.add(y)
else:
result.add copyTree(x)
case templ.kind
of nkSym:
var s = templ.sym
@@ -81,7 +81,7 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode =
if totalParams > expectedRegularParams + genericParams:
globalError(n.info, errWrongNumberOfArguments)
result = newNodeI(nkArgList, n.info)
for i in 1 .. givenRegularParams:
result.addSon n.sons[i]
@@ -96,7 +96,7 @@ proc evalTemplateArgs(n: PNode, s: PSym): PNode =
addSon(result, ast.emptyNode)
else:
addSon(result, default.copyTree)
# add any generic paramaters
for i in 1 .. genericParams:
result.addSon n.sons[givenRegularParams + i]

View File

@@ -9,18 +9,18 @@
# This module implements Nim's standard template filter.
import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
renderer, filters
proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream
# #! template(subsChar='$', metaChar='#') | standard(version="0.7.2")
# implementation
type
TParseState = enum
type
TParseState = enum
psDirective, psTempl
TTmplParser{.final.} = object
TTmplParser{.final.} = object
inp: PLLStream
state: TParseState
info: TLineInfo
@@ -33,18 +33,18 @@ type
pendingExprLine: bool
const
const
PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '.', '_'}
proc newLine(p: var TTmplParser) =
proc newLine(p: var TTmplParser) =
llStreamWrite(p.outp, repeat(')', p.emitPar))
p.emitPar = 0
if p.info.line > int16(1): llStreamWrite(p.outp, "\n")
if p.pendingExprLine:
llStreamWrite(p.outp, spaces(2))
p.pendingExprLine = false
proc scanPar(p: var TTmplParser, d: int) =
proc scanPar(p: var TTmplParser, d: int) =
var i = d
while true:
case p.x[i]
@@ -58,44 +58,44 @@ proc scanPar(p: var TTmplParser, d: int) =
else: discard
inc(i)
proc withInExpr(p: TTmplParser): bool {.inline.} =
proc withInExpr(p: TTmplParser): bool {.inline.} =
result = p.par > 0 or p.bracket > 0 or p.curly > 0
proc parseLine(p: var TTmplParser) =
var
proc parseLine(p: var TTmplParser) =
var
d, j, curly: int
keyw: string
j = 0
while p.x[j] == ' ': inc(j)
if (p.x[0] == p.nimDirective) and (p.x[0 + 1] == '!'):
if (p.x[0] == p.nimDirective) and (p.x[0 + 1] == '!'):
newLine(p)
elif (p.x[j] == p.nimDirective):
elif (p.x[j] == p.nimDirective):
newLine(p)
inc(j)
while p.x[j] == ' ': inc(j)
d = j
keyw = ""
while p.x[j] in PatternChars:
while p.x[j] in PatternChars:
add(keyw, p.x[j])
inc(j)
scanPar(p, j)
p.pendingExprLine = withInExpr(p) or llstream.endsWithOpr(p.x)
case whichKeyword(keyw)
of wEnd:
if p.indent >= 2:
of wEnd:
if p.indent >= 2:
dec(p.indent, 2)
else:
else:
p.info.col = int16(j)
localError(p.info, errXNotAllowedHere, "end")
llStreamWrite(p.outp, spaces(p.indent))
llStreamWrite(p.outp, "#end")
of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator,
wConverter, wMacro, wTemplate, wMethod:
of wIf, wWhen, wTry, wWhile, wFor, wBlock, wCase, wProc, wIterator,
wConverter, wMacro, wTemplate, wMethod:
llStreamWrite(p.outp, spaces(p.indent))
llStreamWrite(p.outp, substr(p.x, d))
inc(p.indent, 2)
of wElif, wOf, wElse, wExcept, wFinally:
of wElif, wOf, wElse, wExcept, wFinally:
llStreamWrite(p.outp, spaces(p.indent - 2))
llStreamWrite(p.outp, substr(p.x, d))
of wLet, wVar, wConst, wType:
@@ -108,7 +108,7 @@ proc parseLine(p: var TTmplParser) =
llStreamWrite(p.outp, spaces(p.indent))
llStreamWrite(p.outp, substr(p.x, d))
p.state = psDirective
else:
else:
# data line
# reset counters
p.par = 0
@@ -116,42 +116,42 @@ proc parseLine(p: var TTmplParser) =
p.bracket = 0
j = 0
case p.state
of psTempl:
of psTempl:
# next line of string literal:
llStreamWrite(p.outp, p.conc)
llStreamWrite(p.outp, "\n")
llStreamWrite(p.outp, spaces(p.indent + 2))
llStreamWrite(p.outp, "\"")
of psDirective:
of psDirective:
newLine(p)
llStreamWrite(p.outp, spaces(p.indent))
llStreamWrite(p.outp, p.emit)
llStreamWrite(p.outp, "(\"")
inc(p.emitPar)
p.state = psTempl
while true:
while true:
case p.x[j]
of '\0':
break
of '\x01'..'\x1F', '\x80'..'\xFF':
of '\0':
break
of '\x01'..'\x1F', '\x80'..'\xFF':
llStreamWrite(p.outp, "\\x")
llStreamWrite(p.outp, toHex(ord(p.x[j]), 2))
inc(j)
of '\\':
of '\\':
llStreamWrite(p.outp, "\\\\")
inc(j)
of '\'':
of '\'':
llStreamWrite(p.outp, "\\\'")
inc(j)
of '\"':
of '\"':
llStreamWrite(p.outp, "\\\"")
inc(j)
else:
if p.x[j] == p.subsChar:
else:
if p.x[j] == p.subsChar:
# parse Nim expression:
inc(j)
case p.x[j]
of '{':
of '{':
p.info.col = int16(j)
llStreamWrite(p.outp, '\"')
llStreamWrite(p.outp, p.conc)
@@ -159,50 +159,50 @@ proc parseLine(p: var TTmplParser) =
llStreamWrite(p.outp, '(')
inc(j)
curly = 0
while true:
while true:
case p.x[j]
of '\0':
of '\0':
localError(p.info, errXExpected, "}")
break
of '{':
of '{':
inc(j)
inc(curly)
llStreamWrite(p.outp, '{')
of '}':
of '}':
inc(j)
if curly == 0: break
if curly == 0: break
if curly > 0: dec(curly)
llStreamWrite(p.outp, '}')
else:
else:
llStreamWrite(p.outp, p.x[j])
inc(j)
llStreamWrite(p.outp, ')')
llStreamWrite(p.outp, p.conc)
llStreamWrite(p.outp, '\"')
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF':
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF':
llStreamWrite(p.outp, '\"')
llStreamWrite(p.outp, p.conc)
llStreamWrite(p.outp, p.toStr)
llStreamWrite(p.outp, '(')
while p.x[j] in PatternChars:
while p.x[j] in PatternChars:
llStreamWrite(p.outp, p.x[j])
inc(j)
llStreamWrite(p.outp, ')')
llStreamWrite(p.outp, p.conc)
llStreamWrite(p.outp, '\"')
else:
if p.x[j] == p.subsChar:
else:
if p.x[j] == p.subsChar:
llStreamWrite(p.outp, p.subsChar)
inc(j)
else:
else:
p.info.col = int16(j)
localError(p.info, errInvalidExpression, "$")
else:
else:
llStreamWrite(p.outp, p.x[j])
inc(j)
llStreamWrite(p.outp, "\\n\"")
proc filterTmpl(stdin: PLLStream, filename: string, call: PNode): PLLStream =
proc filterTmpl(stdin: PLLStream, filename: string, call: PNode): PLLStream =
var p: TTmplParser
p.info = newLineInfo(filename, 0, 0)
p.outp = llStreamOpen("")

View File

@@ -10,7 +10,7 @@
# This module implements Nim's simple filters and helpers for filters.
import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
renderer
proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream
@@ -21,40 +21,40 @@ proc strArg*(n: PNode, name: string, pos: int, default: string): string
proc boolArg*(n: PNode, name: string, pos: int, default: bool): bool
# implementation
proc invalidPragma(n: PNode) =
proc invalidPragma(n: PNode) =
localError(n.info, errXNotAllowedHere, renderTree(n, {renderNoComments}))
proc getArg(n: PNode, name: string, pos: int): PNode =
proc getArg(n: PNode, name: string, pos: int): PNode =
result = nil
if n.kind in {nkEmpty..nkNilLit}: return
for i in countup(1, sonsLen(n) - 1):
if n.sons[i].kind == nkExprEqExpr:
if n.kind in {nkEmpty..nkNilLit}: return
for i in countup(1, sonsLen(n) - 1):
if n.sons[i].kind == nkExprEqExpr:
if n.sons[i].sons[0].kind != nkIdent: invalidPragma(n)
if identEq(n.sons[i].sons[0].ident, name):
if identEq(n.sons[i].sons[0].ident, name):
return n.sons[i].sons[1]
elif i == pos:
elif i == pos:
return n.sons[i]
proc charArg(n: PNode, name: string, pos: int, default: char): char =
proc charArg(n: PNode, name: string, pos: int, default: char): char =
var x = getArg(n, name, pos)
if x == nil: result = default
elif x.kind == nkCharLit: result = chr(int(x.intVal))
else: invalidPragma(n)
proc strArg(n: PNode, name: string, pos: int, default: string): string =
proc strArg(n: PNode, name: string, pos: int, default: string): string =
var x = getArg(n, name, pos)
if x == nil: result = default
elif x.kind in {nkStrLit..nkTripleStrLit}: result = x.strVal
else: invalidPragma(n)
proc boolArg(n: PNode, name: string, pos: int, default: bool): bool =
proc boolArg(n: PNode, name: string, pos: int, default: bool): bool =
var x = getArg(n, name, pos)
if x == nil: result = default
elif (x.kind == nkIdent) and identEq(x.ident, "true"): result = true
elif (x.kind == nkIdent) and identEq(x.ident, "false"): result = false
else: invalidPragma(n)
proc filterStrip(stdin: PLLStream, filename: string, call: PNode): PLLStream =
proc filterStrip(stdin: PLLStream, filename: string, call: PNode): PLLStream =
var pattern = strArg(call, "startswith", 1, "")
var leading = boolArg(call, "leading", 2, true)
var trailing = boolArg(call, "trailing", 3, true)
@@ -62,13 +62,13 @@ proc filterStrip(stdin: PLLStream, filename: string, call: PNode): PLLStream =
var line = newStringOfCap(80)
while llStreamReadLine(stdin, line):
var stripped = strip(line, leading, trailing)
if (len(pattern) == 0) or startsWith(stripped, pattern):
if (len(pattern) == 0) or startsWith(stripped, pattern):
llStreamWriteln(result, stripped)
else:
else:
llStreamWriteln(result, line)
llStreamClose(stdin)
proc filterReplace(stdin: PLLStream, filename: string, call: PNode): PLLStream =
proc filterReplace(stdin: PLLStream, filename: string, call: PNode): PLLStream =
var sub = strArg(call, "sub", 1, "")
if len(sub) == 0: invalidPragma(call)
var by = strArg(call, "by", 2, "")

View File

@@ -14,11 +14,11 @@ import ast, astalgo
const
someCmp = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
mEqUntracedRef, mLeI, mLeF64, mLeU, mLeU64, mLeEnum,
mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtU64, mLtEnum,
mLeCh, mLeB, mLePtr, mLtI, mLtF64, mLtU, mLtU64, mLtEnum,
mLtCh, mLtB, mLtPtr}
proc isCounter(s: PSym): bool {.inline.} =
s.kind in {skResult, skVar, skLet, skTemp} and
s.kind in {skResult, skVar, skLet, skTemp} and
{sfGlobal, sfAddrTaken} * s.flags == {}
proc isCall(n: PNode): bool {.inline.} =
@@ -29,7 +29,7 @@ proc fromSystem(op: PSym): bool = sfSystemModule in getModule(op).flags
proc getCounter(lastStmt: PNode): PSym =
if lastStmt.isCall:
let op = lastStmt.sym
if op.magic in {mDec, mInc} or
if op.magic in {mDec, mInc} or
((op.name.s == "+=" or op.name.s == "-=") and op.fromSystem):
if op[1].kind == nkSym and isCounter(op[1].sym):
result = op[1].sym
@@ -67,7 +67,7 @@ proc extractForLoop*(loop, fullTree: PNode): ForLoop =
if not cond.isCall: return
if cond[0].sym.magic notin someCmp: return
var lastStmt = loop[1]
while lastStmt.kind in {nkStmtList, nkStmtListExpr}:
lastStmt = lastStmt.lastSon
@@ -76,7 +76,7 @@ proc extractForLoop*(loop, fullTree: PNode): ForLoop =
if counter.isNil or counter.ast.isNil: return
template `=~`(a, b): expr = a.kind == nkSym and a.sym == b
if cond[1] =~ counter or cond[2] =~ counter:
# ok, now check 'counter' is not used *after* the loop
if counterInTree(fullTree, loop, counter): return

View File

@@ -28,7 +28,7 @@ proc evalPattern(c: PContext, n, orig: PNode): PNode =
else:
result = semDirectOp(c, n, {})
if optHints in gOptions and hintPattern in gNotes:
message(orig.info, hintPattern, rule & " --> '" &
message(orig.info, hintPattern, rule & " --> '" &
renderTree(result, {renderNoComments}) & "'")
proc applyPatterns(c: PContext, n: PNode): PNode =
@@ -68,7 +68,7 @@ proc hlo(c: PContext, n: PNode): PNode =
result = n
else:
if n.kind in {nkFastAsgn, nkAsgn, nkIdentDefs, nkVarTuple} and
n.sons[0].kind == nkSym and
n.sons[0].kind == nkSym and
{sfGlobal, sfPure} * n.sons[0].sym.flags == {sfGlobal, sfPure}:
# do not optimize 'var g {.global} = re(...)' again!
return n

View File

@@ -11,13 +11,13 @@
# An identifier is a shared immutable string that can be compared by its
# id. This module is essential for the compiler's performance.
import
import
hashes, strutils, etcpriv
type
type
TIdObj* = object of RootObj
id*: int # unique id; use this for comparisons and not the pointers
PIdObj* = ref TIdObj
PIdent* = ref TIdent
TIdent*{.acyclic.} = object of TIdObj
@@ -45,12 +45,12 @@ proc cmpIgnoreStyle(a, b: cstring, blen: int): int =
if aa >= 'A' and aa <= 'Z': aa = chr(ord(aa) + (ord('a') - ord('A')))
if bb >= 'A' and bb <= 'Z': bb = chr(ord(bb) + (ord('a') - ord('A')))
result = ord(aa) - ord(bb)
if (result != 0) or (aa == '\0'): break
if (result != 0) or (aa == '\0'): break
inc(i)
inc(j)
if result == 0:
if a[i] != '\0': result = 1
proc cmpExact(a, b: cstring, blen: int): int =
var i = 0
var j = 0
@@ -59,10 +59,10 @@ proc cmpExact(a, b: cstring, blen: int): int =
var aa = a[i]
var bb = b[j]
result = ord(aa) - ord(bb)
if (result != 0) or (aa == '\0'): break
if (result != 0) or (aa == '\0'): break
inc(i)
inc(j)
if result == 0:
if result == 0:
if a[i] != '\0': result = 1
var wordCounter = 1
@@ -72,14 +72,14 @@ proc getIdent*(identifier: cstring, length: int, h: Hash): PIdent =
result = buckets[idx]
var last: PIdent = nil
var id = 0
while result != nil:
if cmpExact(cstring(result.s), identifier, length) == 0:
if last != nil:
while result != nil:
if cmpExact(cstring(result.s), identifier, length) == 0:
if last != nil:
# make access to last looked up identifier faster:
last.next = result.next
result.next = buckets[idx]
buckets[idx] = result
return
return
elif cmpIgnoreStyle(cstring(result.s), identifier, length) == 0:
assert((id == 0) or (id == result.id))
id = result.id
@@ -91,20 +91,20 @@ proc getIdent*(identifier: cstring, length: int, h: Hash): PIdent =
for i in countup(0, length - 1): result.s[i] = identifier[i]
result.next = buckets[idx]
buckets[idx] = result
if id == 0:
if id == 0:
inc(wordCounter)
result.id = -wordCounter
else:
else:
result.id = id
proc getIdent*(identifier: string): PIdent =
result = getIdent(cstring(identifier), len(identifier),
proc getIdent*(identifier: string): PIdent =
result = getIdent(cstring(identifier), len(identifier),
hashIgnoreStyle(identifier))
proc getIdent*(identifier: string, h: Hash): PIdent =
proc getIdent*(identifier: string, h: Hash): PIdent =
result = getIdent(cstring(identifier), len(identifier), h)
proc identEq*(id: PIdent, name: string): bool =
proc identEq*(id: PIdent, name: string): bool =
result = id.id == getIdent(name).id
var idAnon* = getIdent":anonymous"

View File

@@ -10,7 +10,7 @@
# This module implements a generic doubled linked list.
# TODO Remove this and replace it with something sensible
import os
type
type
PListEntry* = ref TListEntry
TListEntry* = object of RootObj
prev*, next*: PListEntry
@@ -25,68 +25,68 @@ type
TCompareProc* = proc (entry: PListEntry, closure: pointer): bool {.nimcall.}
proc initLinkedList*(list: var TLinkedList) =
proc initLinkedList*(list: var TLinkedList) =
list.counter = 0
list.head = nil
list.tail = nil
proc append*(list: var TLinkedList, entry: PListEntry) =
proc append*(list: var TLinkedList, entry: PListEntry) =
inc(list.counter)
entry.next = nil
entry.prev = list.tail
if list.tail != nil:
if list.tail != nil:
assert(list.tail.next == nil)
list.tail.next = entry
list.tail = entry
if list.head == nil: list.head = entry
proc contains*(list: TLinkedList, data: string): bool =
proc contains*(list: TLinkedList, data: string): bool =
var it = list.head
while it != nil:
if PStrEntry(it).data == data:
while it != nil:
if PStrEntry(it).data == data:
return true
it = it.next
proc newStrEntry(data: string): PStrEntry =
proc newStrEntry(data: string): PStrEntry =
new(result)
result.data = data
proc appendStr*(list: var TLinkedList, data: string) =
proc appendStr*(list: var TLinkedList, data: string) =
append(list, newStrEntry(data))
proc includeStr*(list: var TLinkedList, data: string): bool =
proc includeStr*(list: var TLinkedList, data: string): bool =
if contains(list, data): return true
appendStr(list, data) # else: add to list
proc prepend*(list: var TLinkedList, entry: PListEntry) =
proc prepend*(list: var TLinkedList, entry: PListEntry) =
inc(list.counter)
entry.prev = nil
entry.next = list.head
if list.head != nil:
if list.head != nil:
assert(list.head.prev == nil)
list.head.prev = entry
list.head = entry
if list.tail == nil: list.tail = entry
proc prependStr*(list: var TLinkedList, data: string) =
proc prependStr*(list: var TLinkedList, data: string) =
prepend(list, newStrEntry(data))
proc insertBefore*(list: var TLinkedList, pos, entry: PListEntry) =
proc insertBefore*(list: var TLinkedList, pos, entry: PListEntry) =
assert(pos != nil)
if pos == list.head:
if pos == list.head:
prepend(list, entry)
else:
else:
inc(list.counter)
entry.next = pos
entry.prev = pos.prev
if pos.prev != nil: pos.prev.next = entry
pos.prev = entry
proc remove*(list: var TLinkedList, entry: PListEntry) =
proc remove*(list: var TLinkedList, entry: PListEntry) =
dec(list.counter)
if entry == list.tail:
if entry == list.tail:
list.tail = entry.prev
if entry == list.head:
if entry == list.head:
list.head = entry.next
if entry.next != nil: entry.next.prev = entry.prev
if entry.prev != nil: entry.prev.next = entry.next
@@ -112,8 +112,8 @@ proc excludePath*(list: var TLinkedList, data: string) =
remove(list, it)
it = nxt
proc find*(list: TLinkedList, fn: TCompareProc, closure: pointer): PListEntry =
proc find*(list: TLinkedList, fn: TCompareProc, closure: pointer): PListEntry =
result = list.head
while result != nil:
if fn(result, closure): return
if fn(result, closure): return
result = result.next

View File

@@ -9,7 +9,7 @@
# Built-in types and compilerprocs are registered here.
import
import
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread
var systemModule*: PSym
@@ -29,23 +29,23 @@ var
proc nilOrSysInt*: PType = gSysTypes[tyInt]
proc registerSysType(t: PType) =
proc registerSysType(t: PType) =
if gSysTypes[t.kind] == nil: gSysTypes[t.kind] = t
proc newSysType(kind: TTypeKind, size: int): PType =
proc newSysType(kind: TTypeKind, size: int): PType =
result = newType(kind, systemModule)
result.size = size
result.align = size.int16
proc getSysSym(name: string): PSym =
proc getSysSym(name: string): PSym =
result = strTableGet(systemModule.tab, getIdent(name))
if result == nil:
if result == nil:
rawMessage(errSystemNeeds, name)
result = newSym(skError, getIdent(name), systemModule, systemModule.info)
result.typ = newType(tyError, systemModule)
if result.kind == skStub: loadStub(result)
if result.kind == skAlias: result = result.owner
proc getSysMagic*(name: string, m: TMagic): PSym =
var ti: TIdentIter
let id = getIdent(name)
@@ -57,13 +57,13 @@ proc getSysMagic*(name: string, m: TMagic): PSym =
rawMessage(errSystemNeeds, name)
result = newSym(skError, id, systemModule, systemModule.info)
result.typ = newType(tyError, systemModule)
proc sysTypeFromName*(name: string): PType =
proc sysTypeFromName*(name: string): PType =
result = getSysSym(name).typ
proc getSysType(kind: TTypeKind): PType =
proc getSysType(kind: TTypeKind): PType =
result = gSysTypes[kind]
if result == nil:
if result == nil:
case kind
of tyInt: result = sysTypeFromName("int")
of tyInt8: result = sysTypeFromName("int8")
@@ -87,7 +87,7 @@ proc getSysType(kind: TTypeKind): PType =
of tyNil: result = newSysType(tyNil, ptrSize)
else: internalError("request for typekind: " & $kind)
gSysTypes[kind] = result
if result.kind != kind:
if result.kind != kind:
internalError("wanted: " & $kind & " got: " & $result.kind)
if result == nil: internalError("type not found: " & $kind)
@@ -163,7 +163,7 @@ proc setIntLitType*(result: PNode) =
result.typ = getSysType(tyInt64)
else: internalError(result.info, "invalid int size")
proc getCompilerProc(name: string): PSym =
proc getCompilerProc(name: string): PSym =
var ident = getIdent(name, hashIgnoreStyle(name))
result = strTableGet(compilerprocs, ident)
if result == nil:

View File

@@ -11,8 +11,8 @@
import parseutils, strutils, strtabs, os, options, msgs, lists
proc addPath*(path: string, info: TLineInfo) =
if not contains(options.searchPaths, path):
proc addPath*(path: string, info: TLineInfo) =
if not contains(options.searchPaths, path):
lists.prependStr(options.searchPaths, path)
proc versionSplitPos(s: string): int =
@@ -23,7 +23,7 @@ proc versionSplitPos(s: string): int =
const
latest = "head"
proc `<.`(a, b: string): bool =
proc `<.`(a, b: string): bool =
# wether a has a smaller version than b:
if a == latest: return false
var i = 0

View File

@@ -10,7 +10,7 @@
## exposes the Nim VM to clients.
import
ast, modules, passes, passaux, condsyms,
ast, modules, passes, passaux, condsyms,
options, nimconf, lists, sem, semdata, llstream, vm
proc execute*(program: string) =

View File

@@ -12,10 +12,10 @@
# handling that exists! Only at line endings checks are necessary
# if the buffer needs refilling.
import
import
llstream, strutils
const
const
Lrz* = ' '
Apo* = '\''
Tabulator* = '\x09'
@@ -27,7 +27,7 @@ const
BACKSPACE* = '\x08'
VT* = '\x0B'
const
const
EndOfFile* = '\0' # end of file marker
# A little picture makes everything clear :-)
# buf:
@@ -36,7 +36,7 @@ const
#
NewLines* = {CR, LF}
type
type
TBaseLexer* = object of RootObj
bufpos*: int
buf*: cstring
@@ -46,9 +46,9 @@ type
# private data:
sentinel*: int
lineStart*: int # index of last line start in buffer
proc openBaseLexer*(L: var TBaseLexer, inputstream: PLLStream,
proc openBaseLexer*(L: var TBaseLexer, inputstream: PLLStream,
bufLen: int = 8192)
# 8K is a reasonable buffer size
proc closeBaseLexer*(L: var TBaseLexer)
@@ -64,15 +64,15 @@ proc handleLF*(L: var TBaseLexer, pos: int): int
# of the LF.
# implementation
const
const
chrSize = sizeof(char)
proc closeBaseLexer(L: var TBaseLexer) =
proc closeBaseLexer(L: var TBaseLexer) =
dealloc(L.buf)
llStreamClose(L.stream)
proc fillBuffer(L: var TBaseLexer) =
var
proc fillBuffer(L: var TBaseLexer) =
var
charsRead, toCopy, s: int # all are in characters,
# not bytes (in case this
# is not the same)
@@ -82,68 +82,68 @@ proc fillBuffer(L: var TBaseLexer) =
assert(L.sentinel < L.bufLen)
toCopy = L.bufLen - L.sentinel - 1
assert(toCopy >= 0)
if toCopy > 0:
moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize)
if toCopy > 0:
moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize)
# "moveMem" handles overlapping regions
charsRead = llStreamRead(L.stream, addr(L.buf[toCopy]),
charsRead = llStreamRead(L.stream, addr(L.buf[toCopy]),
(L.sentinel + 1) * chrSize) div chrSize
s = toCopy + charsRead
if charsRead < L.sentinel + 1:
if charsRead < L.sentinel + 1:
L.buf[s] = EndOfFile # set end marker
L.sentinel = s
else:
else:
# compute sentinel:
dec(s) # BUGFIX (valgrind)
while true:
while true:
assert(s < L.bufLen)
while (s >= 0) and not (L.buf[s] in NewLines): dec(s)
if s >= 0:
if s >= 0:
# we found an appropriate character for a sentinel:
L.sentinel = s
break
else:
break
else:
# rather than to give up here because the line is too long,
# double the buffer's size and try again:
oldBufLen = L.bufLen
L.bufLen = L.bufLen * 2
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize))
assert(L.bufLen - oldBufLen == oldBufLen)
charsRead = llStreamRead(L.stream, addr(L.buf[oldBufLen]),
charsRead = llStreamRead(L.stream, addr(L.buf[oldBufLen]),
oldBufLen * chrSize) div chrSize
if charsRead < oldBufLen:
if charsRead < oldBufLen:
L.buf[oldBufLen + charsRead] = EndOfFile
L.sentinel = oldBufLen + charsRead
break
break
s = L.bufLen - 1
proc fillBaseLexer(L: var TBaseLexer, pos: int): int =
proc fillBaseLexer(L: var TBaseLexer, pos: int): int =
assert(pos <= L.sentinel)
if pos < L.sentinel:
if pos < L.sentinel:
result = pos + 1 # nothing to do
else:
else:
fillBuffer(L)
L.bufpos = 0 # XXX: is this really correct?
result = 0
L.lineStart = result
proc handleCR(L: var TBaseLexer, pos: int): int =
proc handleCR(L: var TBaseLexer, pos: int): int =
assert(L.buf[pos] == CR)
inc(L.lineNumber)
result = fillBaseLexer(L, pos)
if L.buf[result] == LF:
if L.buf[result] == LF:
result = fillBaseLexer(L, result)
proc handleLF(L: var TBaseLexer, pos: int): int =
proc handleLF(L: var TBaseLexer, pos: int): int =
assert(L.buf[pos] == LF)
inc(L.lineNumber)
result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result;
proc skipUTF8BOM(L: var TBaseLexer) =
proc skipUTF8BOM(L: var TBaseLexer) =
if L.buf[0] == '\xEF' and L.buf[1] == '\xBB' and L.buf[2] == '\xBF':
inc(L.bufpos, 3)
inc(L.lineStart, 3)
proc openBaseLexer(L: var TBaseLexer, inputstream: PLLStream, bufLen = 8192) =
proc openBaseLexer(L: var TBaseLexer, inputstream: PLLStream, bufLen = 8192) =
assert(bufLen > 0)
L.bufpos = 0
L.bufLen = bufLen
@@ -155,15 +155,15 @@ proc openBaseLexer(L: var TBaseLexer, inputstream: PLLStream, bufLen = 8192) =
fillBuffer(L)
skipUTF8BOM(L)
proc getColNumber(L: TBaseLexer, pos: int): int =
proc getColNumber(L: TBaseLexer, pos: int): int =
result = abs(pos - L.lineStart)
proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
result = ""
var i = L.lineStart
while not (L.buf[i] in {CR, LF, EndOfFile}):
while not (L.buf[i] in {CR, LF, EndOfFile}):
add(result, L.buf[i])
inc(i)
result.add("\n")
if marker:
if marker:
result.add(spaces(getColNumber(L, L.bufpos)) & '^' & "\n")

View File

@@ -9,7 +9,7 @@
# this unit handles Nim sets; it implements symbolic sets
import
import
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer
proc toBitSet*(s: PNode, b: var TBitSet)
@@ -30,17 +30,17 @@ proc equalSets*(a, b: PNode): bool
proc cardSet*(s: PNode): BiggestInt
# implementation
proc inSet(s: PNode, elem: PNode): bool =
if s.kind != nkCurly:
proc inSet(s: PNode, elem: PNode): bool =
if s.kind != nkCurly:
internalError(s.info, "inSet")
return false
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
if leValue(s.sons[i].sons[0], elem) and
leValue(elem, s.sons[i].sons[1]):
leValue(elem, s.sons[i].sons[1]):
return true
else:
if sameValue(s.sons[i], elem):
else:
if sameValue(s.sons[i], elem):
return true
result = false
@@ -58,37 +58,37 @@ proc overlap(a, b: PNode): bool =
else:
result = sameValue(a, b)
proc someInSet(s: PNode, a, b: PNode): bool =
proc someInSet(s: PNode, a, b: PNode): bool =
# checks if some element of a..b is in the set s
if s.kind != nkCurly:
internalError(s.info, "SomeInSet")
return false
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
if leValue(s.sons[i].sons[0], b) and leValue(b, s.sons[i].sons[1]) or
leValue(s.sons[i].sons[0], a) and leValue(a, s.sons[i].sons[1]):
leValue(s.sons[i].sons[0], a) and leValue(a, s.sons[i].sons[1]):
return true
else:
else:
# a <= elem <= b
if leValue(a, s.sons[i]) and leValue(s.sons[i], b):
if leValue(a, s.sons[i]) and leValue(s.sons[i], b):
return true
result = false
proc toBitSet(s: PNode, b: var TBitSet) =
proc toBitSet(s: PNode, b: var TBitSet) =
var first, j: BiggestInt
first = firstOrd(s.typ.sons[0])
bitSetInit(b, int(getSize(s.typ)))
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
j = getOrdValue(s.sons[i].sons[0])
while j <= getOrdValue(s.sons[i].sons[1]):
while j <= getOrdValue(s.sons[i].sons[1]):
bitSetIncl(b, j - first)
inc(j)
else:
else:
bitSetIncl(b, getOrdValue(s.sons[i]) - first)
proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
var
proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
var
a, b, e, first: BiggestInt # a, b are interval borders
elemType: PType
n: PNode
@@ -98,17 +98,17 @@ proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
result.typ = settype
result.info = info
e = 0
while e < len(s) * ElemSize:
if bitSetIn(s, e):
while e < len(s) * ElemSize:
if bitSetIn(s, e):
a = e
b = e
while true:
while true:
inc(b)
if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break
if (b >= len(s) * ElemSize) or not bitSetIn(s, b): break
dec(b)
if a == b:
if a == b:
addSon(result, newIntTypeNode(nkIntLit, a + first, elemType))
else:
else:
n = newNodeI(nkRange, info)
n.typ = elemType
addSon(n, newIntTypeNode(nkIntLit, a + first, elemType))
@@ -117,7 +117,7 @@ proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
e = b
inc(e)
template nodeSetOp(a, b: PNode, op: expr) {.dirty.} =
template nodeSetOp(a, b: PNode, op: expr) {.dirty.} =
var x, y: TBitSet
toBitSet(a, x)
toBitSet(b, y)
@@ -129,13 +129,13 @@ proc diffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetDiff)
proc intersectSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetIntersect)
proc symdiffSets(a, b: PNode): PNode = nodeSetOp(a, b, bitSetSymDiff)
proc containsSets(a, b: PNode): bool =
proc containsSets(a, b: PNode): bool =
var x, y: TBitSet
toBitSet(a, x)
toBitSet(b, y)
result = bitSetContains(x, y)
proc equalSets(a, b: PNode): bool =
proc equalSets(a, b: PNode): bool =
var x, y: TBitSet
toBitSet(a, x)
toBitSet(b, y)
@@ -147,26 +147,26 @@ proc complement*(a: PNode): PNode =
for i in countup(0, high(x)): x[i] = not x[i]
result = toTreeSet(x, a.typ, a.info)
proc cardSet(s: PNode): BiggestInt =
proc cardSet(s: PNode): BiggestInt =
# here we can do better than converting it into a compact set
# we just count the elements directly
result = 0
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
result = result + getOrdValue(s.sons[i].sons[1]) -
getOrdValue(s.sons[i].sons[0]) + 1
else:
else:
inc(result)
proc setHasRange(s: PNode): bool =
proc setHasRange(s: PNode): bool =
if s.kind != nkCurly:
internalError(s.info, "SetHasRange")
return false
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange:
return true
result = false
proc emptyRange(a, b: PNode): bool =
proc emptyRange(a, b: PNode): bool =
result = not leValue(a, b) # a > b iff not (a <= b)

View File

@@ -10,7 +10,7 @@
# This module contains Nim's version. It is the only place where it needs
# to be changed.
const
const
MaxSetElements* = 1 shl 16 # (2^16) to support unicode character sets?
VersionAsString* = system.NimVersion
RodFileVersion* = "1215" # modify this if the rod-format changes!

View File

@@ -9,38 +9,38 @@
## implements some little helper passes
import
import
strutils, ast, astalgo, passes, msgs, options, idgen
proc verboseOpen(s: PSym): PPassContext =
#MessageOut('compiling ' + s.name.s);
result = nil # we don't need a context
rawMessage(hintProcessing, s.name.s)
proc verboseProcess(context: PPassContext, n: PNode): PNode =
proc verboseProcess(context: PPassContext, n: PNode): PNode =
result = n
if context != nil: internalError("logpass: context is not nil")
if gVerbosity == 3:
if gVerbosity == 3:
# system.nim deactivates all hints, for verbosity:3 we want the processing
# messages nonetheless, so we activate them again unconditionally:
incl(msgs.gNotes, hintProcessing)
message(n.info, hintProcessing, $idgen.gBackendId)
const verbosePass* = makePass(open = verboseOpen, process = verboseProcess)
proc cleanUp(c: PPassContext, n: PNode): PNode =
proc cleanUp(c: PPassContext, n: PNode): PNode =
result = n
# we cannot clean up if dead code elimination is activated
if optDeadCodeElim in gGlobalOptions or n == nil: return
if optDeadCodeElim in gGlobalOptions or n == nil: return
case n.kind
of nkStmtList:
of nkStmtList:
for i in countup(0, sonsLen(n) - 1): discard cleanUp(c, n.sons[i])
of nkProcDef, nkMethodDef:
if n.sons[namePos].kind == nkSym:
of nkProcDef, nkMethodDef:
if n.sons[namePos].kind == nkSym:
var s = n.sons[namePos].sym
if sfDeadCodeElim notin getModule(s).flags and not astNeeded(s):
if sfDeadCodeElim notin getModule(s).flags and not astNeeded(s):
s.ast.sons[bodyPos] = ast.emptyNode # free the memory
else:
else:
discard
const cleanupPass* = makePass(process = cleanUp, close = cleanUp)

View File

@@ -68,7 +68,7 @@ proc inSymChoice(sc, x: PNode): bool =
elif sc.kind == nkOpenSymChoice:
# same name suffices for open sym choices!
result = sc.sons[0].sym.name.id == x.sym.name.id
proc checkTypes(c: PPatternContext, p: PSym, n: PNode): bool =
# check param constraints first here as this is quite optimized:
if p.constraint != nil:
@@ -115,13 +115,13 @@ proc matchNested(c: PPatternContext, p, n: PNode, rpn: bool): bool =
if rpn: arglist.add(n.sons[0])
elif n.kind == nkHiddenStdConv and n.sons[1].kind == nkBracket:
let n = n.sons[1]
for i in 0.. <n.len:
for i in 0.. <n.len:
if not matchStarAux(c, op, n[i], arglist, rpn): return false
elif checkTypes(c, p.sons[2].sym, n):
add(arglist, n)
else:
result = false
if n.kind notin nkCallKinds: return false
if matches(c, p.sons[1], n.sons[0]):
var arglist = newNodeI(nkArgList, n.info)
@@ -151,7 +151,7 @@ proc matches(c: PPatternContext, p, n: PNode): bool =
of "**": result = matchNested(c, p, n, rpn=true)
of "~": result = not matches(c, p.sons[1], n)
else: internalError(p.info, "invalid pattern")
# template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) =
# template {add(a, `&` * b)}(a: string{noalias}, b: varargs[string]) =
# add(a, b)
elif p.kind == nkCurlyExpr:
if p.sons[1].kind == nkPrefix:
@@ -212,7 +212,7 @@ proc matchStmtList(c: PPatternContext, p, n: PNode): PNode =
if not isNil(c.mapping): c.mapping = nil
return false
result = true
if p.kind == nkStmtList and n.kind == p.kind and p.len < n.len:
let n = flattenStmts(n)
# no need to flatten 'p' here as that has already been done

View File

@@ -7,12 +7,12 @@
# distribution, for details about the copyright.
#
import
import
llstream, lexer, parser, idents, strutils, ast, msgs
proc parseAll*(p: var TParser): PNode =
proc parseAll*(p: var TParser): PNode =
result = nil
proc parseTopLevelStmt*(p: var TParser): PNode =
proc parseTopLevelStmt*(p: var TParser): PNode =
result = nil

View File

@@ -87,7 +87,7 @@ proc searchForProcNew(c: PContext, scope: PScope, fn: PSym): PSym =
discard
result = nextIdentIter(it, scope.symbols)
return nil
proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym =
@@ -99,17 +99,17 @@ proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym =
debug fn.typ
debug if result != nil: result.typ else: nil
debug if old != nil: old.typ else: nil
when false:
proc paramsFitBorrow(child, parent: PNode): bool =
proc paramsFitBorrow(child, parent: PNode): bool =
var length = sonsLen(child)
result = false
if length == sonsLen(parent):
for i in countup(1, length - 1):
if length == sonsLen(parent):
for i in countup(1, length - 1):
var m = child.sons[i].sym
var n = parent.sons[i].sym
assert((m.kind == skParam) and (n.kind == skParam))
if not compareTypes(m.typ, n.typ, dcEqOrDistinctOf): return
if not compareTypes(m.typ, n.typ, dcEqOrDistinctOf): return
if not compareTypes(child.sons[0].typ, parent.sons[0].typ,
dcEqOrDistinctOf): return
result = true
@@ -120,10 +120,10 @@ when false:
var it: TIdentIter
for scope in walkScopes(startScope):
result = initIdentIter(it, scope.symbols, fn.Name)
while result != nil:
while result != nil:
# watchout! result must not be the same as fn!
if (result.Kind == fn.kind) and (result.id != fn.id):
if equalGenericParams(result.ast.sons[genericParamsPos],
fn.ast.sons[genericParamsPos]):
if paramsFitBorrow(fn.typ.n, result.typ.n): return
if (result.Kind == fn.kind) and (result.id != fn.id):
if equalGenericParams(result.ast.sons[genericParamsPos],
fn.ast.sons[genericParamsPos]):
if paramsFitBorrow(fn.typ.n, result.typ.n): return
result = NextIdentIter(it, scope.symbols)

View File

@@ -12,7 +12,7 @@ import strutils
proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", header: "<stdio.h>", nodecl, varargs.}
proc toStrMaxPrecision*(f: BiggestFloat): string =
proc toStrMaxPrecision*(f: BiggestFloat): string =
if f != f:
result = "NAN"
elif f == 0.0:
@@ -21,17 +21,17 @@ proc toStrMaxPrecision*(f: BiggestFloat): string =
if f > 0.0: result = "INF"
else: result = "-INF"
else:
var buf: array [0..80, char]
c_sprintf(buf, "%#.16e", f)
var buf: array [0..80, char]
c_sprintf(buf, "%#.16e", f)
result = $buf
proc encodeStr*(s: string, result: var string) =
for i in countup(0, len(s) - 1):
for i in countup(0, len(s) - 1):
case s[i]
of 'a'..'z', 'A'..'Z', '0'..'9', '_': add(result, s[i])
else: add(result, '\\' & toHex(ord(s[i]), 2))
proc hexChar(c: char, xi: var int) =
proc hexChar(c: char, xi: var int) =
case c
of '0'..'9': xi = (xi shl 4) or (ord(c) - ord('0'))
of 'a'..'f': xi = (xi shl 4) or (ord(c) - ord('a') + 10)
@@ -41,18 +41,18 @@ proc hexChar(c: char, xi: var int) =
proc decodeStr*(s: cstring, pos: var int): string =
var i = pos
result = ""
while true:
while true:
case s[i]
of '\\':
of '\\':
inc(i, 3)
var xi = 0
hexChar(s[i-2], xi)
hexChar(s[i-1], xi)
add(result, chr(xi))
of 'a'..'z', 'A'..'Z', '0'..'9', '_':
of 'a'..'z', 'A'..'Z', '0'..'9', '_':
add(result, s[i])
inc(i)
else: break
else: break
pos = i
const
@@ -68,11 +68,11 @@ template encodeIntImpl(self: expr) =
var d: char
var v = x
var rem = v mod 190
if rem < 0:
if rem < 0:
add(result, '-')
v = - (v div 190)
rem = - rem
else:
else:
v = v div 190
var idx = int(rem)
if idx < 62: d = chars[idx]
@@ -89,11 +89,11 @@ proc encodeVBiggestInt*(x: BiggestInt, result: var string) =
encodeVBiggestIntAux(x +% vintDelta, result)
# encodeIntImpl(encodeVBiggestInt)
proc encodeVIntAux(x: int, result: var string) =
proc encodeVIntAux(x: int, result: var string) =
## encode an int as a variable length base 190 int.
encodeIntImpl(encodeVIntAux)
proc encodeVInt*(x: int, result: var string) =
proc encodeVInt*(x: int, result: var string) =
## encode an int as a variable length base 190 int.
encodeVIntAux(x +% vintDelta, result)
@@ -101,11 +101,11 @@ template decodeIntImpl() =
var i = pos
var sign = - 1
assert(s[i] in {'a'..'z', 'A'..'Z', '0'..'9', '-', '\x80'..'\xFF'})
if s[i] == '-':
if s[i] == '-':
inc(i)
sign = 1
result = 0
while true:
while true:
case s[i]
of '0'..'9': result = result * 190 - (ord(s[i]) - ord('0'))
of 'a'..'z': result = result * 190 - (ord(s[i]) - ord('a') + 10)
@@ -116,7 +116,7 @@ template decodeIntImpl() =
result = result * sign -% vintDelta
pos = i
proc decodeVInt*(s: cstring, pos: var int): int =
proc decodeVInt*(s: cstring, pos: var int): int =
decodeIntImpl()
proc decodeVBiggestInt*(s: cstring, pos: var int): BiggestInt =

View File

@@ -306,7 +306,7 @@ const
proc equalsFile*(r: Rope, f: File): bool =
## returns true if the contents of the file `f` equal `r`.
var
var
buf: array[bufSize, char]
bpos = buf.len
blen = buf.len

View File

@@ -72,7 +72,7 @@ proc `|*|`*(a, b: BiggestInt): BiggestInt =
# 32 * abs(diff) <= abs(prod) -- 5 good bits is "close enough"
if 32.0 * abs(resAsFloat - floatProd) <= abs(floatProd):
return result
if floatProd >= 0.0:
result = high(result)
else:

View File

@@ -320,7 +320,7 @@ proc semResolvedCall(c: PContext, n: PNode, x: TCandidate): PNode =
x.call.add newSymNode(s, n.info)
else:
internalAssert false
result = x.call
instGenericConvertersSons(c, result, x)
result.sons[0] = newSymNode(finalCallee, result.sons[0].info)

View File

@@ -76,7 +76,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
let L = forLoop.len
let call = forLoop.sons[L-2]
if call.len > 2:
localError(forLoop.info, errGenerated,
localError(forLoop.info, errGenerated,
"parallel 'fields' iterator does not work for 'case' objects")
return
# iterate over the selector:
@@ -106,7 +106,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
# a 'while true: stmt; break' loop ...
result = newNodeI(nkWhileStmt, n.info, 2)
var trueSymbol = strTableGet(magicsys.systemModule.tab, getIdent"true")
if trueSymbol == nil:
if trueSymbol == nil:
localError(n.info, errSystemNeeds, "true")
trueSymbol = newSym(skUnknown, getIdent"true", getCurrOwner(), n.info)
trueSymbol.typ = getSysType(tyBool)
@@ -114,13 +114,13 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
result.sons[0] = newSymNode(trueSymbol, n.info)
var stmts = newNodeI(nkStmtList, n.info)
result.sons[1] = stmts
var length = sonsLen(n)
var call = n.sons[length-2]
if length-2 != sonsLen(call)-1 + ord(m==mFieldPairs):
localError(n.info, errWrongNumberOfVariables)
return result
var tupleTypeA = skipTypes(call.sons[1].typ, abstractVar-{tyTypeDesc})
if tupleTypeA.kind notin {tyTuple, tyObject}:
localError(n.info, errGenerated, "no object or tuple type")
@@ -129,7 +129,7 @@ proc semForFields(c: PContext, n: PNode, m: TMagic): PNode =
var tupleTypeB = skipTypes(call.sons[i].typ, abstractVar-{tyTypeDesc})
if not sameType(tupleTypeA, tupleTypeB):
typeMismatch(call.sons[i], tupleTypeA, tupleTypeB)
inc(c.p.nestedLoopCounter)
if tupleTypeA.kind == tyTuple:
var loopBody = n.sons[length-1]

View File

@@ -1327,7 +1327,7 @@ proc paramTypesMatchAux(m: var TCandidate, f, argType: PType,
# because in that case there is no point in continuing.
var bothMetaCounter = 0
var lastBindingsLength = -1
while r == isBothMetaConvertible and
while r == isBothMetaConvertible and
lastBindingsLength != m.bindings.counter and
bothMetaCounter < 100:
lastBindingsLength = m.bindings.counter

View File

@@ -34,7 +34,7 @@ var
template origModuleName(m: PSym): string = m.name.s
proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo): Suggest =
proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo): Suggest =
result.section = parseIdeCmd(section)
if optIdeTerse in gGlobalOptions:
result.symkind = s.kind
@@ -52,7 +52,7 @@ proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo): Sugge
result.qualifiedPath.add(ow.origModuleName)
result.qualifiedPath.add(s.name.s)
if s.typ != nil:
if s.typ != nil:
result.forth = typeToString(s.typ)
else:
result.forth = ""
@@ -62,7 +62,7 @@ proc symToSuggest(s: PSym, isLocal: bool, section: string, li: TLineInfo): Sugge
when not defined(noDocgen):
result.doc = s.extractDocComment
proc `$`(suggest: Suggest): string =
proc `$`(suggest: Suggest): string =
result = $suggest.section
result.add(sep)
result.add($suggest.symkind)
@@ -80,7 +80,7 @@ proc `$`(suggest: Suggest): string =
when not defined(noDocgen):
result.add(suggest.doc.escape)
proc symToSuggest(s: PSym, isLocal: bool, section: string): Suggest =
proc symToSuggest(s: PSym, isLocal: bool, section: string): Suggest =
result = symToSuggest(s, isLocal, section, s.info)
proc suggestResult(s: Suggest) =
@@ -104,7 +104,7 @@ proc fieldVisible*(c: PContext, f: PSym): bool {.inline.} =
result = true
break
proc suggestField(c: PContext, s: PSym, outputs: var int) =
proc suggestField(c: PContext, s: PSym, outputs: var int) =
if filterSym(s) and fieldVisible(c, s):
suggestResult(symToSuggest(s, isLocal=true, $ideSug))
inc outputs
@@ -122,17 +122,17 @@ template wholeSymTab(cond, section: expr) {.immediate.} =
suggestResult(symToSuggest(it, isLocal = isLocal, section))
inc outputs
proc suggestSymList(c: PContext, list: PNode, outputs: var int) =
for i in countup(0, sonsLen(list) - 1):
proc suggestSymList(c: PContext, list: PNode, outputs: var int) =
for i in countup(0, sonsLen(list) - 1):
if list.sons[i].kind == nkSym:
suggestField(c, list.sons[i].sym, outputs)
#else: InternalError(list.info, "getSymFromList")
proc suggestObject(c: PContext, n: PNode, outputs: var int) =
proc suggestObject(c: PContext, n: PNode, outputs: var int) =
case n.kind
of nkRecList:
of nkRecList:
for i in countup(0, sonsLen(n)-1): suggestObject(c, n.sons[i], outputs)
of nkRecCase:
of nkRecCase:
var L = sonsLen(n)
if L > 0:
suggestObject(c, n.sons[0], outputs)
@@ -140,7 +140,7 @@ proc suggestObject(c: PContext, n: PNode, outputs: var int) =
of nkSym: suggestField(c, n.sym, outputs)
else: discard
proc nameFits(c: PContext, s: PSym, n: PNode): bool =
proc nameFits(c: PContext, s: PSym, n: PNode): bool =
var op = n.sons[0]
if op.kind in {nkOpenSymChoice, nkClosedSymChoice}: op = op.sons[0]
var opr: PIdent
@@ -150,8 +150,8 @@ proc nameFits(c: PContext, s: PSym, n: PNode): bool =
else: return false
result = opr.id == s.name.id
proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool =
case candidate.kind
proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool =
case candidate.kind
of OverloadableSyms:
var m: TCandidate
initCandidate(c, m, candidate, nil)
@@ -160,11 +160,11 @@ proc argsFit(c: PContext, candidate: PSym, n, nOrig: PNode): bool =
else:
result = false
proc suggestCall(c: PContext, n, nOrig: PNode, outputs: var int) =
proc suggestCall(c: PContext, n, nOrig: PNode, outputs: var int) =
wholeSymTab(filterSym(it) and nameFits(c, it, n) and argsFit(c, it, n, nOrig),
$ideCon)
proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
proc typeFits(c: PContext, s: PSym, firstArg: PType): bool {.inline.} =
if s.typ != nil and sonsLen(s.typ) > 1 and s.typ.sons[1] != nil:
# special rule: if system and some weird generic match via 'tyExpr'
# or 'tyGenericParam' we won't list it either to reduce the noise (nobody
@@ -198,48 +198,48 @@ proc suggestFieldAccess(c: PContext, n: PNode, outputs: var int) =
var typ = n.typ
if typ == nil:
# a module symbol has no type for example:
if n.kind == nkSym and n.sym.kind == skModule:
if n.sym == c.module:
if n.kind == nkSym and n.sym.kind == skModule:
if n.sym == c.module:
# all symbols accessible, because we are in the current module:
for it in items(c.topLevelScope.symbols):
if filterSym(it):
if filterSym(it):
suggestResult(symToSuggest(it, isLocal=false, $ideSug))
inc outputs
else:
for it in items(n.sym.tab):
if filterSym(it):
else:
for it in items(n.sym.tab):
if filterSym(it):
suggestResult(symToSuggest(it, isLocal=false, $ideSug))
inc outputs
else:
# fallback:
suggestEverything(c, n, outputs)
elif typ.kind == tyEnum and n.kind == nkSym and n.sym.kind == skType:
elif typ.kind == tyEnum and n.kind == nkSym and n.sym.kind == skType:
# look up if the identifier belongs to the enum:
var t = typ
while t != nil:
while t != nil:
suggestSymList(c, t.n, outputs)
t = t.sons[0]
suggestOperations(c, n, typ, outputs)
else:
typ = skipTypes(typ, {tyGenericInst, tyVar, tyPtr, tyRef})
if typ.kind == tyObject:
if typ.kind == tyObject:
var t = typ
while true:
while true:
suggestObject(c, t.n, outputs)
if t.sons[0] == nil: break
if t.sons[0] == nil: break
t = skipTypes(t.sons[0], {tyGenericInst})
suggestOperations(c, n, typ, outputs)
elif typ.kind == tyTuple and typ.n != nil:
elif typ.kind == tyTuple and typ.n != nil:
suggestSymList(c, typ.n, outputs)
suggestOperations(c, n, typ, outputs)
else:
suggestOperations(c, n, typ, outputs)
type
TCheckPointResult = enum
TCheckPointResult = enum
cpNone, cpFuzzy, cpExact
proc inCheckpoint(current: TLineInfo): TCheckPointResult =
proc inCheckpoint(current: TLineInfo): TCheckPointResult =
if current.fileIndex == gTrackPos.fileIndex:
if current.line == gTrackPos.line and
abs(current.col-gTrackPos.col) < 4:
@@ -255,8 +255,8 @@ proc findClosestDot(n: PNode): PNode =
result = findClosestDot(n.sons[i])
if result != nil: return
proc findClosestCall(n: PNode): PNode =
if n.kind in nkCallKinds and inCheckpoint(n.info) == cpExact:
proc findClosestCall(n: PNode): PNode =
if n.kind in nkCallKinds and inCheckpoint(n.info) == cpExact:
result = n
else:
for i in 0.. <safeLen(n):
@@ -270,8 +270,8 @@ proc isTracked(current: TLineInfo, tokenLen: int): bool =
if col >= current.col and col <= current.col+tokenLen-1:
return true
proc findClosestSym(n: PNode): PNode =
if n.kind == nkSym and inCheckpoint(n.info) == cpExact:
proc findClosestSym(n: PNode): PNode =
if n.kind == nkSym and inCheckpoint(n.info) == cpExact:
result = n
elif n.kind notin {nkNone..nkNilLit}:
for i in 0.. <sonsLen(n):
@@ -328,7 +328,7 @@ proc safeSemExpr*(c: PContext, n: PNode): PNode =
except ERecoverableError:
result = ast.emptyNode
proc suggestExpr*(c: PContext, node: PNode) =
proc suggestExpr*(c: PContext, node: PNode) =
if nfIsCursor notin node.flags:
if gTrackPos.line < 0: return
var cp = inCheckpoint(node.info)
@@ -349,7 +349,7 @@ proc suggestExpr*(c: PContext, node: PNode) =
#writeStackTrace()
else:
suggestEverything(c, n, outputs)
elif gIdeCmd == ideCon:
var n = if nfIsCursor in node.flags: node else: findClosestCall(node)
if n == nil: n = node
@@ -364,9 +364,9 @@ proc suggestExpr*(c: PContext, node: PNode) =
if x.kind == nkEmpty or x.typ == nil: break
addSon(a, x)
suggestCall(c, a, n, outputs)
dec(c.inCompilesContext)
if outputs > 0 and gIdeCmd != ideUse: suggestQuit()
proc suggestStmt*(c: PContext, n: PNode) =
proc suggestStmt*(c: PContext, n: PNode) =
suggestExpr(c, n)

View File

@@ -9,24 +9,24 @@
## Implements the dispatcher for the different parsers.
import
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
import
strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
pbraces, filters, filter_tmpl, renderer
type
TFilterKind* = enum
type
TFilterKind* = enum
filtNone, filtTemplate, filtReplace, filtStrip
TParserKind* = enum
TParserKind* = enum
skinStandard, skinStrongSpaces, skinBraces, skinEndX
const
const
parserNames*: array[TParserKind, string] = ["standard", "strongspaces",
"braces", "endx"]
filterNames*: array[TFilterKind, string] = ["none", "stdtmpl", "replace",
"strip"]
type
TParsers*{.final.} = object
TParsers*{.final.} = object
skin*: TParserKind
parser*: TParser
@@ -42,53 +42,53 @@ proc parseTopLevelStmt*(p: var TParsers): PNode
# implementation
proc parseFile(fileIdx: int32): PNode =
var
var
p: TParsers
f: File
let filename = fileIdx.toFullPathConsiderDirty
if not open(f, filename):
rawMessage(errCannotOpenFile, filename)
return
return
openParsers(p, fileIdx, llStreamOpen(f))
result = parseAll(p)
closeParsers(p)
proc parseAll(p: var TParsers): PNode =
proc parseAll(p: var TParsers): PNode =
case p.skin
of skinStandard, skinStrongSpaces:
result = parser.parseAll(p.parser)
of skinBraces:
of skinBraces:
result = pbraces.parseAll(p.parser)
of skinEndX:
internalError("parser to implement")
of skinEndX:
internalError("parser to implement")
result = ast.emptyNode
proc parseTopLevelStmt(p: var TParsers): PNode =
proc parseTopLevelStmt(p: var TParsers): PNode =
case p.skin
of skinStandard, skinStrongSpaces:
result = parser.parseTopLevelStmt(p.parser)
of skinBraces:
of skinBraces:
result = pbraces.parseTopLevelStmt(p.parser)
of skinEndX:
internalError("parser to implement")
of skinEndX:
internalError("parser to implement")
result = ast.emptyNode
proc utf8Bom(s: string): int =
if (s[0] == '\xEF') and (s[1] == '\xBB') and (s[2] == '\xBF'):
proc utf8Bom(s: string): int =
if (s[0] == '\xEF') and (s[1] == '\xBB') and (s[2] == '\xBF'):
result = 3
else:
else:
result = 0
proc containsShebang(s: string, i: int): bool =
if (s[i] == '#') and (s[i + 1] == '!'):
proc containsShebang(s: string, i: int): bool =
if (s[i] == '#') and (s[i + 1] == '!'):
var j = i + 2
while s[j] in Whitespace: inc(j)
result = s[j] == '/'
proc parsePipe(filename: string, inputStream: PLLStream): PNode =
proc parsePipe(filename: string, inputStream: PLLStream): PNode =
result = ast.emptyNode
var s = llStreamOpen(filename, fmRead)
if s != nil:
if s != nil:
var line = newStringOfCap(80)
discard llStreamReadLine(s, line)
var i = utf8Bom(line)
@@ -104,50 +104,50 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
closeParser(q)
llStreamClose(s)
proc getFilter(ident: PIdent): TFilterKind =
for i in countup(low(TFilterKind), high(TFilterKind)):
if identEq(ident, filterNames[i]):
proc getFilter(ident: PIdent): TFilterKind =
for i in countup(low(TFilterKind), high(TFilterKind)):
if identEq(ident, filterNames[i]):
return i
result = filtNone
proc getParser(ident: PIdent): TParserKind =
for i in countup(low(TParserKind), high(TParserKind)):
if identEq(ident, parserNames[i]):
proc getParser(ident: PIdent): TParserKind =
for i in countup(low(TParserKind), high(TParserKind)):
if identEq(ident, parserNames[i]):
return i
rawMessage(errInvalidDirectiveX, ident.s)
proc getCallee(n: PNode): PIdent =
if n.kind in nkCallKinds and n.sons[0].kind == nkIdent:
proc getCallee(n: PNode): PIdent =
if n.kind in nkCallKinds and n.sons[0].kind == nkIdent:
result = n.sons[0].ident
elif n.kind == nkIdent:
elif n.kind == nkIdent:
result = n.ident
else:
else:
rawMessage(errXNotAllowedHere, renderTree(n))
proc applyFilter(p: var TParsers, n: PNode, filename: string,
stdin: PLLStream): PLLStream =
proc applyFilter(p: var TParsers, n: PNode, filename: string,
stdin: PLLStream): PLLStream =
var ident = getCallee(n)
var f = getFilter(ident)
case f
of filtNone:
of filtNone:
p.skin = getParser(ident)
result = stdin
of filtTemplate:
of filtTemplate:
result = filterTmpl(stdin, filename, n)
of filtStrip:
of filtStrip:
result = filterStrip(stdin, filename, n)
of filtReplace:
of filtReplace:
result = filterReplace(stdin, filename, n)
if f != filtNone:
if f != filtNone:
if hintCodeBegin in gNotes:
rawMessage(hintCodeBegin, [])
msgWriteln(result.s)
rawMessage(hintCodeEnd, [])
proc evalPipe(p: var TParsers, n: PNode, filename: string,
start: PLLStream): PLLStream =
proc evalPipe(p: var TParsers, n: PNode, filename: string,
start: PLLStream): PLLStream =
result = start
if n.kind == nkEmpty: return
if n.kind == nkEmpty: return
if n.kind == nkInfix and n.sons[0].kind == nkIdent and
identEq(n.sons[0].ident, "|"):
for i in countup(1, 2):
@@ -159,8 +159,8 @@ proc evalPipe(p: var TParsers, n: PNode, filename: string,
result = evalPipe(p, n.sons[0], filename, result)
else:
result = applyFilter(p, n, filename, result)
proc openParsers(p: var TParsers, fileIdx: int32, inputstream: PLLStream) =
proc openParsers(p: var TParsers, fileIdx: int32, inputstream: PLLStream) =
var s: PLLStream
p.skin = skinStandard
let filename = fileIdx.toFullPathConsiderDirty
@@ -172,6 +172,6 @@ proc openParsers(p: var TParsers, fileIdx: int32, inputstream: PLLStream) =
parser.openParser(p.parser, fileIdx, s, false)
of skinStrongSpaces:
parser.openParser(p.parser, fileIdx, s, true)
proc closeParsers(p: var TParsers) =
parser.closeParser(p.parser)

View File

@@ -12,10 +12,10 @@ import
{.compile: "../tinyc/libtcc.c".}
proc tinyCErrorHandler(closure: pointer, msg: cstring) {.cdecl.} =
proc tinyCErrorHandler(closure: pointer, msg: cstring) {.cdecl.} =
rawMessage(errGenerated, $msg)
proc initTinyCState: PccState =
proc initTinyCState: PccState =
result = openCCState()
setErrorFunc(result, nil, tinyCErrorHandler)
@@ -23,25 +23,25 @@ var
gTinyC = initTinyCState()
libIncluded = false
proc addFile(filename: string) =
proc addFile(filename: string) =
if addFile(gTinyC, filename) != 0'i32:
rawMessage(errCannotOpenFile, filename)
proc setupEnvironment =
proc setupEnvironment =
when defined(amd64):
defineSymbol(gTinyC, "__x86_64__", nil)
elif defined(i386):
defineSymbol(gTinyC, "__i386__", nil)
defineSymbol(gTinyC, "__i386__", nil)
when defined(linux):
defineSymbol(gTinyC, "__linux__", nil)
defineSymbol(gTinyC, "__linux", nil)
var nimrodDir = getPrefixDir()
addIncludePath(gTinyC, libpath)
when defined(windows):
when defined(windows):
addSysincludePath(gTinyC, nimrodDir / "tinyc/win32/include")
addSysincludePath(gTinyC, nimrodDir / "tinyc/include")
when defined(windows):
when defined(windows):
defineSymbol(gTinyC, "_WIN32", nil)
# we need Mingw's headers too:
var gccbin = getConfigVar("gcc.path") % ["nimrod", nimrodDir]
@@ -54,7 +54,7 @@ proc setupEnvironment =
#addFile(nimrodDir / r"tinyc\win32\dllcrt1.o")
#addFile(nimrodDir / r"tinyc\win32\dllmain.o")
addFile(nimrodDir / r"tinyc\win32\libtcc1.o")
#addFile(nimrodDir / r"tinyc\win32\lib\crt1.c")
#addFile(nimrodDir / r"tinyc\lib\libtcc1.c")
else:
@@ -62,12 +62,12 @@ proc setupEnvironment =
when defined(amd64):
addSysincludePath(gTinyC, "/usr/include/x86_64-linux-gnu")
proc compileCCode*(ccode: string) =
proc compileCCode*(ccode: string) =
if not libIncluded:
libIncluded = true
setupEnvironment()
discard compileString(gTinyC, ccode)
proc run*(args: string) =
var s = @[cstring(gProjectName)] & map(split(args), proc(x: string): cstring = cstring(x))
var err = tinyc.run(gTinyC, cint(len(s)), cast[cstringArray](addr(s[0]))) != 0'i32

View File

@@ -9,36 +9,36 @@
# Implements a table from trees to trees. Does structural equivalence checking.
import
import
hashes, ast, astalgo, types
proc hashTree(n: PNode): Hash =
if n == nil: return
proc hashTree(n: PNode): Hash =
if n == nil: return
result = ord(n.kind)
case n.kind
of nkEmpty, nkNilLit, nkType:
of nkEmpty, nkNilLit, nkType:
discard
of nkIdent:
of nkIdent:
result = result !& n.ident.h
of nkSym:
result = result !& n.sym.name.h
of nkCharLit..nkUInt64Lit:
if (n.intVal >= low(int)) and (n.intVal <= high(int)):
of nkCharLit..nkUInt64Lit:
if (n.intVal >= low(int)) and (n.intVal <= high(int)):
result = result !& int(n.intVal)
of nkFloatLit..nkFloat64Lit:
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
result = result !& toInt(n.floatVal)
of nkStrLit..nkTripleStrLit:
if not n.strVal.isNil:
result = result !& hash(n.strVal)
else:
for i in countup(0, sonsLen(n) - 1):
else:
for i in countup(0, sonsLen(n) - 1):
result = result !& hashTree(n.sons[i])
proc treesEquivalent(a, b: PNode): bool =
if a == b:
proc treesEquivalent(a, b: PNode): bool =
if a == b:
result = true
elif (a != nil) and (b != nil) and (a.kind == b.kind):
elif (a != nil) and (b != nil) and (a.kind == b.kind):
case a.kind
of nkEmpty, nkNilLit, nkType: result = true
of nkSym: result = a.sym.id == b.sym.id
@@ -46,28 +46,28 @@ proc treesEquivalent(a, b: PNode): bool =
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
else:
if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1):
if not treesEquivalent(a.sons[i], b.sons[i]): return
else:
if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1):
if not treesEquivalent(a.sons[i], b.sons[i]): return
result = true
if result: result = sameTypeOrNil(a.typ, b.typ)
proc nodeTableRawGet(t: TNodeTable, k: Hash, key: PNode): int =
proc nodeTableRawGet(t: TNodeTable, k: Hash, key: PNode): int =
var h: Hash = k and high(t.data)
while t.data[h].key != nil:
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
while t.data[h].key != nil:
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
return h
h = nextTry(h, high(t.data))
result = -1
proc nodeTableGet*(t: TNodeTable, key: PNode): int =
proc nodeTableGet*(t: TNodeTable, key: PNode): int =
var index = nodeTableRawGet(t, hashTree(key), key)
if index >= 0: result = t.data[index].val
else: result = low(int)
proc nodeTableRawInsert(data: var TNodePairSeq, k: Hash, key: PNode,
val: int) =
proc nodeTableRawInsert(data: var TNodePairSeq, k: Hash, key: PNode,
val: int) =
var h: Hash = k and high(data)
while data[h].key != nil: h = nextTry(h, high(data))
assert(data[h].key == nil)
@@ -75,35 +75,35 @@ proc nodeTableRawInsert(data: var TNodePairSeq, k: Hash, key: PNode,
data[h].key = key
data[h].val = val
proc nodeTablePut*(t: var TNodeTable, key: PNode, val: int) =
proc nodeTablePut*(t: var TNodeTable, key: PNode, val: int) =
var n: TNodePairSeq
var k: Hash = hashTree(key)
var index = nodeTableRawGet(t, k, key)
if index >= 0:
if index >= 0:
assert(t.data[index].key != nil)
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter):
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
if t.data[i].key != nil:
for i in countup(0, high(t.data)):
if t.data[i].key != nil:
nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n)
nodeTableRawInsert(t.data, k, key, val)
inc(t.counter)
proc nodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int =
proc nodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int =
var n: TNodePairSeq
var k: Hash = hashTree(key)
var index = nodeTableRawGet(t, k, key)
if index >= 0:
if index >= 0:
assert(t.data[index].key != nil)
result = t.data[index].val
else:
if mustRehash(len(t.data), t.counter):
else:
if mustRehash(len(t.data), t.counter):
newSeq(n, len(t.data) * GrowthFactor)
for i in countup(0, high(t.data)):
if t.data[i].key != nil:
for i in countup(0, high(t.data)):
if t.data[i].key != nil:
nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n)
nodeTableRawInsert(t.data, k, key, val)