case consistency part 1

This commit is contained in:
Araq 2013-12-27 15:48:53 +01:00
commit 2df9b442c6
88 changed files with 1266 additions and 1144 deletions

View file

@ -24,35 +24,35 @@ proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope
proc lineInfoToStr*(info: TLineInfo): PRope proc lineInfoToStr*(info: TLineInfo): PRope
# ----------------------- node sets: --------------------------------------- # ----------------------- node sets: ---------------------------------------
proc ObjectSetContains*(t: TObjectSet, obj: PObject): bool proc objectSetContains*(t: TObjectSet, obj: PObject): bool
# returns true whether n is in t # returns true whether n is in t
proc ObjectSetIncl*(t: var TObjectSet, obj: PObject) proc objectSetIncl*(t: var TObjectSet, obj: PObject)
# include an element n in the table t # include an element n in the table t
proc ObjectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool proc objectSetContainsOrIncl*(t: var TObjectSet, obj: PObject): bool
# more are not needed ... # more are not needed ...
# ----------------------- (key, val)-Hashtables ---------------------------- # ----------------------- (key, val)-Hashtables ----------------------------
proc TablePut*(t: var TTable, key, val: PObject) proc tablePut*(t: var TTable, key, val: PObject)
proc TableGet*(t: TTable, key: PObject): PObject proc tableGet*(t: TTable, key: PObject): PObject
type type
TCmpProc* = proc (key, closure: PObject): bool {.nimcall.} # true if found TCmpProc* = proc (key, closure: PObject): bool {.nimcall.} # true if found
proc TableSearch*(t: TTable, key, closure: PObject, proc tableSearch*(t: TTable, key, closure: PObject,
comparator: TCmpProc): PObject comparator: TCmpProc): PObject
# return val as soon as comparator returns true; if this never happens, # return val as soon as comparator returns true; if this never happens,
# nil is returned # nil is returned
# ----------------------- str table ----------------------------------------- # ----------------------- str table -----------------------------------------
proc StrTableContains*(t: TStrTable, n: PSym): bool proc strTableContains*(t: TStrTable, n: PSym): bool
proc StrTableAdd*(t: var TStrTable, n: PSym) proc strTableAdd*(t: var TStrTable, n: PSym)
proc StrTableGet*(t: TStrTable, name: PIdent): PSym proc strTableGet*(t: TStrTable, name: PIdent): PSym
type type
TTabIter*{.final.} = object # consider all fields here private TTabIter*{.final.} = object # consider all fields here private
h*: THash # current hash h*: THash # current hash
proc InitTabIter*(ti: var TTabIter, tab: TStrTable): PSym proc initTabIter*(ti: var TTabIter, tab: TStrTable): PSym
proc NextIter*(ti: var TTabIter, tab: TStrTable): PSym proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym
# usage: # usage:
# var # var
# i: TTabIter # i: TTabIter
@ -69,8 +69,8 @@ type
name*: PIdent name*: PIdent
proc InitIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym proc initIdentIter*(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym
proc NextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym proc nextIdentIter*(ti: var TIdentIter, tab: TStrTable): PSym
# these are for debugging only: They are not really deprecated, but I want # these are for debugging only: They are not really deprecated, but I want
# the warning so that release versions do not contain debugging statements: # the warning so that release versions do not contain debugging statements:
@ -79,15 +79,14 @@ proc debug*(n: PType) {.deprecated.}
proc debug*(n: PNode) {.deprecated.} proc debug*(n: PNode) {.deprecated.}
# --------------------------- ident tables ---------------------------------- # --------------------------- ident tables ----------------------------------
proc IdTableGet*(t: TIdTable, key: PIdObj): PObject proc idTableGet*(t: TIdTable, key: PIdObj): PObject
proc IdTableGet*(t: TIdTable, key: int): PObject proc idTableGet*(t: TIdTable, key: int): PObject
proc IdTablePut*(t: var TIdTable, key: PIdObj, val: PObject) proc idTablePut*(t: var TIdTable, key: PIdObj, val: PObject)
proc IdTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool proc idTableHasObjectAsKey*(t: TIdTable, key: PIdObj): bool
# checks if `t` contains the `key` (compared by the pointer value, not only # checks if `t` contains the `key` (compared by the pointer value, not only
# `key`'s id) # `key`'s id)
proc IdNodeTableGet*(t: TIdNodeTable, key: PIdObj): PNode proc idNodeTableGet*(t: TIdNodeTable, key: PIdObj): PNode
proc IdNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode) proc idNodeTablePut*(t: var TIdNodeTable, key: PIdObj, val: PNode)
proc writeIdNodeTable*(t: TIdNodeTable)
# --------------------------------------------------------------------------- # ---------------------------------------------------------------------------
@ -111,9 +110,9 @@ type
data*: TIIPairSeq data*: TIIPairSeq
proc initIITable*(x: var TIITable) proc initIiTable*(x: var TIITable)
proc IITableGet*(t: TIITable, key: int): int proc iiTableGet*(t: TIITable, key: int): int
proc IITablePut*(t: var TIITable, key, val: int) proc iiTablePut*(t: var TIITable, key, val: int)
# implementation # implementation
@ -129,7 +128,7 @@ proc skipConvTakeType*(n: PNode): PNode =
result = n.skipConv result = n.skipConv
result.typ = n.typ result.typ = n.typ
proc SameValue*(a, b: PNode): bool = proc sameValue*(a, b: PNode): bool =
result = false result = false
case a.kind case a.kind
of nkCharLit..nkInt64Lit: of nkCharLit..nkInt64Lit:
@ -141,7 +140,7 @@ proc SameValue*(a, b: PNode): bool =
else: else:
# don't raise an internal error for 'nimrod check': # don't raise an internal error for 'nimrod check':
#InternalError(a.info, "SameValue") #InternalError(a.info, "SameValue")
nil discard
proc leValue*(a, b: PNode): bool = proc leValue*(a, b: PNode): bool =
# a <= b? # a <= b?
@ -156,7 +155,7 @@ proc leValue*(a, b: PNode): bool =
else: else:
# don't raise an internal error for 'nimrod check': # don't raise an internal error for 'nimrod check':
#InternalError(a.info, "leValue") #InternalError(a.info, "leValue")
nil discard
proc lookupInRecord(n: PNode, field: PIdent): PSym = proc lookupInRecord(n: PNode, field: PIdent): PSym =
result = nil result = nil
@ -182,14 +181,14 @@ proc lookupInRecord(n: PNode, field: PIdent): PSym =
proc getModule(s: PSym): PSym = proc getModule(s: PSym): PSym =
result = s result = s
assert((result.kind == skModule) or (result.owner != result)) assert((result.kind == skModule) or (result.owner != result))
while (result != nil) and (result.kind != skModule): result = result.owner while result != nil and result.kind != skModule: result = result.owner
proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym = proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
for i in countup(start, sonsLen(list) - 1): for i in countup(start, sonsLen(list) - 1):
if list.sons[i].kind == nkSym: if list.sons[i].kind == nkSym:
result = list.sons[i].sym result = list.sons[i].sym
if result.name.id == ident.id: return if result.name.id == ident.id: return
else: InternalError(list.info, "getSymFromList") else: internalError(list.info, "getSymFromList")
result = nil result = nil
proc hashNode(p: PObject): THash = proc hashNode(p: PObject): THash =
@ -501,7 +500,7 @@ proc objectSetContainsOrIncl(t: var TObjectSet, obj: PObject): bool =
inc(t.counter) inc(t.counter)
result = false result = false
proc TableRawGet(t: TTable, key: PObject): int = proc tableRawGet(t: TTable, key: PObject): int =
var h: THash = hashNode(key) and high(t.data) # start with real hash value var h: THash = hashNode(key) and high(t.data) # start with real hash value
while t.data[h].key != nil: while t.data[h].key != nil:
if t.data[h].key == key: if t.data[h].key == key:
@ -509,7 +508,7 @@ proc TableRawGet(t: TTable, key: PObject): int =
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = -1 result = -1
proc TableSearch(t: TTable, key, closure: PObject, proc tableSearch(t: TTable, key, closure: PObject,
comparator: TCmpProc): PObject = comparator: TCmpProc): PObject =
var h: THash = hashNode(key) and high(t.data) # start with real hash value var h: THash = hashNode(key) and high(t.data) # start with real hash value
while t.data[h].key != nil: while t.data[h].key != nil:
@ -520,13 +519,13 @@ proc TableSearch(t: TTable, key, closure: PObject,
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = nil result = nil
proc TableGet(t: TTable, key: PObject): PObject = proc tableGet(t: TTable, key: PObject): PObject =
var index = TableRawGet(t, key) var index = tableRawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = nil else: result = nil
proc TableRawInsert(data: var TPairSeq, key, val: PObject) = proc tableRawInsert(data: var TPairSeq, key, val: PObject) =
var h: THash = HashNode(key) and high(data) var h: THash = hashNode(key) and high(data)
while data[h].key != nil: while data[h].key != nil:
assert(data[h].key != key) assert(data[h].key != key)
h = nextTry(h, high(data)) h = nextTry(h, high(data))
@ -534,23 +533,23 @@ proc TableRawInsert(data: var TPairSeq, key, val: PObject) =
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc TableEnlarge(t: var TTable) = proc tableEnlarge(t: var TTable) =
var n: TPairSeq var n: TPairSeq
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].key != nil: TableRawInsert(n, t.data[i].key, t.data[i].val) if t.data[i].key != nil: tableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
proc TablePut(t: var TTable, key, val: PObject) = proc tablePut(t: var TTable, key, val: PObject) =
var index = TableRawGet(t, key) var index = TableRawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].val = val t.data[index].val = val
else: else:
if mustRehash(len(t.data), t.counter): TableEnlarge(t) if mustRehash(len(t.data), t.counter): tableEnlarge(t)
TableRawInsert(t.data, key, val) tableRawInsert(t.data, key, val)
inc(t.counter) inc(t.counter)
proc StrTableContains(t: TStrTable, n: PSym): bool = proc strTableContains(t: TStrTable, n: PSym): bool =
var h: THash = n.name.h and high(t.data) # start with real hash value var h: THash = n.name.h and high(t.data) # start with real hash value
while t.data[h] != nil: while t.data[h] != nil:
if (t.data[h] == n): if (t.data[h] == n):
@ -558,7 +557,7 @@ proc StrTableContains(t: TStrTable, n: PSym): bool =
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = false result = false
proc StrTableRawInsert(data: var TSymSeq, n: PSym) = proc strTableRawInsert(data: var TSymSeq, n: PSym) =
var h: THash = n.name.h and high(data) var h: THash = n.name.h and high(data)
while data[h] != nil: while data[h] != nil:
if data[h] == n: if data[h] == n:
@ -569,7 +568,7 @@ proc StrTableRawInsert(data: var TSymSeq, n: PSym) =
assert(data[h] == nil) assert(data[h] == nil)
data[h] = n data[h] = n
proc SymTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) = proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
assert prevSym.name.h == newSym.name.h assert prevSym.name.h == newSym.name.h
var h: THash = prevSym.name.h and high(data) var h: THash = prevSym.name.h and high(data)
while data[h] != nil: while data[h] != nil:
@ -579,22 +578,22 @@ proc SymTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
h = nextTry(h, high(data)) h = nextTry(h, high(data))
assert false assert false
proc SymTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) = proc symTabReplace*(t: var TStrTable, prevSym: PSym, newSym: PSym) =
SymTabReplaceRaw(t.data, prevSym, newSym) symTabReplaceRaw(t.data, prevSym, newSym)
proc StrTableEnlarge(t: var TStrTable) = proc strTableEnlarge(t: var TStrTable) =
var n: TSymSeq var n: TSymSeq
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i] != nil: StrTableRawInsert(n, t.data[i]) if t.data[i] != nil: StrTableRawInsert(n, t.data[i])
swap(t.data, n) swap(t.data, n)
proc StrTableAdd(t: var TStrTable, n: PSym) = proc strTableAdd(t: var TStrTable, n: PSym) =
if mustRehash(len(t.data), t.counter): StrTableEnlarge(t) if mustRehash(len(t.data), t.counter): StrTableEnlarge(t)
StrTableRawInsert(t.data, n) StrTableRawInsert(t.data, n)
inc(t.counter) inc(t.counter)
proc StrTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} = proc strTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} =
# returns true if n is already in the string table: # returns true if n is already in the string table:
# It is essential that `n` is written nevertheless! # It is essential that `n` is written nevertheless!
# This way the newest redefinition is picked by the semantic analyses! # This way the newest redefinition is picked by the semantic analyses!
@ -616,7 +615,7 @@ proc StrTableIncl*(t: var TStrTable, n: PSym): bool {.discardable.} =
inc(t.counter) inc(t.counter)
result = false result = false
proc StrTableGet(t: TStrTable, name: PIdent): PSym = proc strTableGet(t: TStrTable, name: PIdent): PSym =
var h: THash = name.h and high(t.data) var h: THash = name.h and high(t.data)
while true: while true:
result = t.data[h] result = t.data[h]
@ -624,13 +623,13 @@ proc StrTableGet(t: TStrTable, name: PIdent): PSym =
if result.name.id == name.id: break if result.name.id == name.id: break
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
proc InitIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym = proc initIdentIter(ti: var TIdentIter, tab: TStrTable, s: PIdent): PSym =
ti.h = s.h ti.h = s.h
ti.name = s ti.name = s
if tab.Counter == 0: result = nil if tab.Counter == 0: result = nil
else: result = NextIdentIter(ti, tab) else: result = NextIdentIter(ti, tab)
proc NextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym = proc nextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
var h, start: THash var h, start: THash
h = ti.h and high(tab.data) h = ti.h and high(tab.data)
start = h start = h
@ -644,7 +643,7 @@ proc NextIdentIter(ti: var TIdentIter, tab: TStrTable): PSym =
result = tab.data[h] result = tab.data[h]
ti.h = nextTry(h, high(tab.data)) ti.h = nextTry(h, high(tab.data))
proc NextIdentExcluding*(ti: var TIdentIter, tab: TStrTable, proc nextIdentExcluding*(ti: var TIdentIter, tab: TStrTable,
excluding: TIntSet): PSym = excluding: TIntSet): PSym =
var h: THash = ti.h and high(tab.data) var h: THash = ti.h and high(tab.data)
var start = h var start = h
@ -660,33 +659,33 @@ proc NextIdentExcluding*(ti: var TIdentIter, tab: TStrTable,
ti.h = nextTry(h, high(tab.data)) ti.h = nextTry(h, high(tab.data))
if result != nil and Contains(excluding, result.id): result = nil if result != nil and Contains(excluding, result.id): result = nil
proc FirstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent, proc firstIdentExcluding*(ti: var TIdentIter, tab: TStrTable, s: PIdent,
excluding: TIntSet): PSym = excluding: TIntSet): PSym =
ti.h = s.h ti.h = s.h
ti.name = s ti.name = s
if tab.Counter == 0: result = nil if tab.Counter == 0: result = nil
else: result = NextIdentExcluding(ti, tab, excluding) else: result = NextIdentExcluding(ti, tab, excluding)
proc InitTabIter(ti: var TTabIter, tab: TStrTable): PSym = proc initTabIter(ti: var TTabIter, tab: TStrTable): PSym =
ti.h = 0 # we start by zero ... ti.h = 0 # we start by zero ...
if tab.counter == 0: if tab.counter == 0:
result = nil # FIX 1: removed endless loop result = nil # FIX 1: removed endless loop
else: else:
result = NextIter(ti, tab) result = NextIter(ti, tab)
proc NextIter(ti: var TTabIter, tab: TStrTable): PSym = proc nextIter(ti: var TTabIter, tab: TStrTable): PSym =
result = nil result = nil
while (ti.h <= high(tab.data)): while (ti.h <= high(tab.data)):
result = tab.data[ti.h] result = tab.data[ti.h]
Inc(ti.h) # ... and increment by one always inc(ti.h) # ... and increment by one always
if result != nil: break if result != nil: break
iterator items*(tab: TStrTable): PSym = iterator items*(tab: TStrTable): PSym =
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, tab) var s = initTabIter(it, tab)
while s != nil: while s != nil:
yield s yield s
s = NextIter(it, tab) s = nextIter(it, tab)
proc hasEmptySlot(data: TIdPairSeq): bool = proc hasEmptySlot(data: TIdPairSeq): bool =
for h in countup(0, high(data)): for h in countup(0, high(data)):
@ -694,7 +693,7 @@ proc hasEmptySlot(data: TIdPairSeq): bool =
return true return true
result = false result = false
proc IdTableRawGet(t: TIdTable, key: int): int = proc idTableRawGet(t: TIdTable, key: int): int =
var h: THash var h: THash
h = key and high(t.data) # start with real hash value h = key and high(t.data) # start with real hash value
while t.data[h].key != nil: while t.data[h].key != nil:
@ -703,18 +702,18 @@ proc IdTableRawGet(t: TIdTable, key: int): int =
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = - 1 result = - 1
proc IdTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool = proc idTableHasObjectAsKey(t: TIdTable, key: PIdObj): bool =
var index = IdTableRawGet(t, key.id) var index = idTableRawGet(t, key.id)
if index >= 0: result = t.data[index].key == key if index >= 0: result = t.data[index].key == key
else: result = false else: result = false
proc IdTableGet(t: TIdTable, key: PIdObj): PObject = proc idTableGet(t: TIdTable, key: PIdObj): PObject =
var index = IdTableRawGet(t, key.id) var index = idTableRawGet(t, key.id)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = nil else: result = nil
proc IdTableGet(t: TIdTable, key: int): PObject = proc idTableGet(t: TIdTable, key: int): PObject =
var index = IdTableRawGet(t, key) var index = idTableRawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = nil else: result = nil
@ -723,7 +722,7 @@ iterator pairs*(t: TIdTable): tuple[key: int, value: PObject] =
if t.data[i].key != nil: if t.data[i].key != nil:
yield (t.data[i].key.id, t.data[i].val) yield (t.data[i].key.id, t.data[i].val)
proc IdTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) = proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) =
var h: THash var h: THash
h = key.id and high(data) h = key.id and high(data)
while data[h].key != nil: while data[h].key != nil:
@ -733,7 +732,7 @@ proc IdTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: PObject) =
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc IdTablePut(t: var TIdTable, key: PIdObj, val: PObject) = proc idTablePut(t: var TIdTable, key: PIdObj, val: PObject) =
var var
index: int index: int
n: TIdPairSeq n: TIdPairSeq
@ -752,14 +751,11 @@ proc IdTablePut(t: var TIdTable, key: PIdObj, val: PObject) =
IdTableRawInsert(t.data, key, val) IdTableRawInsert(t.data, key, val)
inc(t.counter) inc(t.counter)
iterator IdTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] = iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: PObject] =
for i in 0 .. high(t.data): for i in 0 .. high(t.data):
if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val) if not isNil(t.data[i].key): yield (t.data[i].key, t.data[i].val)
proc writeIdNodeTable(t: TIdNodeTable) = proc idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
nil
proc IdNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
var h: THash var h: THash
h = key.id and high(t.data) # start with real hash value h = key.id and high(t.data) # start with real hash value
while t.data[h].key != nil: while t.data[h].key != nil:
@ -768,17 +764,17 @@ proc IdNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = - 1 result = - 1
proc IdNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode = proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode =
var index: int var index: int
index = IdNodeTableRawGet(t, key) index = idNodeTableRawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = nil else: result = nil
proc IdNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode = proc idNodeTableGetLazy*(t: TIdNodeTable, key: PIdObj): PNode =
if not isNil(t.data): if not isNil(t.data):
result = IdNodeTableGet(t, key) result = idNodeTableGet(t, key)
proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) = proc idNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) =
var h: THash var h: THash
h = key.id and high(data) h = key.id and high(data)
while data[h].key != nil: while data[h].key != nil:
@ -788,7 +784,7 @@ proc IdNodeTableRawInsert(data: var TIdNodePairSeq, key: PIdObj, val: PNode) =
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc IdNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) = proc idNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
var index = IdNodeTableRawGet(t, key) var index = IdNodeTableRawGet(t, key)
if index >= 0: if index >= 0:
assert(t.data[index].key != nil) assert(t.data[index].key != nil)
@ -799,14 +795,14 @@ proc IdNodeTablePut(t: var TIdNodeTable, key: PIdObj, val: PNode) =
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].key != nil: if t.data[i].key != nil:
IdNodeTableRawInsert(n, t.data[i].key, t.data[i].val) idNodeTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
IdNodeTableRawInsert(t.data, key, val) idNodeTableRawInsert(t.data, key, val)
inc(t.counter) inc(t.counter)
proc IdNodeTablePutLazy*(t: var TIdNodeTable, key: PIdObj, val: PNode) = proc idNodeTablePutLazy*(t: var TIdNodeTable, key: PIdObj, val: PNode) =
if isNil(t.data): initIdNodeTable(t) if isNil(t.data): initIdNodeTable(t)
IdNodeTablePut(t, key, val) idNodeTablePut(t, key, val)
iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] = iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
for i in 0 .. high(t.data): for i in 0 .. high(t.data):
@ -817,21 +813,20 @@ proc initIITable(x: var TIITable) =
newSeq(x.data, startSize) newSeq(x.data, startSize)
for i in countup(0, startSize - 1): x.data[i].key = InvalidKey for i in countup(0, startSize - 1): x.data[i].key = InvalidKey
proc IITableRawGet(t: TIITable, key: int): int = proc iiTableRawGet(t: TIITable, key: int): int =
var h: THash var h: THash
h = key and high(t.data) # start with real hash value h = key and high(t.data) # start with real hash value
while t.data[h].key != InvalidKey: while t.data[h].key != InvalidKey:
if (t.data[h].key == key): if t.data[h].key == key: return h
return h
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = - 1 result = -1
proc IITableGet(t: TIITable, key: int): int = proc iiTableGet(t: TIITable, key: int): int =
var index = IITableRawGet(t, key) var index = iiTableRawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = InvalidKey else: result = InvalidKey
proc IITableRawInsert(data: var TIIPairSeq, key, val: int) = proc iiTableRawInsert(data: var TIIPairSeq, key, val: int) =
var h: THash var h: THash
h = key and high(data) h = key and high(data)
while data[h].key != InvalidKey: while data[h].key != InvalidKey:
@ -841,7 +836,7 @@ proc IITableRawInsert(data: var TIIPairSeq, key, val: int) =
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc IITablePut(t: var TIITable, key, val: int) = proc iiTablePut(t: var TIITable, key, val: int) =
var index = IITableRawGet(t, key) var index = IITableRawGet(t, key)
if index >= 0: if index >= 0:
assert(t.data[index].key != InvalidKey) assert(t.data[index].key != InvalidKey)
@ -853,7 +848,7 @@ proc IITablePut(t: var TIITable, key, val: int) =
for i in countup(0, high(n)): n[i].key = InvalidKey for i in countup(0, high(n)): n[i].key = InvalidKey
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].key != InvalidKey: if t.data[i].key != InvalidKey:
IITableRawInsert(n, t.data[i].key, t.data[i].val) iiTableRawInsert(n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
IITableRawInsert(t.data, key, val) iiTableRawInsert(t.data, key, val)
inc(t.counter) inc(t.counter)

View file

@ -18,53 +18,53 @@ type
const const
ElemSize* = sizeof(int8) * 8 ElemSize* = sizeof(int8) * 8
proc BitSetInit*(b: var TBitSet, length: int) proc bitSetInit*(b: var TBitSet, length: int)
proc BitSetUnion*(x: var TBitSet, y: TBitSet) proc bitSetUnion*(x: var TBitSet, y: TBitSet)
proc BitSetDiff*(x: var TBitSet, y: TBitSet) proc bitSetDiff*(x: var TBitSet, y: TBitSet)
proc BitSetSymDiff*(x: var TBitSet, y: TBitSet) proc bitSetSymDiff*(x: var TBitSet, y: TBitSet)
proc BitSetIntersect*(x: var TBitSet, y: TBitSet) proc bitSetIntersect*(x: var TBitSet, y: TBitSet)
proc BitSetIncl*(x: var TBitSet, elem: BiggestInt) proc bitSetIncl*(x: var TBitSet, elem: BiggestInt)
proc BitSetExcl*(x: var TBitSet, elem: BiggestInt) proc bitSetExcl*(x: var TBitSet, elem: BiggestInt)
proc BitSetIn*(x: TBitSet, e: BiggestInt): bool proc bitSetIn*(x: TBitSet, e: BiggestInt): bool
proc BitSetEquals*(x, y: TBitSet): bool proc bitSetEquals*(x, y: TBitSet): bool
proc BitSetContains*(x, y: TBitSet): bool proc bitSetContains*(x, y: TBitSet): bool
# implementation # 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)))) != result = (x[int(e div ElemSize)] and toU8(int(1 shl (e mod ElemSize)))) !=
toU8(0) toU8(0)
proc BitSetIncl(x: var TBitSet, elem: BiggestInt) = proc bitSetIncl(x: var TBitSet, elem: BiggestInt) =
assert(elem >= 0) assert(elem >= 0)
x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or x[int(elem div ElemSize)] = x[int(elem div ElemSize)] or
toU8(int(1 shl (elem mod ElemSize))) 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 x[int(elem div ElemSize)] = x[int(elem div ElemSize)] and
not toU8(int(1 shl (elem mod ElemSize))) 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) 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] 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] 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] 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] for i in countup(0, high(x)): x[i] = x[i] and y[i]
proc BitSetEquals(x, y: TBitSet): bool = proc bitSetEquals(x, y: TBitSet): bool =
for i in countup(0, high(x)): for i in countup(0, high(x)):
if x[i] != y[i]: if x[i] != y[i]:
return false return false
result = true result = true
proc BitSetContains(x, y: TBitSet): bool = proc bitSetContains(x, y: TBitSet): bool =
for i in countup(0, high(x)): for i in countup(0, high(x)):
if (x[i] and not y[i]) != int8(0): if (x[i] and not y[i]) != int8(0):
return false return false

View file

@ -1669,14 +1669,14 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
[rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)]) [rdLoc(d), mangleRecFieldName(t.n.sons[i].sym, t)])
expr(p, it, rec) expr(p, it, rec)
proc IsConstClosure(n: PNode): bool {.inline.} = proc isConstClosure(n: PNode): bool {.inline.} =
result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and result = n.sons[0].kind == nkSym and isRoutine(n.sons[0].sym) and
n.sons[1].kind == nkNilLit n.sons[1].kind == nkNilLit
proc genClosure(p: BProc, n: PNode, d: var TLoc) = proc genClosure(p: BProc, n: PNode, d: var TLoc) =
assert n.kind == nkClosure assert n.kind == nkClosure
if IsConstClosure(n): if isConstClosure(n):
inc(p.labels) inc(p.labels)
var tmp = con("LOC", toRope(p.labels)) var tmp = con("LOC", toRope(p.labels))
appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n", appf(p.module.s[cfsData], "NIM_CONST $1 $2 = $3;$n",

View file

@ -208,7 +208,7 @@ proc readKey(L: var TBaseLexer, result: var string) =
if buf[pos] != ':': internalError("ccgmerge: ':' expected") if buf[pos] != ':': internalError("ccgmerge: ':' expected")
L.bufpos = pos + 1 # skip ':' L.bufpos = pos + 1 # skip ':'
proc NewFakeType(id: int): PType = proc newFakeType(id: int): PType =
new(result) new(result)
result.id = id result.id = id
@ -323,4 +323,3 @@ proc mergeFiles*(cfilename: string, m: BModule) =
m.s[i] = con(old.f[i], m.s[i]) m.s[i] = con(old.f[i], m.s[i])
for i in low(TCProcSection)..high(TCProcSection): for i in low(TCProcSection)..high(TCProcSection):
m.initProc.s(i) = con(old.p[i], m.initProc.s(i)) m.initProc.s(i) = con(old.p[i], m.initProc.s(i))

View file

@ -232,11 +232,11 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
# Lend: # Lend:
var var
a: TLoc a: TLoc
Lelse: TLabel lelse: TLabel
if not isEmptyType(n.typ) and d.k == locNone: if not isEmptyType(n.typ) and d.k == locNone:
getTemp(p, n.typ, d) getTemp(p, n.typ, d)
genLineDir(p, n) genLineDir(p, n)
let Lend = getLabel(p) let lend = getLabel(p)
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
let it = n.sons[i] let it = n.sons[i]
if it.len == 2: if it.len == 2:
@ -251,14 +251,14 @@ proc genIf(p: BProc, n: PNode, d: var TLoc) =
expr(p, it.sons[1], d) expr(p, it.sons[1], d)
endBlock(p) endBlock(p)
if sonsLen(n) > 1: if sonsLen(n) > 1:
lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [Lend]) lineFF(p, cpsStmts, "goto $1;$n", "br label %$1$n", [lend])
fixLabel(p, Lelse) fixLabel(p, Lelse)
elif it.len == 1: elif it.len == 1:
startBlock(p) startBlock(p)
expr(p, it.sons[0], d) expr(p, it.sons[0], d)
endBlock(p) endBlock(p)
else: internalError(n.info, "genIf()") else: internalError(n.info, "genIf()")
if sonsLen(n) > 1: fixLabel(p, Lend) if sonsLen(n) > 1: fixLabel(p, lend)
proc blockLeaveActions(p: BProc, howMany: int) = proc blockLeaveActions(p: BProc, howMany: int) =
var L = p.nestedTryStmts.len var L = p.nestedTryStmts.len
@ -367,7 +367,7 @@ proc genWhileStmt(p: BProc, t: PNode) =
# significantly worse code # significantly worse code
var var
a: TLoc a: TLoc
Labl: TLabel labl: TLabel
assert(sonsLen(t) == 2) assert(sonsLen(t) == 2)
inc(p.withinLoop) inc(p.withinLoop)
genLineDir(p, t) genLineDir(p, t)
@ -499,16 +499,16 @@ proc genCaseGenericBranch(p: BProc, b: PNode, e: TLoc,
proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc, proc genCaseSecondPass(p: BProc, t: PNode, d: var TLoc,
labId, until: int): TLabel = labId, until: int): TLabel =
var Lend = getLabel(p) var lend = getLabel(p)
for i in 1..until: for i in 1..until:
lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)]) lineF(p, cpsStmts, "LA$1: ;$n", [toRope(labId + i)])
if t.sons[i].kind == nkOfBranch: if t.sons[i].kind == nkOfBranch:
var length = sonsLen(t.sons[i]) var length = sonsLen(t.sons[i])
exprBlock(p, t.sons[i].sons[length - 1], d) exprBlock(p, t.sons[i].sons[length - 1], d)
lineF(p, cpsStmts, "goto $1;$n", [Lend]) lineF(p, cpsStmts, "goto $1;$n", [lend])
else: else:
exprBlock(p, t.sons[i].sons[0], d) exprBlock(p, t.sons[i].sons[0], d)
result = Lend result = lend
proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc, proc genIfForCaseUntil(p: BProc, t: PNode, d: var TLoc,
rangeFormat, eqFormat: TFormatStr, rangeFormat, eqFormat: TFormatStr,
@ -535,8 +535,8 @@ proc genCaseGeneric(p: BProc, t: PNode, d: var TLoc,
rangeFormat, eqFormat: TFormatStr) = rangeFormat, eqFormat: TFormatStr) =
var a: TLoc var a: TLoc
initLocExpr(p, t.sons[0], a) initLocExpr(p, t.sons[0], a)
var Lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a) var lend = genIfForCaseUntil(p, t, d, rangeFormat, eqFormat, sonsLen(t)-1, a)
fixLabel(p, Lend) fixLabel(p, lend)
proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel, proc genCaseStringBranch(p: BProc, b: PNode, e: TLoc, labl: TLabel,
branches: var openArray[PRope]) = branches: var openArray[PRope]) =
@ -580,8 +580,8 @@ proc genStringCase(p: BProc, t: PNode, d: var TLoc) =
if t.sons[sonsLen(t)-1].kind != nkOfBranch: if t.sons[sonsLen(t)-1].kind != nkOfBranch:
lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)]) lineF(p, cpsStmts, "goto LA$1;$n", [toRope(p.labels)])
# third pass: generate statements # third pass: generate statements
var Lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1) var lend = genCaseSecondPass(p, t, d, labId, sonsLen(t)-1)
fixLabel(p, Lend) fixLabel(p, lend)
else: else:
genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n") genCaseGeneric(p, t, d, "", "if (#eqStrings($1, $2)) goto $3;$n")
@ -592,7 +592,7 @@ proc branchHasTooBigRange(b: PNode): bool =
b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit: b.sons[i].sons[1].intVal - b.sons[i].sons[0].intVal > RangeExpandLimit:
return true return true
proc IfSwitchSplitPoint(p: BProc, n: PNode): int = proc ifSwitchSplitPoint(p: BProc, n: PNode): int =
for i in 1..n.len-1: for i in 1..n.len-1:
var branch = n[i] var branch = n[i]
var stmtBlock = lastSon(branch) var stmtBlock = lastSon(branch)
@ -625,7 +625,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
# generate if part (might be empty): # generate if part (might be empty):
var a: TLoc var a: TLoc
initLocExpr(p, n.sons[0], a) initLocExpr(p, n.sons[0], a)
var Lend = if splitPoint > 0: genIfForCaseUntil(p, n, d, var lend = if splitPoint > 0: genIfForCaseUntil(p, n, d,
rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n", rangeFormat = "if ($1 >= $2 && $1 <= $3) goto $4;$n",
eqFormat = "if ($1 == $2) goto $3;$n", eqFormat = "if ($1 == $2) goto $3;$n",
splitPoint, a) else: nil splitPoint, a) else: nil
@ -647,7 +647,7 @@ proc genOrdinalCase(p: BProc, n: PNode, d: var TLoc) =
if (hasAssume in CC[ccompiler].props) and not hasDefault: if (hasAssume in CC[ccompiler].props) and not hasDefault:
lineF(p, cpsStmts, "default: __assume(0);$n") lineF(p, cpsStmts, "default: __assume(0);$n")
lineF(p, cpsStmts, "}$n") lineF(p, cpsStmts, "}$n")
if Lend != nil: fixLabel(p, Lend) if lend != nil: fixLabel(p, lend)
proc genCase(p: BProc, t: PNode, d: var TLoc) = proc genCase(p: BProc, t: PNode, d: var TLoc) =
genLineDir(p, t) genLineDir(p, t)
@ -928,7 +928,7 @@ proc genPragma(p: BProc, n: PNode) =
p.module.injectStmt = p.s(cpsStmts) p.module.injectStmt = p.s(cpsStmts)
else: discard else: discard
proc FieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool = proc fieldDiscriminantCheckNeeded(p: BProc, asgn: PNode): bool =
if optFieldCheck in p.options: if optFieldCheck in p.options:
var le = asgn.sons[0] var le = asgn.sons[0]
if le.kind == nkCheckedFieldExpr: if le.kind == nkCheckedFieldExpr:

View file

@ -17,7 +17,7 @@ proc emulatedThreadVars(): bool =
proc accessThreadLocalVar(p: BProc, s: PSym) = proc accessThreadLocalVar(p: BProc, s: PSym) =
if emulatedThreadVars() and not p.ThreadVarAccessed: if emulatedThreadVars() and not p.ThreadVarAccessed:
p.ThreadVarAccessed = true p.threadVarAccessed = true
p.module.usesThreadVars = true p.module.usesThreadVars = true
appf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n") appf(p.procSec(cpsLocals), "\tNimThreadVars* NimTV;$n")
app(p.procSec(cpsInit), app(p.procSec(cpsInit),
@ -55,7 +55,7 @@ proc generateThreadLocalStorage(m: BModule) =
for t in items(nimtvDeps): discard getTypeDesc(m, t) for t in items(nimtvDeps): discard getTypeDesc(m, t)
appf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv]) appf(m.s[cfsSeqTypes], "typedef struct {$1} NimThreadVars;$n", [nimtv])
proc GenerateThreadVarsSize(m: BModule) = proc generateThreadVarsSize(m: BModule) =
if nimtv != nil: if nimtv != nil:
app(m.s[cfsProcs], app(m.s[cfsProcs],
"NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}" & tnl) "NI NimThreadVarsSize(){return (NI)sizeof(NimThreadVars);}" & tnl)

View file

@ -229,11 +229,11 @@ const
"stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline", "stdcall $1", "ccc $1", "safecall $1", "syscall $1", "$1 alwaysinline",
"$1 noinline", "fastcc $1", "ccc $1", "$1"] "$1 noinline", "fastcc $1", "ccc $1", "$1"]
proc CacheGetType(tab: TIdTable, key: PType): PRope = proc cacheGetType(tab: TIdTable, key: PType): PRope =
# returns nil if we need to declare this type # returns nil if we need to declare this type
# since types are now unique via the ``GetUniqueType`` mechanism, this slow # since types are now unique via the ``GetUniqueType`` mechanism, this slow
# linear search is not necessary anymore: # linear search is not necessary anymore:
result = PRope(IdTableGet(tab, key)) result = PRope(idTableGet(tab, key))
proc getTempName(): PRope = proc getTempName(): PRope =
result = rfmt(nil, "TMP$1", toRope(backendId())) result = rfmt(nil, "TMP$1", toRope(backendId()))
@ -952,4 +952,4 @@ proc genTypeInfo(m: BModule, t: PType): PRope =
result = con("(&".toRope, result, ")".toRope) result = con("(&".toRope, result, ")".toRope)
proc genTypeSection(m: BModule, n: PNode) = proc genTypeSection(m: BModule, n: PNode) =
nil discard

View file

@ -22,7 +22,7 @@ proc getPragmaStmt*(n: PNode, w: TSpecialWord): PNode =
of nkPragma: of nkPragma:
for i in 0 .. < n.len: for i in 0 .. < n.len:
if whichPragma(n[i]) == w: return n[i] if whichPragma(n[i]) == w: return n[i]
else: nil else: discard
proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool = proc stmtsContainPragma*(n: PNode, w: TSpecialWord): bool =
result = getPragmaStmt(n, w) != nil result = getPragmaStmt(n, w) != nil
@ -70,7 +70,7 @@ when false:
for i in countup(low(TTypeKind), high(TTypeKind)): for i in countup(low(TTypeKind), high(TTypeKind)):
echo i, " ", gTypeTable[i].counter echo i, " ", gTypeTable[i].counter
proc GetUniqueType*(key: PType): PType = proc getUniqueType*(key: PType): PType =
# this is a hotspot in the compiler! # this is a hotspot in the compiler!
if key == nil: return if key == nil: return
var k = key.kind var k = key.kind
@ -87,11 +87,11 @@ proc GetUniqueType*(key: PType): PType =
gCanonicalTypes[k] = key gCanonicalTypes[k] = key
result = key result = key
of tyTypeDesc, tyTypeClasses: of tyTypeDesc, tyTypeClasses:
InternalError("value expected, but got a type") internalError("value expected, but got a type")
of tyGenericParam: of tyGenericParam:
InternalError("GetUniqueType") internalError("GetUniqueType")
of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter: of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter:
result = GetUniqueType(lastSon(key)) result = getUniqueType(lastSon(key))
of tyArrayConstr, tyGenericInvokation, tyGenericBody, of tyArrayConstr, tyGenericInvokation, tyGenericBody,
tyOpenArray, tyArray, tySet, tyRange, tyTuple, tyOpenArray, tyArray, tySet, tyRange, tyTuple,
tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar: tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar:
@ -102,33 +102,33 @@ proc GetUniqueType*(key: PType): PType =
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need
# to be compared by their structure: # to be compared by their structure:
if IdTableHasObjectAsKey(gTypeTable[k], key): return key if idTableHasObjectAsKey(gTypeTable[k], key): return key
for h in countup(0, high(gTypeTable[k].data)): for h in countup(0, high(gTypeTable[k].data)):
var t = PType(gTypeTable[k].data[h].key) var t = PType(gTypeTable[k].data[h].key)
if t != nil and sameBackendType(t, key): if t != nil and sameBackendType(t, key):
return t return t
IdTablePut(gTypeTable[k], key, key) idTablePut(gTypeTable[k], key, key)
result = key result = key
of tyObject: of tyObject:
if tfFromGeneric notin key.flags: if tfFromGeneric notin key.flags:
# fast case; lookup per id suffices: # fast case; lookup per id suffices:
result = PType(IdTableGet(gTypeTable[k], key)) result = PType(idTableGet(gTypeTable[k], key))
if result == nil: if result == nil:
IdTablePut(gTypeTable[k], key, key) idTablePut(gTypeTable[k], key, key)
result = key result = key
else: else:
# ugly slow case: need to compare by structure # ugly slow case: need to compare by structure
if IdTableHasObjectAsKey(gTypeTable[k], key): return key if idTableHasObjectAsKey(gTypeTable[k], key): return key
for h in countup(0, high(gTypeTable[k].data)): for h in countup(0, high(gTypeTable[k].data)):
var t = PType(gTypeTable[k].data[h].key) var t = PType(gTypeTable[k].data[h].key)
if t != nil and sameType(t, key): if t != nil and sameType(t, key):
return t return t
IdTablePut(gTypeTable[k], key, key) idTablePut(gTypeTable[k], key, key)
result = key result = key
of tyEnum: of tyEnum:
result = PType(IdTableGet(gTypeTable[k], key)) result = PType(idTableGet(gTypeTable[k], key))
if result == nil: if result == nil:
IdTablePut(gTypeTable[k], key, key) idTablePut(gTypeTable[k], key, key)
result = key result = key
of tyProc: of tyProc:
# tyVar is not 100% correct, but would speeds things up a little: # tyVar is not 100% correct, but would speeds things up a little:
@ -136,17 +136,17 @@ proc GetUniqueType*(key: PType): PType =
result = key result = key
else: else:
# ugh, we need the canon here: # ugh, we need the canon here:
if IdTableHasObjectAsKey(gTypeTable[k], key): return key if idTableHasObjectAsKey(gTypeTable[k], key): return key
for h in countup(0, high(gTypeTable[k].data)): for h in countup(0, high(gTypeTable[k].data)):
var t = PType(gTypeTable[k].data[h].key) var t = PType(gTypeTable[k].data[h].key)
if t != nil and sameBackendType(t, key): if t != nil and sameBackendType(t, key):
return t return t
IdTablePut(gTypeTable[k], key, key) idTablePut(gTypeTable[k], key, key)
result = key result = key
proc TableGetType*(tab: TIdTable, key: PType): PObject = proc tableGetType*(tab: TIdTable, key: PType): PObject =
# returns nil if we need to declare this type # returns nil if we need to declare this type
result = IdTableGet(tab, key) result = idTableGet(tab, key)
if (result == nil) and (tab.counter > 0): if (result == nil) and (tab.counter > 0):
# we have to do a slow linear search because types may need # we have to do a slow linear search because types may need
# to be compared by their structure: # to be compared by their structure:
@ -178,4 +178,4 @@ proc makeLLVMString*(s: string): PRope =
add(res, "\\00\"") add(res, "\\00\"")
app(result, toRope(res)) app(result, toRope(res))
InitTypeTables() initTypeTables()

View file

@ -513,7 +513,7 @@ proc assignLocalVar(p: BProc, s: PSym) =
include ccgthreadvars include ccgthreadvars
proc VarInDynamicLib(m: BModule, sym: PSym) proc varInDynamicLib(m: BModule, sym: PSym)
proc mangleDynLibProc(sym: PSym): PRope proc mangleDynLibProc(sym: PSym): PRope
proc assignGlobalVar(p: BProc, s: PSym) = proc assignGlobalVar(p: BProc, s: PSym) =
@ -641,7 +641,7 @@ proc mangleDynLibProc(sym: PSym): PRope =
else: else:
result = ropef("Dl_$1", [toRope(sym.id)]) result = ropef("Dl_$1", [toRope(sym.id)])
proc SymInDynamicLib(m: BModule, sym: PSym) = proc symInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex var lib = sym.annex
let isCall = isGetProcAddr(lib) let isCall = isGetProcAddr(lib)
var extname = sym.loc.r var extname = sym.loc.r
@ -682,7 +682,7 @@ proc SymInDynamicLib(m: BModule, sym: PSym) =
"$1 = linkonce global $2 zeroinitializer$n", "$1 = linkonce global $2 zeroinitializer$n",
[sym.loc.r, getTypeDesc(m, sym.loc.t)]) [sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc VarInDynamicLib(m: BModule, sym: PSym) = proc varInDynamicLib(m: BModule, sym: PSym) =
var lib = sym.annex var lib = sym.annex
var extname = sym.loc.r var extname = sym.loc.r
loadDynamicLib(m, lib) loadDynamicLib(m, lib)
@ -697,7 +697,7 @@ proc VarInDynamicLib(m: BModule, sym: PSym) =
appf(m.s[cfsVars], "$2* $1;$n", appf(m.s[cfsVars], "$2* $1;$n",
[sym.loc.r, getTypeDesc(m, sym.loc.t)]) [sym.loc.r, getTypeDesc(m, sym.loc.t)])
proc SymInDynamicLibPartial(m: BModule, sym: PSym) = proc symInDynamicLibPartial(m: BModule, sym: PSym) =
sym.loc.r = mangleDynLibProc(sym) sym.loc.r = mangleDynLibProc(sym)
sym.typ.sym = nil # generate a new name sym.typ.sym = nil # generate a new name

View file

@ -126,14 +126,14 @@ proc cmpSignatures(a, b: PSym, relevantCols: TIntSet): int =
proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) = proc sortBucket(a: var TSymSeq, relevantCols: TIntSet) =
# we use shellsort here; fast and simple # we use shellsort here; fast and simple
var N = len(a) var n = len(a)
var h = 1 var h = 1
while true: while true:
h = 3 * h + 1 h = 3 * h + 1
if h > N: break if h > n: break
while true: while true:
h = h div 3 h = h div 3
for i in countup(h, N - 1): for i in countup(h, n - 1):
var v = a[i] var v = a[i]
var j = i var j = i
while cmpSignatures(a[j - h], v, relevantCols) >= 0: while cmpSignatures(a[j - h], v, relevantCols) >= 0:

View file

@ -21,7 +21,7 @@ type
passCmd2, # second pass over the command line passCmd2, # second pass over the command line
passPP # preprocessor called ProcessCommand() passPP # preprocessor called ProcessCommand()
proc ProcessCommand*(switch: string, pass: TCmdLinePass) proc processCommand*(switch: string, pass: TCmdLinePass)
proc processSwitch*(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) proc processSwitch*(switch, arg: string, pass: TCmdlinePass, info: TLineInfo)
# implementation # implementation
@ -38,21 +38,21 @@ proc getCommandLineDesc(): string =
result = (HelpMessage % [VersionAsString, platform.os[platform.hostOS].name, result = (HelpMessage % [VersionAsString, platform.os[platform.hostOS].name,
cpu[platform.hostCPU].name]) & Usage cpu[platform.hostCPU].name]) & Usage
proc HelpOnError(pass: TCmdLinePass) = proc helpOnError(pass: TCmdLinePass) =
if pass == passCmd1: if pass == passCmd1:
MsgWriteln(getCommandLineDesc()) msgWriteln(getCommandLineDesc())
quit(0) quit(0)
proc writeAdvancedUsage(pass: TCmdLinePass) = proc writeAdvancedUsage(pass: TCmdLinePass) =
if pass == passCmd1: if pass == passCmd1:
MsgWriteln(`%`(HelpMessage, [VersionAsString, msgWriteln(`%`(HelpMessage, [VersionAsString,
platform.os[platform.hostOS].name, platform.os[platform.hostOS].name,
cpu[platform.hostCPU].name]) & AdvancedUsage) cpu[platform.hostCPU].name]) & AdvancedUsage)
quit(0) quit(0)
proc writeVersionInfo(pass: TCmdLinePass) = proc writeVersionInfo(pass: TCmdLinePass) =
if pass == passCmd1: if pass == passCmd1:
MsgWriteln(`%`(HelpMessage, [VersionAsString, msgWriteln(`%`(HelpMessage, [VersionAsString,
platform.os[platform.hostOS].name, platform.os[platform.hostOS].name,
cpu[platform.hostCPU].name])) cpu[platform.hostCPU].name]))
quit(0) quit(0)
@ -62,16 +62,16 @@ var
proc writeCommandLineUsage() = proc writeCommandLineUsage() =
if not helpWritten: if not helpWritten:
MsgWriteln(getCommandLineDesc()) msgWriteln(getCommandLineDesc())
helpWritten = true helpWritten = true
proc addPrefix(switch: string): string = proc addPrefix(switch: string): string =
if len(switch) == 1: result = "-" & switch if len(switch) == 1: result = "-" & switch
else: result = "--" & switch else: result = "--" & switch
proc InvalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) = proc invalidCmdLineOption(pass: TCmdLinePass, switch: string, info: TLineInfo) =
if switch == " ": LocalError(info, errInvalidCmdLineOption, "-") if switch == " ": localError(info, errInvalidCmdLineOption, "-")
else: LocalError(info, errInvalidCmdLineOption, addPrefix(switch)) else: localError(info, errInvalidCmdLineOption, addPrefix(switch))
proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass, proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
info: TLineInfo) = info: TLineInfo) =
@ -86,29 +86,29 @@ proc splitSwitch(switch: string, cmd, arg: var string, pass: TCmdLinePass,
inc(i) inc(i)
if i >= len(switch): arg = "" if i >= len(switch): arg = ""
elif switch[i] in {':', '=', '['}: arg = substr(switch, i + 1) elif switch[i] in {':', '=', '['}: arg = substr(switch, i + 1)
else: InvalidCmdLineOption(pass, switch, info) else: invalidCmdLineOption(pass, switch, info)
proc ProcessOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass, proc processOnOffSwitch(op: TOptions, arg: string, pass: TCmdlinePass,
info: TLineInfo) = info: TLineInfo) =
case whichKeyword(arg) case whichKeyword(arg)
of wOn: gOptions = gOptions + op of wOn: gOptions = gOptions + op
of wOff: gOptions = gOptions - op of wOff: gOptions = gOptions - op
else: LocalError(info, errOnOrOffExpectedButXFound, arg) else: localError(info, errOnOrOffExpectedButXFound, arg)
proc ProcessOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdlinePass, proc processOnOffSwitchG(op: TGlobalOptions, arg: string, pass: TCmdlinePass,
info: TLineInfo) = info: TLineInfo) =
case whichKeyword(arg) case whichKeyword(arg)
of wOn: gGlobalOptions = gGlobalOptions + op of wOn: gGlobalOptions = gGlobalOptions + op
of wOff: gGlobalOptions = gGlobalOptions - op of wOff: gGlobalOptions = gGlobalOptions - op
else: LocalError(info, errOnOrOffExpectedButXFound, arg) else: localError(info, errOnOrOffExpectedButXFound, arg)
proc ExpectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = proc expectArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
if arg == "": LocalError(info, errCmdLineArgExpected, addPrefix(switch)) if arg == "": localError(info, errCmdLineArgExpected, addPrefix(switch))
proc ExpectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) = proc expectNoArg(switch, arg: string, pass: TCmdLinePass, info: TLineInfo) =
if arg != "": LocalError(info, errCmdLineNoArgExpected, addPrefix(switch)) if arg != "": localError(info, errCmdLineNoArgExpected, addPrefix(switch))
proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass, proc processSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
info: TLineInfo) = info: TLineInfo) =
var id = "" # arg = "X]:on|off" var id = "" # arg = "X]:on|off"
var i = 0 var i = 0
@ -117,21 +117,21 @@ proc ProcessSpecificNote(arg: string, state: TSpecialWord, pass: TCmdlinePass,
add(id, arg[i]) add(id, arg[i])
inc(i) inc(i)
if i < len(arg) and (arg[i] == ']'): inc(i) if i < len(arg) and (arg[i] == ']'): inc(i)
else: InvalidCmdLineOption(pass, arg, info) else: invalidCmdLineOption(pass, arg, info)
if i < len(arg) and (arg[i] in {':', '='}): inc(i) if i < len(arg) and (arg[i] in {':', '='}): inc(i)
else: InvalidCmdLineOption(pass, arg, info) else: invalidCmdLineOption(pass, arg, info)
if state == wHint: if state == wHint:
var x = findStr(msgs.HintsToStr, id) var x = findStr(msgs.HintsToStr, id)
if x >= 0: n = TNoteKind(x + ord(hintMin)) if x >= 0: n = TNoteKind(x + ord(hintMin))
else: InvalidCmdLineOption(pass, arg, info) else: invalidCmdLineOption(pass, arg, info)
else: else:
var x = findStr(msgs.WarningsToStr, id) var x = findStr(msgs.WarningsToStr, id)
if x >= 0: n = TNoteKind(x + ord(warnMin)) if x >= 0: n = TNoteKind(x + ord(warnMin))
else: InvalidCmdLineOption(pass, arg, info) else: invalidCmdLineOption(pass, arg, info)
case whichKeyword(substr(arg, i)) case whichKeyword(substr(arg, i))
of wOn: incl(gNotes, n) of wOn: incl(gNotes, n)
of wOff: excl(gNotes, n) of wOff: excl(gNotes, n)
else: LocalError(info, errOnOrOffExpectedButXFound, arg) else: localError(info, errOnOrOffExpectedButXFound, arg)
proc processCompile(filename: string) = proc processCompile(filename: string) =
var found = findFile(filename) var found = findFile(filename)
@ -150,14 +150,14 @@ proc testCompileOptionArg*(switch, arg: string, info: TLineInfo): bool =
of "markandsweep": result = gSelectedGC == gcMarkAndSweep of "markandsweep": result = gSelectedGC == gcMarkAndSweep
of "generational": result = gSelectedGC == gcGenerational of "generational": result = gSelectedGC == gcGenerational
of "none": result = gSelectedGC == gcNone of "none": result = gSelectedGC == gcNone
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) else: localError(info, errNoneBoehmRefcExpectedButXFound, arg)
of "opt": of "opt":
case arg.normalize case arg.normalize
of "speed": result = contains(gOptions, optOptimizeSpeed) of "speed": result = contains(gOptions, optOptimizeSpeed)
of "size": result = contains(gOptions, optOptimizeSize) of "size": result = contains(gOptions, optOptimizeSize)
of "none": result = gOptions * {optOptimizeSpeed, optOptimizeSize} == {} of "none": result = gOptions * {optOptimizeSpeed, optOptimizeSize} == {}
else: LocalError(info, errNoneSpeedOrSizeExpectedButXFound, arg) else: localError(info, errNoneSpeedOrSizeExpectedButXFound, arg)
else: InvalidCmdLineOption(passCmd1, switch, info) else: invalidCmdLineOption(passCmd1, switch, info)
proc testCompileOption*(switch: string, info: TLineInfo): bool = proc testCompileOption*(switch: string, info: TLineInfo): bool =
case switch.normalize case switch.normalize
@ -194,7 +194,7 @@ proc testCompileOption*(switch: string, info: TLineInfo): bool =
of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation) of "tlsemulation": result = contains(gGlobalOptions, optTlsEmulation)
of "implicitstatic": result = contains(gOptions, optImplicitStatic) of "implicitstatic": result = contains(gOptions, optImplicitStatic)
of "patterns": result = contains(gOptions, optPatterns) of "patterns": result = contains(gOptions, optPatterns)
else: InvalidCmdLineOption(passCmd1, switch, info) else: invalidCmdLineOption(passCmd1, switch, info)
proc processPath(path: string, notRelativeToProj = false): string = proc processPath(path: string, notRelativeToProj = false): string =
let p = if notRelativeToProj or os.isAbsolute(path) or let p = if notRelativeToProj or os.isAbsolute(path) or
@ -202,20 +202,20 @@ proc processPath(path: string, notRelativeToProj = false): string =
path path
else: else:
options.gProjectPath / path options.gProjectPath / path
result = UnixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath, result = unixToNativePath(p % ["nimrod", getPrefixDir(), "lib", libpath,
"home", removeTrailingDirSep(os.getHomeDir()), "home", removeTrailingDirSep(os.getHomeDir()),
"projectname", options.gProjectName, "projectname", options.gProjectName,
"projectpath", options.gProjectPath]) "projectpath", options.gProjectPath])
proc trackDirty(arg: string, info: TLineInfo) = proc trackDirty(arg: string, info: TLineInfo) =
var a = arg.split(',') var a = arg.split(',')
if a.len != 4: LocalError(info, errTokenExpected, if a.len != 4: localError(info, errTokenExpected,
"DIRTY_BUFFER,ORIGINAL_FILE,LINE,COLUMN") "DIRTY_BUFFER,ORIGINAL_FILE,LINE,COLUMN")
var line, column: int var line, column: int
if parseUtils.parseInt(a[2], line) <= 0: if parseUtils.parseInt(a[2], line) <= 0:
LocalError(info, errInvalidNumber, a[1]) localError(info, errInvalidNumber, a[1])
if parseUtils.parseInt(a[3], column) <= 0: if parseUtils.parseInt(a[3], column) <= 0:
LocalError(info, errInvalidNumber, a[2]) localError(info, errInvalidNumber, a[2])
gDirtyBufferIdx = a[0].fileInfoIdx gDirtyBufferIdx = a[0].fileInfoIdx
gDirtyOriginalIdx = a[1].fileInfoIdx gDirtyOriginalIdx = a[1].fileInfoIdx
@ -225,12 +225,12 @@ proc trackDirty(arg: string, info: TLineInfo) =
proc track(arg: string, info: TLineInfo) = proc track(arg: string, info: TLineInfo) =
var a = arg.split(',') var a = arg.split(',')
if a.len != 3: LocalError(info, errTokenExpected, "FILE,LINE,COLUMN") if a.len != 3: localError(info, errTokenExpected, "FILE,LINE,COLUMN")
var line, column: int var line, column: int
if parseUtils.parseInt(a[1], line) <= 0: if parseUtils.parseInt(a[1], line) <= 0:
LocalError(info, errInvalidNumber, a[1]) localError(info, errInvalidNumber, a[1])
if parseUtils.parseInt(a[2], column) <= 0: if parseUtils.parseInt(a[2], column) <= 0:
LocalError(info, errInvalidNumber, a[2]) localError(info, errInvalidNumber, a[2])
optTrackPos = newLineInfo(a[0], line, column) optTrackPos = newLineInfo(a[0], line, column)
msgs.addCheckpoint(optTrackPos) msgs.addCheckpoint(optTrackPos)
@ -305,7 +305,7 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
case arg.normalize case arg.normalize
of "boehm": of "boehm":
gSelectedGC = gcBoehm gSelectedGC = gcBoehm
DefineSymbol("boehmgc") defineSymbol("boehmgc")
of "refc": of "refc":
gSelectedGC = gcRefc gSelectedGC = gcRefc
of "v2": of "v2":
@ -319,8 +319,8 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
of "none": of "none":
gSelectedGC = gcNone gSelectedGC = gcNone
defineSymbol("nogc") defineSymbol("nogc")
else: LocalError(info, errNoneBoehmRefcExpectedButXFound, arg) else: localError(info, errNoneBoehmRefcExpectedButXFound, arg)
of "warnings", "w": ProcessOnOffSwitch({optWarns}, arg, pass, info) of "warnings", "w": processOnOffSwitch({optWarns}, arg, pass, info)
of "warning": ProcessSpecificNote(arg, wWarning, pass, info) of "warning": ProcessSpecificNote(arg, wWarning, pass, info)
of "hint": ProcessSpecificNote(arg, wHint, pass, info) of "hint": ProcessSpecificNote(arg, wHint, pass, info)
of "hints": ProcessOnOffSwitch({optHints}, arg, pass, info) of "hints": ProcessOnOffSwitch({optHints}, arg, pass, info)
@ -517,13 +517,13 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) =
case arg case arg
of "partial": idents.firstCharIsCS = true of "partial": idents.firstCharIsCS = true
of "none": idents.firstCharIsCS = false of "none": idents.firstCharIsCS = false
else: LocalError(info, errGenerated, else: localError(info, errGenerated,
"'partial' or 'none' expected, but found " & arg) "'partial' or 'none' expected, but found " & arg)
else: else:
if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg) if strutils.find(switch, '.') >= 0: options.setConfigVar(switch, arg)
else: InvalidCmdLineOption(pass, switch, info) else: invalidCmdLineOption(pass, switch, info)
proc ProcessCommand(switch: string, pass: TCmdLinePass) = proc processCommand(switch: string, pass: TCmdLinePass) =
var cmd, arg: string var cmd, arg: string
splitSwitch(switch, cmd, arg, pass, gCmdLineInfo) splitSwitch(switch, cmd, arg, pass, gCmdLineInfo)
processSwitch(cmd, arg, pass, gCmdLineInfo) processSwitch(cmd, arg, pass, gCmdLineInfo)

View file

@ -16,10 +16,10 @@ import
# to be style insensitive. Otherwise hell would break lose. # to be style insensitive. Otherwise hell would break lose.
var gSymbols: PStringTable var gSymbols: PStringTable
proc DefineSymbol*(symbol: string) = proc defineSymbol*(symbol: string) =
gSymbols[symbol] = "true" gSymbols[symbol] = "true"
proc UndefSymbol*(symbol: string) = proc undefSymbol*(symbol: string) =
gSymbols[symbol] = "false" gSymbols[symbol] = "false"
proc isDefined*(symbol: string): bool = proc isDefined*(symbol: string): bool =
@ -37,52 +37,52 @@ proc countDefinedSymbols*(): int =
for key, val in pairs(gSymbols): for key, val in pairs(gSymbols):
if val == "true": inc(result) if val == "true": inc(result)
proc InitDefines*() = proc initDefines*() =
gSymbols = newStringTable(modeStyleInsensitive) gSymbols = newStringTable(modeStyleInsensitive)
DefineSymbol("nimrod") # 'nimrod' is always defined defineSymbol("nimrod") # 'nimrod' is always defined
# for bootstrapping purposes and old code: # for bootstrapping purposes and old code:
DefineSymbol("nimhygiene") defineSymbol("nimhygiene")
DefineSymbol("niminheritable") defineSymbol("niminheritable")
DefineSymbol("nimmixin") defineSymbol("nimmixin")
DefineSymbol("nimeffects") defineSymbol("nimeffects")
DefineSymbol("nimbabel") defineSymbol("nimbabel")
DefineSymbol("nimcomputedgoto") defineSymbol("nimcomputedgoto")
# add platform specific symbols: # add platform specific symbols:
case targetCPU case targetCPU
of cpuI386: DefineSymbol("x86") of cpuI386: defineSymbol("x86")
of cpuIa64: DefineSymbol("itanium") of cpuIa64: defineSymbol("itanium")
of cpuAmd64: DefineSymbol("x8664") of cpuAmd64: defineSymbol("x8664")
else: discard else: discard
case targetOS case targetOS
of osDOS: of osDOS:
DefineSymbol("msdos") defineSymbol("msdos")
of osWindows: of osWindows:
DefineSymbol("mswindows") defineSymbol("mswindows")
DefineSymbol("win32") defineSymbol("win32")
of osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX, osAtari, osAix, of osLinux, osMorphOS, osSkyOS, osIrix, osPalmOS, osQNX, osAtari, osAix,
osHaiku: osHaiku:
# these are all 'unix-like' # these are all 'unix-like'
DefineSymbol("unix") defineSymbol("unix")
DefineSymbol("posix") defineSymbol("posix")
of osSolaris: of osSolaris:
DefineSymbol("sunos") defineSymbol("sunos")
DefineSymbol("unix") defineSymbol("unix")
DefineSymbol("posix") defineSymbol("posix")
of osNetBSD, osFreeBSD, osOpenBSD: of osNetBSD, osFreeBSD, osOpenBSD:
DefineSymbol("unix") defineSymbol("unix")
DefineSymbol("bsd") defineSymbol("bsd")
DefineSymbol("posix") defineSymbol("posix")
of osMacOS: of osMacOS:
DefineSymbol("macintosh") defineSymbol("macintosh")
of osMacOSX: of osMacOSX:
DefineSymbol("macintosh") defineSymbol("macintosh")
DefineSymbol("unix") defineSymbol("unix")
DefineSymbol("posix") DefineSymbol("posix")
else: discard else: discard
DefineSymbol("cpu" & $cpu[targetCPU].bit) defineSymbol("cpu" & $cpu[targetCPU].bit)
DefineSymbol(normalize(endianToStr[cpu[targetCPU].endian])) defineSymbol(normalize(endianToStr[cpu[targetCPU].endian]))
DefineSymbol(cpu[targetCPU].name) defineSymbol(cpu[targetCPU].name)
DefineSymbol(platform.os[targetOS].name) defineSymbol(platform.os[targetOS].name)
if platform.OS[targetOS].props.contains(ospLacksThreadVars): if platform.OS[targetOS].props.contains(ospLacksThreadVars):
DefineSymbol("emulatedthreadvars") defineSymbol("emulatedthreadvars")

View file

@ -313,7 +313,7 @@ proc generateDoc*(d: PDoc, n: PNode) =
of nkImportStmt: of nkImportStmt:
for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i]) for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i])
of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0]) of nkFromStmt, nkImportExceptStmt: traceDeps(d, n.sons[0])
else: nil else: discard
proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode = proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode =
case n.kind case n.kind
@ -355,7 +355,7 @@ proc generateJson(d: PDoc, n: PNode, jArray: PJsonNode = nil): PJsonNode =
# generate documentation for the first branch only: # generate documentation for the first branch only:
if not checkForFalse(n.sons[0].sons[0]) and jArray != nil: if not checkForFalse(n.sons[0].sons[0]) and jArray != nil:
discard generateJson(d, lastSon(n.sons[0]), jArray) discard generateJson(d, lastSon(n.sons[0]), jArray)
else: nil else: discard
proc genSection(d: PDoc, kind: TSymKind) = proc genSection(d: PDoc, kind: TSymKind) =
const sectionNames: array[skModule..skTemplate, string] = [ const sectionNames: array[skModule..skTemplate, string] = [
@ -417,7 +417,7 @@ proc writeOutput*(d: PDoc, filename, outExt: string, useWarning = false) =
else: else:
writeRope(content, getOutFile(filename, outExt), useWarning) writeRope(content, getOutFile(filename, outExt), useWarning)
proc CommandDoc*() = proc commandDoc*() =
var ast = parseFile(gProjectMainIdx) var ast = parseFile(gProjectMainIdx)
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
@ -426,7 +426,7 @@ proc CommandDoc*() =
writeOutput(d, gProjectFull, HtmlExt) writeOutput(d, gProjectFull, HtmlExt)
generateIndex(d) generateIndex(d)
proc CommandRstAux(filename, outExt: string) = proc commandRstAux(filename, outExt: string) =
var filen = addFileExt(filename, "txt") var filen = addFileExt(filename, "txt")
var d = newDocumentor(filen, options.gConfigVars) var d = newDocumentor(filen, options.gConfigVars)
var rst = parseRst(readFile(filen), filen, 0, 1, d.hasToc, var rst = parseRst(readFile(filen), filen, 0, 1, d.hasToc,
@ -439,14 +439,14 @@ proc CommandRstAux(filename, outExt: string) =
writeOutput(d, filename, outExt) writeOutput(d, filename, outExt)
generateIndex(d) generateIndex(d)
proc CommandRst2Html*() = proc commandRst2Html*() =
CommandRstAux(gProjectFull, HtmlExt) commandRstAux(gProjectFull, HtmlExt)
proc CommandRst2TeX*() = proc commandRst2TeX*() =
splitter = "\\-" splitter = "\\-"
CommandRstAux(gProjectFull, TexExt) commandRstAux(gProjectFull, TexExt)
proc CommandJSON*() = proc commandJSON*() =
var ast = parseFile(gProjectMainIdx) var ast = parseFile(gProjectMainIdx)
if ast == nil: return if ast == nil: return
var d = newDocumentor(gProjectFull, options.gConfigVars) var d = newDocumentor(gProjectFull, options.gConfigVars)
@ -460,7 +460,7 @@ proc CommandJSON*() =
echo getOutFile(gProjectFull, JsonExt) echo getOutFile(gProjectFull, JsonExt)
writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false) writeRope(content, getOutFile(gProjectFull, JsonExt), useWarning = false)
proc CommandBuildIndex*() = proc commandBuildIndex*() =
var content = mergeIndexes(gProjectFull).toRope var content = mergeIndexes(gProjectFull).toRope
let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", let code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title",

View file

@ -324,7 +324,7 @@ var
compileOptions: string = "" compileOptions: string = ""
ccompilerpath: string = "" ccompilerpath: string = ""
proc NameToCC*(name: string): TSystemCC = proc nameToCC*(name: string): TSystemCC =
for i in countup(succ(ccNone), high(TSystemCC)): for i in countup(succ(ccNone), high(TSystemCC)):
if cmpIgnoreStyle(name, CC[i].name) == 0: if cmpIgnoreStyle(name, CC[i].name) == 0:
return i return i
@ -405,7 +405,7 @@ proc execExternalProgram*(cmd: string) =
proc generateScript(projectFile: string, script: PRope) = proc generateScript(projectFile: string, script: PRope) =
let (dir, name, ext) = splitFile(projectFile) let (dir, name, ext) = splitFile(projectFile)
WriteRope(script, dir / addFileExt("compile_" & name, writeRope(script, dir / addFileExt("compile_" & name,
platform.os[targetOS].scriptExt)) platform.os[targetOS].scriptExt))
proc getOptSpeed(c: TSystemCC): string = proc getOptSpeed(c: TSystemCC): string =
@ -439,7 +439,7 @@ var fileCounter: int
proc add(s: var string, many: openarray[string]) = proc add(s: var string, many: openarray[string]) =
s.add many.join s.add many.join
proc CFileSpecificOptions(cfilename: string): string = proc cFileSpecificOptions(cfilename: string): string =
result = compileOptions result = compileOptions
var trunk = splitFile(cfilename).name var trunk = splitFile(cfilename).name
if optCDebug in gGlobalOptions: if optCDebug in gGlobalOptions:
@ -541,7 +541,7 @@ proc addExternalFileToCompile*(filename: string) =
if optForceFullMake in gGlobalOptions or externalFileChanged(filename): if optForceFullMake in gGlobalOptions or externalFileChanged(filename):
appendStr(externalToCompile, filename) appendStr(externalToCompile, filename)
proc CompileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq, proc compileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
isExternal: bool) = isExternal: bool) =
var it = PStrEntry(list.head) var it = PStrEntry(list.head)
while it != nil: while it != nil:
@ -554,7 +554,7 @@ proc CompileCFile(list: TLinkedList, script: var PRope, cmds: var TStringSeq,
app(script, tnl) app(script, tnl)
it = PStrEntry(it.next) it = PStrEntry(it.next)
proc CallCCompiler*(projectfile: string) = proc callCCompiler*(projectfile: string) =
var var
linkCmd, buildgui, builddll: string linkCmd, buildgui, builddll: string
if gGlobalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}: if gGlobalOptions * {optCompileOnly, optGenScript} == {optCompileOnly}:
@ -564,8 +564,8 @@ proc CallCCompiler*(projectfile: string) =
var c = ccompiler var c = ccompiler
var script: PRope = nil var script: PRope = nil
var cmds: TStringSeq = @[] var cmds: TStringSeq = @[]
CompileCFile(toCompile, script, cmds, false) compileCFile(toCompile, script, cmds, false)
CompileCFile(externalToCompile, script, cmds, true) compileCFile(externalToCompile, script, cmds, true)
if optCompileOnly notin gGlobalOptions: if optCompileOnly notin gGlobalOptions:
if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors() if gNumberOfProcessors == 0: gNumberOfProcessors = countProcessors()
var res = 0 var res = 0
@ -640,7 +640,7 @@ proc CallCCompiler*(projectfile: string) =
proc genMappingFiles(list: TLinkedList): PRope = proc genMappingFiles(list: TLinkedList): PRope =
var it = PStrEntry(list.head) var it = PStrEntry(list.head)
while it != nil: while it != nil:
appf(result, "--file:r\"$1\"$N", [toRope(AddFileExt(it.data, cExt))]) appf(result, "--file:r\"$1\"$N", [toRope(addFileExt(it.data, cExt))])
it = PStrEntry(it.next) it = PStrEntry(it.next)
proc writeMapping*(gSymbolMapping: PRope) = proc writeMapping*(gSymbolMapping: PRope) =
@ -658,5 +658,5 @@ proc writeMapping*(gSymbolMapping: PRope) =
app(code, strutils.escape(libpath)) app(code, strutils.escape(libpath))
appf(code, "\n[Symbols]$n$1", [gSymbolMapping]) appf(code, "\n[Symbols]$n$1", [gSymbolMapping])
WriteRope(code, joinPath(gProjectPath, "mapping.txt")) writeRope(code, joinPath(gProjectPath, "mapping.txt"))

View file

@ -102,7 +102,7 @@ proc getIdent*(identifier: string): PIdent =
proc getIdent*(identifier: string, h: THash): PIdent = proc getIdent*(identifier: string, h: THash): PIdent =
result = getIdent(cstring(identifier), len(identifier), h) 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 result = id.id == getIdent(name).id
var idAnon* = getIdent":anonymous" var idAnon* = getIdent":anonymous"

View file

@ -23,8 +23,8 @@ when debugIds:
proc registerID*(id: PIdObj) = proc registerID*(id: PIdObj) =
when debugIDs: when debugIDs:
if id.id == -1 or ContainsOrIncl(usedIds, id.id): if id.id == -1 or containsOrIncl(usedIds, id.id):
InternalError("ID already used: " & $id.id) internalError("ID already used: " & $id.id)
proc getID*(): int {.inline.} = proc getID*(): int {.inline.} =
result = gFrontEndId result = gFrontEndId
@ -37,7 +37,7 @@ proc backendId*(): int {.inline.} =
proc setId*(id: int) {.inline.} = proc setId*(id: int) {.inline.} =
gFrontEndId = max(gFrontEndId, id + 1) gFrontEndId = max(gFrontEndId, id + 1)
proc IDsynchronizationPoint*(idRange: int) = proc idSynchronizationPoint*(idRange: int) =
gFrontEndId = (gFrontEndId div IdRange + 1) * IdRange + 1 gFrontEndId = (gFrontEndId div IdRange + 1) * IdRange + 1
proc toGid(f: string): string = proc toGid(f: string): string =

View file

@ -132,7 +132,7 @@ proc getLineInfo*(L: TLexer, tok: TToken): TLineInfo {.inline.} =
newLineInfo(L.fileIdx, tok.line, tok.col) newLineInfo(L.fileIdx, tok.line, tok.col)
proc closeLexer*(lex: var TLexer) proc closeLexer*(lex: var TLexer)
proc PrintTok*(tok: TToken) proc printTok*(tok: TToken)
proc tokToStr*(tok: TToken): string proc tokToStr*(tok: TToken): string
proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) = proc openLexer*(lex: var TLexer, filename: string, inputstream: PLLStream) =
@ -172,7 +172,7 @@ proc prettyTok*(tok: TToken): string =
if IsKeyword(tok.tokType): result = "keyword " & tok.ident.s if IsKeyword(tok.tokType): result = "keyword " & tok.ident.s
else: result = tokToStr(tok) else: result = tokToStr(tok)
proc PrintTok*(tok: TToken) = proc printTok*(tok: TToken) =
write(stdout, TokTypeToStr[tok.tokType]) write(stdout, TokTypeToStr[tok.tokType])
write(stdout, " ") write(stdout, " ")
writeln(stdout, tokToStr(tok)) writeln(stdout, tokToStr(tok))
@ -246,7 +246,7 @@ proc isFloatLiteral(s: string): bool =
return true return true
result = false result = false
proc GetNumber(L: var TLexer): TToken = proc getNumber(L: var TLexer): TToken =
var var
pos, endpos: int pos, endpos: int
xi: biggestInt xi: biggestInt
@ -499,7 +499,7 @@ proc newString(s: cstring, len: int): string =
for i in 0 .. <len: for i in 0 .. <len:
result[i] = s[i] result[i] = s[i]
proc HandleCRLF(L: var TLexer, pos: int): int = proc handleCRLF(L: var TLexer, pos: int): int =
template registerLine = template registerLine =
let col = L.getColNumber(pos) let col = L.getColNumber(pos)

View file

@ -24,12 +24,12 @@ type
TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool {.nimcall.} TCompareProc* = proc (entry: PListEntry, closure: Pointer): bool {.nimcall.}
proc InitLinkedList*(list: var TLinkedList) = proc initLinkedList*(list: var TLinkedList) =
list.Counter = 0 list.Counter = 0
list.head = nil list.head = nil
list.tail = nil list.tail = nil
proc Append*(list: var TLinkedList, entry: PListEntry) = proc append*(list: var TLinkedList, entry: PListEntry) =
Inc(list.counter) Inc(list.counter)
entry.next = nil entry.next = nil
entry.prev = list.tail entry.prev = list.tail
@ -39,7 +39,7 @@ proc Append*(list: var TLinkedList, entry: PListEntry) =
list.tail = entry list.tail = entry
if list.head == nil: list.head = 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 var it = list.head
while it != nil: while it != nil:
if PStrEntry(it).data == data: if PStrEntry(it).data == data:
@ -50,14 +50,14 @@ proc newStrEntry(data: string): PStrEntry =
new(result) new(result)
result.data = data result.data = data
proc AppendStr*(list: var TLinkedList, data: string) = proc appendStr*(list: var TLinkedList, data: string) =
append(list, newStrEntry(data)) 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 if Contains(list, data): return true
AppendStr(list, data) # else: add to list AppendStr(list, data) # else: add to list
proc Prepend*(list: var TLinkedList, entry: PListEntry) = proc prepend*(list: var TLinkedList, entry: PListEntry) =
Inc(list.counter) Inc(list.counter)
entry.prev = nil entry.prev = nil
entry.next = list.head entry.next = list.head
@ -67,10 +67,10 @@ proc Prepend*(list: var TLinkedList, entry: PListEntry) =
list.head = entry list.head = entry
if list.tail == nil: list.tail = 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)) prepend(list, newStrEntry(data))
proc InsertBefore*(list: var TLinkedList, pos, entry: PListEntry) = proc insertBefore*(list: var TLinkedList, pos, entry: PListEntry) =
assert(pos != nil) assert(pos != nil)
if pos == list.head: if pos == list.head:
prepend(list, entry) prepend(list, entry)
@ -81,7 +81,7 @@ proc InsertBefore*(list: var TLinkedList, pos, entry: PListEntry) =
if pos.prev != nil: pos.prev.next = entry if pos.prev != nil: pos.prev.next = entry
pos.prev = entry pos.prev = entry
proc Remove*(list: var TLinkedList, entry: PListEntry) = proc remove*(list: var TLinkedList, entry: PListEntry) =
Dec(list.counter) Dec(list.counter)
if entry == list.tail: if entry == list.tail:
list.tail = entry.prev list.tail = entry.prev
@ -103,14 +103,14 @@ proc bringToFront*(list: var TLinkedList, entry: PListEntry) =
entry.next = list.head entry.next = list.head
list.head = entry list.head = entry
proc ExcludeStr*(list: var TLinkedList, data: string) = proc excludeStr*(list: var TLinkedList, data: string) =
var it = list.head var it = list.head
while it != nil: while it != nil:
let nxt = it.next let nxt = it.next
if PStrEntry(it).data == data: remove(list, it) if PStrEntry(it).data == data: remove(list, it)
it = nxt it = nxt
proc Find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry = proc find*(list: TLinkedList, fn: TCompareProc, closure: Pointer): PListEntry =
result = list.head result = list.head
while result != nil: while result != nil:
if fn(result, closure): return if fn(result, closure): return

View file

@ -30,56 +30,56 @@ type
PLLStream* = ref TLLStream PLLStream* = ref TLLStream
proc LLStreamOpen*(data: string): PLLStream proc llStreamOpen*(data: string): PLLStream
proc LLStreamOpen*(f: var tfile): PLLStream proc llStreamOpen*(f: var tfile): PLLStream
proc LLStreamOpen*(filename: string, mode: TFileMode): PLLStream proc llStreamOpen*(filename: string, mode: TFileMode): PLLStream
proc LLStreamOpen*(): PLLStream proc llStreamOpen*(): PLLStream
proc LLStreamOpenStdIn*(): PLLStream proc llStreamOpenStdIn*(): PLLStream
proc LLStreamClose*(s: PLLStream) proc llStreamClose*(s: PLLStream)
proc LLStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int proc llStreamRead*(s: PLLStream, buf: pointer, bufLen: int): int
proc LLStreamReadLine*(s: PLLStream, line: var string): bool proc llStreamReadLine*(s: PLLStream, line: var string): bool
proc LLStreamReadAll*(s: PLLStream): string proc llStreamReadAll*(s: PLLStream): string
proc LLStreamWrite*(s: PLLStream, data: string) proc llStreamWrite*(s: PLLStream, data: string)
proc LLStreamWrite*(s: PLLStream, data: Char) proc llStreamWrite*(s: PLLStream, data: Char)
proc LLStreamWrite*(s: PLLStream, buf: pointer, buflen: int) proc llStreamWrite*(s: PLLStream, buf: pointer, buflen: int)
proc LLStreamWriteln*(s: PLLStream, data: string) proc llStreamWriteln*(s: PLLStream, data: string)
# implementation # implementation
proc LLStreamOpen(data: string): PLLStream = proc llStreamOpen(data: string): PLLStream =
new(result) new(result)
result.s = data result.s = data
result.kind = llsString result.kind = llsString
proc LLStreamOpen(f: var tfile): PLLStream = proc llStreamOpen(f: var tfile): PLLStream =
new(result) new(result)
result.f = f result.f = f
result.kind = llsFile result.kind = llsFile
proc LLStreamOpen(filename: string, mode: TFileMode): PLLStream = proc llStreamOpen(filename: string, mode: TFileMode): PLLStream =
new(result) new(result)
result.kind = llsFile result.kind = llsFile
if not open(result.f, filename, mode): result = nil if not open(result.f, filename, mode): result = nil
proc LLStreamOpen(): PLLStream = proc llStreamOpen(): PLLStream =
new(result) new(result)
result.kind = llsNone result.kind = llsNone
proc LLStreamOpenStdIn(): PLLStream = proc llStreamOpenStdIn(): PLLStream =
new(result) new(result)
result.kind = llsStdIn result.kind = llsStdIn
result.s = "" result.s = ""
result.lineOffset = -1 result.lineOffset = -1
proc LLStreamClose(s: PLLStream) = proc llStreamClose(s: PLLStream) =
case s.kind case s.kind
of llsNone, llsString, llsStdIn: of llsNone, llsString, llsStdIn:
nil discard
of llsFile: of llsFile:
close(s.f) close(s.f)
when not defined(ReadLineFromStdin): when not defined(readLineFromStdin):
# fallback implementation: # fallback implementation:
proc ReadLineFromStdin(prompt: string, line: var string): bool = proc readLineFromStdin(prompt: string, line: var string): bool =
stdout.write(prompt) stdout.write(prompt)
result = readLine(stdin, line) result = readLine(stdin, line)
@ -111,7 +111,7 @@ proc countTriples(s: string): int =
inc i, 2 inc i, 2
inc i inc i
proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int = proc llReadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
s.s = "" s.s = ""
s.rd = 0 s.rd = 0
var line = newStringOfCap(120) var line = newStringOfCap(120)
@ -127,7 +127,7 @@ proc LLreadFromStdin(s: PLLStream, buf: pointer, bufLen: int): int =
copyMem(buf, addr(s.s[s.rd]), result) copyMem(buf, addr(s.s[s.rd]), result)
inc(s.rd, result) inc(s.rd, result)
proc LLStreamRead(s: PLLStream, buf: pointer, bufLen: int): int = proc llStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
case s.kind case s.kind
of llsNone: of llsNone:
result = 0 result = 0
@ -141,7 +141,7 @@ proc LLStreamRead(s: PLLStream, buf: pointer, bufLen: int): int =
of llsStdIn: of llsStdIn:
result = LLreadFromStdin(s, buf, bufLen) result = LLreadFromStdin(s, buf, bufLen)
proc LLStreamReadLine(s: PLLStream, line: var string): bool = proc llStreamReadLine(s: PLLStream, line: var string): bool =
setLen(line, 0) setLen(line, 0)
case s.kind case s.kind
of llsNone: of llsNone:
@ -165,25 +165,25 @@ proc LLStreamReadLine(s: PLLStream, line: var string): bool =
of llsStdIn: of llsStdIn:
result = readLine(stdin, line) result = readLine(stdin, line)
proc LLStreamWrite(s: PLLStream, data: string) = proc llStreamWrite(s: PLLStream, data: string) =
case s.kind case s.kind
of llsNone, llsStdIn: of llsNone, llsStdIn:
nil discard
of llsString: of llsString:
add(s.s, data) add(s.s, data)
inc(s.wr, len(data)) inc(s.wr, len(data))
of llsFile: of llsFile:
write(s.f, data) write(s.f, data)
proc LLStreamWriteln(s: PLLStream, data: string) = proc llStreamWriteln(s: PLLStream, data: string) =
LLStreamWrite(s, data) llStreamWrite(s, data)
LLStreamWrite(s, "\n") llStreamWrite(s, "\n")
proc LLStreamWrite(s: PLLStream, data: Char) = proc llStreamWrite(s: PLLStream, data: Char) =
var c: char var c: char
case s.kind case s.kind
of llsNone, llsStdIn: of llsNone, llsStdIn:
nil discard
of llsString: of llsString:
add(s.s, data) add(s.s, data)
inc(s.wr) inc(s.wr)
@ -191,10 +191,10 @@ proc LLStreamWrite(s: PLLStream, data: Char) =
c = data c = data
discard writeBuffer(s.f, addr(c), sizeof(c)) discard writeBuffer(s.f, addr(c), sizeof(c))
proc LLStreamWrite(s: PLLStream, buf: pointer, buflen: int) = proc llStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
case s.kind case s.kind
of llsNone, llsStdIn: of llsNone, llsStdIn:
nil discard
of llsString: of llsString:
if bufLen > 0: if bufLen > 0:
setlen(s.s, len(s.s) + bufLen) setlen(s.s, len(s.s) + bufLen)
@ -203,10 +203,9 @@ proc LLStreamWrite(s: PLLStream, buf: pointer, buflen: int) =
of llsFile: of llsFile:
discard writeBuffer(s.f, buf, bufLen) discard writeBuffer(s.f, buf, bufLen)
proc LLStreamReadAll(s: PLLStream): string = proc llStreamReadAll(s: PLLStream): string =
const const
bufSize = 2048 bufSize = 2048
var bytes, i: int
case s.kind case s.kind
of llsNone, llsStdIn: of llsNone, llsStdIn:
result = "" result = ""
@ -216,8 +215,8 @@ proc LLStreamReadAll(s: PLLStream): string =
s.rd = len(s.s) s.rd = len(s.s)
of llsFile: of llsFile:
result = newString(bufSize) result = newString(bufSize)
bytes = readBuffer(s.f, addr(result[0]), bufSize) var bytes = readBuffer(s.f, addr(result[0]), bufSize)
i = bytes var i = bytes
while bytes == bufSize: while bytes == bufSize:
setlen(result, i + bufSize) setlen(result, i + bufSize)
bytes = readBuffer(s.f, addr(result[i + 0]), bufSize) bytes = readBuffer(s.f, addr(result[i + 0]), bufSize)

View file

@ -21,7 +21,7 @@ proc considerAcc*(n: PNode): PIdent =
of nkSym: result = n.sym.name of nkSym: result = n.sym.name
of nkAccQuoted: of nkAccQuoted:
case n.len case n.len
of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n)) of 0: globalError(n.info, errIdentifierExpected, renderTree(n))
of 1: result = considerAcc(n.sons[0]) of 1: result = considerAcc(n.sons[0])
else: else:
var id = "" var id = ""
@ -30,16 +30,16 @@ proc considerAcc*(n: PNode): PIdent =
case x.kind case x.kind
of nkIdent: id.add(x.ident.s) of nkIdent: id.add(x.ident.s)
of nkSym: id.add(x.sym.name.s) of nkSym: id.add(x.sym.name.s)
else: GlobalError(n.info, errIdentifierExpected, renderTree(n)) else: globalError(n.info, errIdentifierExpected, renderTree(n))
result = getIdent(id) result = getIdent(id)
else: else:
GlobalError(n.info, errIdentifierExpected, renderTree(n)) globalError(n.info, errIdentifierExpected, renderTree(n))
template addSym*(scope: PScope, s: PSym) = template addSym*(scope: PScope, s: PSym) =
StrTableAdd(scope.symbols, s) strTableAdd(scope.symbols, s)
proc addUniqueSym*(scope: PScope, s: PSym): TResult = proc addUniqueSym*(scope: PScope, s: PSym): TResult =
if StrTableIncl(scope.symbols, s): if strTableIncl(scope.symbols, s):
result = Failure result = Failure
else: else:
result = Success result = Success
@ -64,17 +64,17 @@ iterator walkScopes*(scope: PScope): PScope =
current = current.parent current = current.parent
proc localSearchInScope*(c: PContext, s: PIdent): PSym = proc localSearchInScope*(c: PContext, s: PIdent): PSym =
result = StrTableGet(c.currentScope.symbols, s) result = strTableGet(c.currentScope.symbols, s)
proc searchInScopes*(c: PContext, s: PIdent): PSym = proc searchInScopes*(c: PContext, s: PIdent): PSym =
for scope in walkScopes(c.currentScope): for scope in walkScopes(c.currentScope):
result = StrTableGet(scope.symbols, s) result = strTableGet(scope.symbols, s)
if result != nil: return if result != nil: return
result = nil result = nil
proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym = proc searchInScopes*(c: PContext, s: PIdent, filter: TSymKinds): PSym =
for scope in walkScopes(c.currentScope): for scope in walkScopes(c.currentScope):
result = StrTableGet(scope.symbols, s) result = strTableGet(scope.symbols, s)
if result != nil and result.kind in filter: return if result != nil and result.kind in filter: return
result = nil result = nil
@ -114,22 +114,22 @@ proc getSymRepr*(s: PSym): string =
proc ensureNoMissingOrUnusedSymbols(scope: PScope) = proc ensureNoMissingOrUnusedSymbols(scope: PScope) =
# check if all symbols have been used and defined: # check if all symbols have been used and defined:
var it: TTabIter var it: TTabIter
var s = InitTabIter(it, scope.symbols) var s = initTabIter(it, scope.symbols)
var missingImpls = 0 var missingImpls = 0
while s != nil: while s != nil:
if sfForward in s.flags: if sfForward in s.flags:
# too many 'implementation of X' errors are annoying # too many 'implementation of X' errors are annoying
# and slow 'suggest' down: # and slow 'suggest' down:
if missingImpls == 0: if missingImpls == 0:
LocalError(s.info, errImplOfXexpected, getSymRepr(s)) localError(s.info, errImplOfXexpected, getSymRepr(s))
inc missingImpls inc missingImpls
elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options: elif {sfUsed, sfExported} * s.flags == {} and optHints in s.options:
# BUGFIX: check options in s! # BUGFIX: check options in s!
if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}: if s.kind notin {skForVar, skParam, skMethod, skUnknown, skGenericParam}:
Message(s.info, hintXDeclaredButNotUsed, getSymRepr(s)) message(s.info, hintXDeclaredButNotUsed, getSymRepr(s))
s = NextIter(it, scope.symbols) s = nextIter(it, scope.symbols)
proc WrongRedefinition*(info: TLineInfo, s: string) = proc wrongRedefinition*(info: TLineInfo, s: string) =
if gCmd != cmdInteractive: if gCmd != cmdInteractive:
localError(info, errAttemptToRedefine, s) localError(info, errAttemptToRedefine, s)
@ -144,7 +144,7 @@ proc addDeclAt*(scope: PScope, sym: PSym) =
if scope.addUniqueSym(sym) == Failure: if scope.addUniqueSym(sym) == Failure:
WrongRedefinition(sym.info, sym.Name.s) WrongRedefinition(sym.info, sym.Name.s)
proc AddInterfaceDeclAux(c: PContext, sym: PSym) = proc addInterfaceDeclAux(c: PContext, sym: PSym) =
if sfExported in sym.flags: if sfExported in sym.flags:
# add to interface: # add to interface:
if c.module != nil: StrTableAdd(c.module.tab, sym) if c.module != nil: StrTableAdd(c.module.tab, sym)
@ -152,27 +152,27 @@ proc AddInterfaceDeclAux(c: PContext, sym: PSym) =
proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) = proc addInterfaceDeclAt*(c: PContext, scope: PScope, sym: PSym) =
addDeclAt(scope, sym) addDeclAt(scope, sym)
AddInterfaceDeclAux(c, sym) addInterfaceDeclAux(c, sym)
proc addOverloadableSymAt*(scope: PScope, fn: PSym) = proc addOverloadableSymAt*(scope: PScope, fn: PSym) =
if fn.kind notin OverloadableSyms: if fn.kind notin OverloadableSyms:
InternalError(fn.info, "addOverloadableSymAt") internalError(fn.info, "addOverloadableSymAt")
return return
var check = StrTableGet(scope.symbols, fn.name) var check = StrTableGet(scope.symbols, fn.name)
if check != nil and check.Kind notin OverloadableSyms: if check != nil and check.Kind notin OverloadableSyms:
WrongRedefinition(fn.info, fn.Name.s) wrongRedefinition(fn.info, fn.Name.s)
else: else:
scope.addSym(fn) scope.addSym(fn)
proc addInterfaceDecl*(c: PContext, sym: PSym) = proc addInterfaceDecl*(c: PContext, sym: PSym) =
# it adds the symbol to the interface if appropriate # it adds the symbol to the interface if appropriate
addDecl(c, sym) addDecl(c, sym)
AddInterfaceDeclAux(c, sym) addInterfaceDeclAux(c, sym)
proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) = proc addInterfaceOverloadableSymAt*(c: PContext, scope: PScope, sym: PSym) =
# it adds the symbol to the interface if appropriate # it adds the symbol to the interface if appropriate
addOverloadableSymAt(scope, sym) addOverloadableSymAt(scope, sym)
AddInterfaceDeclAux(c, sym) addInterfaceDeclAux(c, sym)
proc lookUp*(c: PContext, n: PNode): PSym = proc lookUp*(c: PContext, n: PNode): PSym =
# Looks up a symbol. Generates an error in case of nil. # Looks up a symbol. Generates an error in case of nil.
@ -180,7 +180,7 @@ proc lookUp*(c: PContext, n: PNode): PSym =
of nkIdent: of nkIdent:
result = searchInScopes(c, n.ident) result = searchInScopes(c, n.ident)
if result == nil: if result == nil:
LocalError(n.info, errUndeclaredIdentifier, n.ident.s) localError(n.info, errUndeclaredIdentifier, n.ident.s)
result = errorSym(c, n) result = errorSym(c, n)
of nkSym: of nkSym:
result = n.sym result = n.sym
@ -188,34 +188,34 @@ proc lookUp*(c: PContext, n: PNode): PSym =
var ident = considerAcc(n) var ident = considerAcc(n)
result = searchInScopes(c, ident) result = searchInScopes(c, ident)
if result == nil: if result == nil:
LocalError(n.info, errUndeclaredIdentifier, ident.s) localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n) result = errorSym(c, n)
else: else:
InternalError(n.info, "lookUp") internalError(n.info, "lookUp")
return return
if Contains(c.AmbiguousSymbols, result.id): if contains(c.AmbiguousSymbols, result.id):
LocalError(n.info, errUseQualifier, result.name.s) localError(n.info, errUseQualifier, result.name.s)
if result.kind == skStub: loadStub(result) if result.kind == skStub: loadStub(result)
type type
TLookupFlag* = enum TLookupFlag* = enum
checkAmbiguity, checkUndeclared checkAmbiguity, checkUndeclared
proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym = proc qualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerAcc(n) var ident = considerAcc(n)
result = searchInScopes(c, ident) result = searchInScopes(c, ident)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
LocalError(n.info, errUndeclaredIdentifier, ident.s) localError(n.info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n) result = errorSym(c, n)
elif checkAmbiguity in flags and result != nil and elif checkAmbiguity in flags and result != nil and
Contains(c.AmbiguousSymbols, result.id): contains(c.AmbiguousSymbols, result.id):
LocalError(n.info, errUseQualifier, ident.s) localError(n.info, errUseQualifier, ident.s)
of nkSym: of nkSym:
result = n.sym result = n.sym
if checkAmbiguity in flags and Contains(c.AmbiguousSymbols, result.id): if checkAmbiguity in flags and contains(c.AmbiguousSymbols, result.id):
LocalError(n.info, errUseQualifier, n.sym.name.s) localError(n.info, errUseQualifier, n.sym.name.s)
of nkDotExpr: of nkDotExpr:
result = nil result = nil
var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared}) var m = qualifiedLookUp(c, n.sons[0], flags*{checkUndeclared})
@ -227,31 +227,31 @@ proc QualifiedLookUp*(c: PContext, n: PNode, flags = {checkUndeclared}): PSym =
ident = considerAcc(n.sons[1]) ident = considerAcc(n.sons[1])
if ident != nil: if ident != nil:
if m == c.module: if m == c.module:
result = StrTableGet(c.topLevelScope.symbols, ident) result = strTableGet(c.topLevelScope.symbols, ident)
else: else:
result = StrTableGet(m.tab, ident) result = strTableGet(m.tab, ident)
if result == nil and checkUndeclared in flags: if result == nil and checkUndeclared in flags:
LocalError(n.sons[1].info, errUndeclaredIdentifier, ident.s) localError(n.sons[1].info, errUndeclaredIdentifier, ident.s)
result = errorSym(c, n.sons[1]) result = errorSym(c, n.sons[1])
elif n.sons[1].kind == nkSym: elif n.sons[1].kind == nkSym:
result = n.sons[1].sym result = n.sons[1].sym
elif checkUndeclared in flags and elif checkUndeclared in flags and
n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}: n.sons[1].kind notin {nkOpenSymChoice, nkClosedSymChoice}:
LocalError(n.sons[1].info, errIdentifierExpected, localError(n.sons[1].info, errIdentifierExpected,
renderTree(n.sons[1])) renderTree(n.sons[1]))
result = errorSym(c, n.sons[1]) result = errorSym(c, n.sons[1])
else: else:
result = nil result = nil
if result != nil and result.kind == skStub: loadStub(result) if result != nil and result.kind == skStub: loadStub(result)
proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym = proc initOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
case n.kind case n.kind
of nkIdent, nkAccQuoted: of nkIdent, nkAccQuoted:
var ident = considerAcc(n) var ident = considerAcc(n)
o.scope = c.currentScope o.scope = c.currentScope
o.mode = oimNoQualifier o.mode = oimNoQualifier
while true: while true:
result = InitIdentIter(o.it, o.scope.symbols, ident) result = initIdentIter(o.it, o.scope.symbols, ident)
if result != nil: if result != nil:
break break
else: else:
@ -272,12 +272,12 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
if ident != nil: if ident != nil:
if o.m == c.module: if o.m == c.module:
# a module may access its private members: # a module may access its private members:
result = InitIdentIter(o.it, c.topLevelScope.symbols, ident) result = initIdentIter(o.it, c.topLevelScope.symbols, ident)
o.mode = oimSelfModule o.mode = oimSelfModule
else: else:
result = InitIdentIter(o.it, o.m.tab, ident) result = InitIdentIter(o.it, o.m.tab, ident)
else: else:
LocalError(n.sons[1].info, errIdentifierExpected, localError(n.sons[1].info, errIdentifierExpected,
renderTree(n.sons[1])) renderTree(n.sons[1]))
result = errorSym(c, n.sons[1]) result = errorSym(c, n.sons[1])
of nkClosedSymChoice, nkOpenSymChoice: of nkClosedSymChoice, nkOpenSymChoice:
@ -285,7 +285,7 @@ proc InitOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
result = n.sons[0].sym result = n.sons[0].sym
o.symChoiceIndex = 1 o.symChoiceIndex = 1
o.inSymChoice = initIntSet() o.inSymChoice = initIntSet()
Incl(o.inSymChoice, result.id) incl(o.inSymChoice, result.id)
else: nil else: nil
if result != nil and result.kind == skStub: loadStub(result) if result != nil and result.kind == skStub: loadStub(result)
@ -306,7 +306,7 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = InitIdentIter(o.it, o.scope.symbols, o.it.name) result = initIdentIter(o.it, o.scope.symbols, o.it.name)
# BUGFIX: o.it.name <-> n.ident # BUGFIX: o.it.name <-> n.ident
else: else:
result = nil result = nil
@ -323,19 +323,19 @@ proc nextOverloadIter*(o: var TOverloadIter, c: PContext, n: PNode): PSym =
# try 'local' symbols too for Koenig's lookup: # try 'local' symbols too for Koenig's lookup:
o.mode = oimSymChoiceLocalLookup o.mode = oimSymChoiceLocalLookup
o.scope = c.currentScope o.scope = c.currentScope
result = FirstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = FirstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
of oimSymChoiceLocalLookup: of oimSymChoiceLocalLookup:
result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice) result = nextIdentExcluding(o.it, o.scope.symbols, o.inSymChoice)
while result == nil: while result == nil:
o.scope = o.scope.parent o.scope = o.scope.parent
if o.scope == nil: break if o.scope == nil: break
result = FirstIdentExcluding(o.it, o.scope.symbols, result = firstIdentExcluding(o.it, o.scope.symbols,
n.sons[0].sym.name, o.inSymChoice) n.sons[0].sym.name, o.inSymChoice)
if result != nil and result.kind == skStub: loadStub(result) if result != nil and result.kind == skStub: loadStub(result)

View file

@ -12,14 +12,14 @@
import import
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread
var SystemModule*: PSym var systemModule*: PSym
proc registerSysType*(t: PType) proc registerSysType*(t: PType)
# magic symbols in the system module: # magic symbols in the system module:
proc getSysType*(kind: TTypeKind): PType proc getSysType*(kind: TTypeKind): PType
proc getCompilerProc*(name: string): PSym proc getCompilerProc*(name: string): PSym
proc registerCompilerProc*(s: PSym) proc registerCompilerProc*(s: PSym)
proc FinishSystem*(tab: TStrTable) proc finishSystem*(tab: TStrTable)
proc getSysSym*(name: string): PSym proc getSysSym*(name: string): PSym
# implementation # implementation
@ -126,7 +126,7 @@ proc skipIntLit*(t: PType): PType {.inline.} =
return getSysType(t.kind) return getSysType(t.kind)
result = t result = t
proc AddSonSkipIntLit*(father, son: PType) = proc addSonSkipIntLit*(father, son: PType) =
if isNil(father.sons): father.sons = @[] if isNil(father.sons): father.sons = @[]
let s = son.skipIntLit let s = son.skipIntLit
add(father.sons, s) add(father.sons, s)
@ -158,13 +158,13 @@ proc setIntLitType*(result: PNode) =
result.typ = getSysType(tyInt32) result.typ = getSysType(tyInt32)
else: else:
result.typ = getSysType(tyInt64) result.typ = getSysType(tyInt64)
else: InternalError(result.info, "invalid int size") else: internalError(result.info, "invalid int size")
proc getCompilerProc(name: string): PSym = proc getCompilerProc(name: string): PSym =
var ident = getIdent(name, hashIgnoreStyle(name)) var ident = getIdent(name, hashIgnoreStyle(name))
result = StrTableGet(compilerprocs, ident) result = strTableGet(compilerprocs, ident)
if result == nil: if result == nil:
result = StrTableGet(rodCompilerProcs, ident) result = strTableGet(rodCompilerProcs, ident)
if result != nil: if result != nil:
strTableAdd(compilerprocs, result) strTableAdd(compilerprocs, result)
if result.kind == skStub: loadStub(result) if result.kind == skStub: loadStub(result)
@ -172,7 +172,6 @@ proc getCompilerProc(name: string): PSym =
proc registerCompilerProc(s: PSym) = proc registerCompilerProc(s: PSym) =
strTableAdd(compilerprocs, s) strTableAdd(compilerprocs, s)
proc FinishSystem(tab: TStrTable) = nil proc finishSystem(tab: TStrTable) = discard
initStrTable(compilerprocs) initStrTable(compilerprocs)

View file

@ -21,9 +21,9 @@ import
from magicsys import SystemModule, resetSysTypes from magicsys import SystemModule, resetSysTypes
const const
has_LLVM_Backend = false hasLLVM_Backend = false
when has_LLVM_Backend: when hasLLVM_Backend:
import llvmgen import llvmgen
proc rodPass = proc rodPass =
@ -37,7 +37,7 @@ proc semanticPasses =
registerPass verbosePass registerPass verbosePass
registerPass semPass registerPass semPass
proc CommandGenDepend = proc commandGenDepend =
semanticPasses() semanticPasses()
registerPass(genDependPass) registerPass(genDependPass)
registerPass(cleanupPass) registerPass(cleanupPass)
@ -46,13 +46,13 @@ proc CommandGenDepend =
execExternalProgram("dot -Tpng -o" & changeFileExt(gProjectFull, "png") & execExternalProgram("dot -Tpng -o" & changeFileExt(gProjectFull, "png") &
' ' & changeFileExt(gProjectFull, "dot")) ' ' & changeFileExt(gProjectFull, "dot"))
proc CommandCheck = proc commandCheck =
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
semanticPasses() # use an empty backend for semantic checking only semanticPasses() # use an empty backend for semantic checking only
rodPass() rodPass()
compileProject() compileProject()
proc CommandDoc2 = proc commandDoc2 =
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
semanticPasses() semanticPasses()
registerPass(docgen2Pass) registerPass(docgen2Pass)
@ -60,7 +60,7 @@ proc CommandDoc2 =
compileProject() compileProject()
finishDoc2Pass(gProjectName) finishDoc2Pass(gProjectName)
proc CommandCompileToC = proc commandCompileToC =
semanticPasses() semanticPasses()
registerPass(cgenPass) registerPass(cgenPass)
rodPass() rodPass()
@ -111,15 +111,15 @@ proc CommandCompileToC =
ccgutils.resetCaches() ccgutils.resetCaches()
GC_fullCollect() GC_fullCollect()
when has_LLVM_Backend: when hasLLVM_Backend:
proc CommandCompileToLLVM = proc commandCompileToLLVM =
semanticPasses() semanticPasses()
registerPass(llvmgen.llvmgenPass()) registerPass(llvmgen.llvmgenPass())
rodPass() rodPass()
#registerPass(cleanupPass()) #registerPass(cleanupPass())
compileProject() compileProject()
proc CommandCompileToJS = proc commandCompileToJS =
#incl(gGlobalOptions, optSafeCode) #incl(gGlobalOptions, optSafeCode)
setTarget(osJS, cpuJS) setTarget(osJS, cpuJS)
#initDefines() #initDefines()
@ -130,7 +130,7 @@ proc CommandCompileToJS =
registerPass(jsgenPass) registerPass(jsgenPass)
compileProject() compileProject()
proc InteractivePasses = proc interactivePasses =
#incl(gGlobalOptions, optSafeCode) #incl(gGlobalOptions, optSafeCode)
#setTarget(osNimrodVM, cpuNimrodVM) #setTarget(osNimrodVM, cpuNimrodVM)
initDefines() initDefines()
@ -140,7 +140,7 @@ proc InteractivePasses =
registerPass(semPass) registerPass(semPass)
registerPass(evalPass) registerPass(evalPass)
proc CommandInteractive = proc commandInteractive =
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
InteractivePasses() InteractivePasses()
compileSystemModule() compileSystemModule()
@ -163,20 +163,20 @@ proc commandEval(exp: string) =
var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")" var echoExp = "echo \"eval\\t\", " & "repr(" & exp & ")"
evalNim(echoExp.parseString, makeStdinModule()) evalNim(echoExp.parseString, makeStdinModule())
proc CommandPrettyOld = proc commandPrettyOld =
var projectFile = addFileExt(mainCommandArg(), NimExt) var projectFile = addFileExt(mainCommandArg(), NimExt)
var module = parseFile(projectFile.fileInfoIdx) var module = parseFile(projectFile.fileInfoIdx)
if module != nil: if module != nil:
renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt)) renderModule(module, getOutFile(mainCommandArg(), "pretty." & NimExt))
proc CommandPretty = proc commandPretty =
msgs.gErrorMax = high(int) # do not stop after first error msgs.gErrorMax = high(int) # do not stop after first error
semanticPasses() semanticPasses()
registerPass(prettyPass) registerPass(prettyPass)
compileProject() compileProject()
pretty.overwriteFiles() pretty.overwriteFiles()
proc CommandScan = proc commandScan =
var f = addFileExt(mainCommandArg(), nimExt) var f = addFileExt(mainCommandArg(), nimExt)
var stream = LLStreamOpen(f, fmRead) var stream = LLStreamOpen(f, fmRead)
if stream != nil: if stream != nil:
@ -193,7 +193,7 @@ proc CommandScan =
else: else:
rawMessage(errCannotOpenFile, f) rawMessage(errCannotOpenFile, f)
proc CommandSuggest = proc commandSuggest =
if isServing: if isServing:
# XXX: hacky work-around ahead # XXX: hacky work-around ahead
# Currently, it's possible to issue a idetools command, before # Currently, it's possible to issue a idetools command, before
@ -286,7 +286,7 @@ const
SimiluateCaasMemReset = false SimiluateCaasMemReset = false
PrintRopeCacheStats = false PrintRopeCacheStats = false
proc MainCommand* = proc mainCommand* =
when SimiluateCaasMemReset: when SimiluateCaasMemReset:
gGlobalOptions.incl(optCaasEnabled) gGlobalOptions.incl(optCaasEnabled)

View file

@ -184,7 +184,7 @@ proc compileSystemModule* =
SystemFileIdx = fileInfoIdx(options.libpath/"system.nim") SystemFileIdx = fileInfoIdx(options.libpath/"system.nim")
discard CompileModule(SystemFileIdx, {sfSystemModule}) discard CompileModule(SystemFileIdx, {sfSystemModule})
proc CompileProject*(projectFile = gProjectMainIdx) = proc compileProject*(projectFile = gProjectMainIdx) =
let systemFileIdx = fileInfoIdx(options.libpath / "system.nim") let systemFileIdx = fileInfoIdx(options.libpath / "system.nim")
if projectFile == SystemFileIdx: if projectFile == SystemFileIdx:
discard CompileModule(projectFile, {sfMainModule, sfSystemModule}) discard CompileModule(projectFile, {sfMainModule, sfSystemModule})

View file

@ -453,7 +453,7 @@ const
var var
filenameToIndexTbl = initTable[string, int32]() filenameToIndexTbl = initTable[string, int32]()
fileInfos*: seq[TFileInfo] = @[] fileInfos*: seq[TFileInfo] = @[]
SystemFileIdx*: int32 systemFileIdx*: int32
proc toCChar*(c: Char): string = proc toCChar*(c: Char): string =
case c case c
@ -545,7 +545,7 @@ var
when useCaas: when useCaas:
var stdoutSocket*: TSocket var stdoutSocket*: TSocket
proc UnknownLineInfo*(): TLineInfo = proc unknownLineInfo*(): TLineInfo =
result.line = int16(-1) result.line = int16(-1)
result.col = int16(-1) result.col = int16(-1)
result.fileIndex = -1 result.fileIndex = -1
@ -560,7 +560,7 @@ var
proc clearBufferedMsgs* = proc clearBufferedMsgs* =
bufferedMsgs = nil bufferedMsgs = nil
proc SuggestWriteln*(s: string) = proc suggestWriteln*(s: string) =
if eStdOut in errorOutputs: if eStdOut in errorOutputs:
when useCaas: when useCaas:
if isNil(stdoutSocket): Writeln(stdout, s) if isNil(stdoutSocket): Writeln(stdout, s)
@ -573,7 +573,7 @@ proc SuggestWriteln*(s: string) =
if eInMemory in errorOutputs: if eInMemory in errorOutputs:
bufferedMsgs.safeAdd(s) bufferedMsgs.safeAdd(s)
proc SuggestQuit*() = proc suggestQuit*() =
if not isServing: if not isServing:
quit(0) quit(0)
elif isWorkingWithDirtyBuffer: elif isWorkingWithDirtyBuffer:
@ -656,11 +656,11 @@ proc addCheckpoint*(info: TLineInfo) =
proc addCheckpoint*(filename: string, line: int) = proc addCheckpoint*(filename: string, line: int) =
addCheckpoint(newLineInfo(filename, line, - 1)) addCheckpoint(newLineInfo(filename, line, - 1))
proc OutWriteln*(s: string) = proc outWriteln*(s: string) =
## Writes to stdout. Always. ## Writes to stdout. Always.
if eStdOut in errorOutputs: Writeln(stdout, s) if eStdOut in errorOutputs: Writeln(stdout, s)
proc MsgWriteln*(s: string) = proc msgWriteln*(s: string) =
## Writes to stdout. If --stdout option is given, writes to stderr instead. ## Writes to stdout. If --stdout option is given, writes to stderr instead.
if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return if gCmd == cmdIdeTools and optCDebug notin gGlobalOptions: return
@ -675,7 +675,7 @@ proc coordToStr(coord: int): string =
if coord == -1: result = "???" if coord == -1: result = "???"
else: result = $coord else: result = $coord
proc MsgKindToString*(kind: TMsgKind): string = proc msgKindToString*(kind: TMsgKind): string =
# later versions may provide translated error messages # later versions may provide translated error messages
result = msgKindToStr[kind] result = msgKindToStr[kind]
@ -724,7 +724,7 @@ proc writeContext(lastinfo: TLineInfo) =
var info = lastInfo var info = lastInfo
for i in countup(0, len(msgContext) - 1): for i in countup(0, len(msgContext) - 1):
if msgContext[i] != lastInfo and msgContext[i] != info: if msgContext[i] != lastInfo and msgContext[i] != info:
MsgWriteln(posContextFormat % [toMsgFilename(msgContext[i]), msgWriteln(posContextFormat % [toMsgFilename(msgContext[i]),
coordToStr(msgContext[i].line), coordToStr(msgContext[i].line),
coordToStr(msgContext[i].col), coordToStr(msgContext[i].col),
getMessageStr(errInstantiationFrom, "")]) getMessageStr(errInstantiationFrom, "")])
@ -748,7 +748,7 @@ proc rawMessage*(msg: TMsgKind, args: openarray[string]) =
frmt = rawHintFormat frmt = rawHintFormat
inc(gHintCounter) inc(gHintCounter)
let s = `%`(frmt, `%`(msgKindToString(msg), args)) let s = `%`(frmt, `%`(msgKindToString(msg), args))
MsgWriteln(s) msgWriteln(s)
handleError(msg, doAbort, s) handleError(msg, doAbort, s)
proc rawMessage*(msg: TMsgKind, arg: string) = proc rawMessage*(msg: TMsgKind, arg: string) =
@ -756,8 +756,8 @@ proc rawMessage*(msg: TMsgKind, arg: string) =
proc writeSurroundingSrc(info: TLineInfo) = proc writeSurroundingSrc(info: TLineInfo) =
const indent = " " const indent = " "
MsgWriteln(indent & info.sourceLine.ropeToStr) msgWriteln(indent & info.sourceLine.ropeToStr)
MsgWriteln(indent & repeatChar(info.col, ' ') & '^') msgWriteln(indent & repeatChar(info.col, ' ') & '^')
proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string, proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
eh: TErrorHandling) = eh: TErrorHandling) =
@ -783,45 +783,45 @@ proc liMessage(info: TLineInfo, msg: TMsgKind, arg: string,
let s = frmt % [toMsgFilename(info), coordToStr(info.line), let s = frmt % [toMsgFilename(info), coordToStr(info.line),
coordToStr(info.col), getMessageStr(msg, arg)] coordToStr(info.col), getMessageStr(msg, arg)]
if not ignoreMsg: if not ignoreMsg:
MsgWriteln(s) msgWriteln(s)
if optPrintSurroundingSrc and msg in errMin..errMax: if optPrintSurroundingSrc and msg in errMin..errMax:
info.writeSurroundingSrc info.writeSurroundingSrc
handleError(msg, eh, s) handleError(msg, eh, s)
proc Fatal*(info: TLineInfo, msg: TMsgKind, arg = "") = proc fatal*(info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(info, msg, arg, doAbort) liMessage(info, msg, arg, doAbort)
proc GlobalError*(info: TLineInfo, msg: TMsgKind, arg = "") = proc globalError*(info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(info, msg, arg, doRaise) liMessage(info, msg, arg, doRaise)
proc GlobalError*(info: TLineInfo, arg: string) = proc globalError*(info: TLineInfo, arg: string) =
liMessage(info, errGenerated, arg, doRaise) liMessage(info, errGenerated, arg, doRaise)
proc LocalError*(info: TLineInfo, msg: TMsgKind, arg = "") = proc localError*(info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(info, msg, arg, doNothing) liMessage(info, msg, arg, doNothing)
proc LocalError*(info: TLineInfo, arg: string) = proc localError*(info: TLineInfo, arg: string) =
liMessage(info, errGenerated, arg, doNothing) liMessage(info, errGenerated, arg, doNothing)
proc Message*(info: TLineInfo, msg: TMsgKind, arg = "") = proc message*(info: TLineInfo, msg: TMsgKind, arg = "") =
liMessage(info, msg, arg, doNothing) liMessage(info, msg, arg, doNothing)
proc InternalError*(info: TLineInfo, errMsg: string) = proc internalError*(info: TLineInfo, errMsg: string) =
if gCmd == cmdIdeTools: return if gCmd == cmdIdeTools: return
writeContext(info) writeContext(info)
liMessage(info, errInternal, errMsg, doAbort) liMessage(info, errInternal, errMsg, doAbort)
proc InternalError*(errMsg: string) = proc internalError*(errMsg: string) =
if gCmd == cmdIdeTools: return if gCmd == cmdIdeTools: return
writeContext(UnknownLineInfo()) writeContext(UnknownLineInfo())
rawMessage(errInternal, errMsg) rawMessage(errInternal, errMsg)
template AssertNotNil*(e: expr): expr = template assertNotNil*(e: expr): expr =
if e == nil: InternalError($InstantiationInfo()) if e == nil: internalError($instantiationInfo())
e e
template InternalAssert*(e: bool): stmt = template internalAssert*(e: bool): stmt =
if not e: InternalError($InstantiationInfo()) if not e: internalError($instantiationInfo())
proc addSourceLine*(fileIdx: int32, line: string) = proc addSourceLine*(fileIdx: int32, line: string) =
fileInfos[fileIdx].lines.add line.toRope fileInfos[fileIdx].lines.add line.toRope
@ -835,14 +835,14 @@ proc sourceLine*(i: TLineInfo): PRope =
addSourceLine i.fileIndex, line.string addSourceLine i.fileIndex, line.string
except EIO: except EIO:
discard discard
InternalAssert i.fileIndex < fileInfos.len internalAssert i.fileIndex < fileInfos.len
# can happen if the error points to EOF: # can happen if the error points to EOF:
if i.line > fileInfos[i.fileIndex].lines.len: return nil if i.line > fileInfos[i.fileIndex].lines.len: return nil
result = fileInfos[i.fileIndex].lines[i.line-1] result = fileInfos[i.fileIndex].lines[i.line-1]
proc quotedFilename*(i: TLineInfo): PRope = proc quotedFilename*(i: TLineInfo): PRope =
InternalAssert i.fileIndex >= 0 internalAssert i.fileIndex >= 0
result = fileInfos[i.fileIndex].quotedName result = fileInfos[i.fileIndex].quotedName
ropes.ErrorHandler = proc (err: TRopesError, msg: string, useWarning: bool) = ropes.ErrorHandler = proc (err: TRopesError, msg: string, useWarning: bool) =

View file

@ -219,7 +219,7 @@ proc getSystemConfigPath(filename: string): string =
if not existsFile(result): result = joinPath([p, "etc", filename]) if not existsFile(result): result = joinPath([p, "etc", filename])
if not existsFile(result): result = "/etc/" & filename if not existsFile(result): result = "/etc/" & filename
proc LoadConfigs*(cfg: string) = proc loadConfigs*(cfg: string) =
# set default value (can be overwritten): # set default value (can be overwritten):
if libpath == "": if libpath == "":
# choose default libpath: # choose default libpath:

View file

@ -54,11 +54,11 @@ proc openBaseLexer*(L: var TBaseLexer, inputstream: PLLStream,
proc closeBaseLexer*(L: var TBaseLexer) proc closeBaseLexer*(L: var TBaseLexer)
proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string
proc getColNumber*(L: TBaseLexer, pos: int): int proc getColNumber*(L: TBaseLexer, pos: int): int
proc HandleCR*(L: var TBaseLexer, pos: int): int proc handleCR*(L: var TBaseLexer, pos: int): int
# Call this if you scanned over CR in the buffer; it returns the # Call this if you scanned over CR in the buffer; it returns the
# position to continue the scanning from. `pos` must be the position # position to continue the scanning from. `pos` must be the position
# of the CR. # of the CR.
proc HandleLF*(L: var TBaseLexer, pos: int): int proc handleLF*(L: var TBaseLexer, pos: int): int
# Call this if you scanned over LF in the buffer; it returns the the # Call this if you scanned over LF in the buffer; it returns the the
# position to continue the scanning from. `pos` must be the position # position to continue the scanning from. `pos` must be the position
# of the LF. # of the LF.
@ -71,7 +71,7 @@ proc closeBaseLexer(L: var TBaseLexer) =
dealloc(L.buf) dealloc(L.buf)
LLStreamClose(L.stream) LLStreamClose(L.stream)
proc FillBuffer(L: var TBaseLexer) = proc fillBuffer(L: var TBaseLexer) =
var var
charsRead, toCopy, s: int # all are in characters, charsRead, toCopy, s: int # all are in characters,
# not bytes (in case this # not bytes (in case this
@ -126,20 +126,20 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int =
result = 0 result = 0
L.lineStart = result L.lineStart = result
proc HandleCR(L: var TBaseLexer, pos: int): int = proc handleCR(L: var TBaseLexer, pos: int): int =
assert(L.buf[pos] == CR) assert(L.buf[pos] == CR)
inc(L.linenumber) inc(L.linenumber)
result = fillBaseLexer(L, pos) result = fillBaseLexer(L, pos)
if L.buf[result] == LF: if L.buf[result] == LF:
result = fillBaseLexer(L, result) 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) assert(L.buf[pos] == LF)
inc(L.linenumber) inc(L.linenumber)
result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result;
proc skip_UTF_8_BOM(L: var TBaseLexer) = proc skipUTF8BOM(L: var TBaseLexer) =
if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): if L.buf[0] == '\xEF' and L.buf[1] == '\xBB' and L.buf[2] == '\xBF':
inc(L.bufpos, 3) inc(L.bufpos, 3)
inc(L.lineStart, 3) inc(L.lineStart, 3)
@ -167,4 +167,3 @@ proc getCurrentLine(L: TBaseLexer, marker: bool = true): string =
result.add("\n") result.add("\n")
if marker: if marker:
result.add(RepeatChar(getColNumber(L, L.bufpos)) & '^' & "\n") result.add(RepeatChar(getColNumber(L, L.bufpos)) & '^' & "\n")

View file

@ -31,7 +31,7 @@ proc prependCurDir(f: string): string =
else: else:
result = f result = f
proc HandleCmdLine() = proc handleCmdLine() =
if paramCount() == 0: if paramCount() == 0:
writeCommandLineUsage() writeCommandLineUsage()
else: else:
@ -47,12 +47,12 @@ proc HandleCmdLine() =
gProjectName = p.name gProjectName = p.name
else: else:
gProjectPath = getCurrentDir() gProjectPath = getCurrentDir()
LoadConfigs(DefaultConfig) # load all config files loadConfigs(DefaultConfig) # load all config files
# now process command line arguments again, because some options in the # now process command line arguments again, because some options in the
# command line can overwite the config file's settings # command line can overwite the config file's settings
extccomp.initVars() extccomp.initVars()
ProcessCmdLine(passCmd2, "") processCmdLine(passCmd2, "")
MainCommand() mainCommand()
if gVerbosity >= 2: echo(GC_getStatistics()) if gVerbosity >= 2: echo(GC_getStatistics())
#echo(GC_getStatistics()) #echo(GC_getStatistics())
if msgs.gErrorCounter == 0: if msgs.gErrorCounter == 0:
@ -84,5 +84,5 @@ when compileOption("gc", "v2") or compileOption("gc", "refc"):
condsyms.InitDefines() condsyms.InitDefines()
when not defined(selftest): when not defined(selftest):
HandleCmdLine() handleCmdLine()
quit(int8(msgs.gErrorCounter > 0)) quit(int8(msgs.gErrorCounter > 0))

View file

@ -18,7 +18,7 @@ proc overlap*(a, b: PNode): bool
proc inSet*(s: PNode, elem: PNode): bool proc inSet*(s: PNode, elem: PNode): bool
proc someInSet*(s: PNode, a, b: PNode): bool proc someInSet*(s: PNode, a, b: PNode): bool
proc emptyRange*(a, b: PNode): bool proc emptyRange*(a, b: PNode): bool
proc SetHasRange*(s: PNode): bool proc setHasRange*(s: PNode): bool
# returns true if set contains a range (needed by the code generator) # returns true if set contains a range (needed by the code generator)
# these are used for constant folding: # these are used for constant folding:
proc unionSets*(a, b: PNode): PNode proc unionSets*(a, b: PNode): PNode
@ -87,7 +87,7 @@ proc toBitSet(s: PNode, b: var TBitSet) =
else: else:
BitSetIncl(b, getOrdValue(s.sons[i]) - first) BitSetIncl(b, getOrdValue(s.sons[i]) - first)
proc ToTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode = proc toTreeSet(s: TBitSet, settype: PType, info: TLineInfo): PNode =
var var
a, b, e, first: BiggestInt # a, b are interval borders a, b, e, first: BiggestInt # a, b are interval borders
elemType: PType elemType: PType
@ -158,9 +158,9 @@ proc cardSet(s: PNode): BiggestInt =
else: else:
Inc(result) Inc(result)
proc SetHasRange(s: PNode): bool = proc setHasRange(s: PNode): bool =
if s.kind != nkCurly: if s.kind != nkCurly:
InternalError(s.info, "SetHasRange") internalError(s.info, "SetHasRange")
return false return false
for i in countup(0, sonsLen(s) - 1): for i in countup(0, sonsLen(s) - 1):
if s.sons[i].kind == nkRange: if s.sons[i].kind == nkRange:

View file

@ -277,7 +277,7 @@ proc rawFindFile2(f: string): string =
it = PStrEntry(it.Next) it = PStrEntry(it.Next)
result = "" result = ""
proc FindFile*(f: string): string {.procvar.} = proc findFile*(f: string): string {.procvar.} =
result = f.rawFindFile result = f.rawFindFile
if result.len == 0: if result.len == 0:
result = f.toLower.rawFindFile result = f.toLower.rawFindFile

View file

@ -35,7 +35,7 @@ type
lex*: TLexer # the lexer that is used for parsing lex*: TLexer # the lexer that is used for parsing
tok*: TToken # the current token tok*: TToken # the current token
proc ParseAll*(p: var TParser): PNode proc parseAll*(p: var TParser): PNode
proc openParser*(p: var TParser, filename: string, inputstream: PLLStream) proc openParser*(p: var TParser, filename: string, inputstream: PLLStream)
proc closeParser*(p: var TParser) proc closeParser*(p: var TParser)
proc parseTopLevelStmt*(p: var TParser): PNode proc parseTopLevelStmt*(p: var TParser): PNode
@ -59,9 +59,9 @@ proc newFloatNodeP*(kind: TNodeKind, floatVal: BiggestFloat, p: TParser): PNode
proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode proc newStrNodeP*(kind: TNodeKind, strVal: string, p: TParser): PNode
proc newIdentNodeP*(ident: PIdent, p: TParser): PNode proc newIdentNodeP*(ident: PIdent, p: TParser): PNode
proc expectIdentOrKeyw*(p: TParser) proc expectIdentOrKeyw*(p: TParser)
proc ExpectIdent*(p: TParser) proc expectIdent*(p: TParser)
proc parLineInfo*(p: TParser): TLineInfo proc parLineInfo*(p: TParser): TLineInfo
proc Eat*(p: var TParser, TokType: TTokType) proc eat*(p: var TParser, TokType: TTokType)
proc skipInd*(p: var TParser) proc skipInd*(p: var TParser)
proc optPar*(p: var TParser) proc optPar*(p: var TParser)
proc optInd*(p: var TParser, n: PNode) proc optInd*(p: var TParser, n: PNode)
@ -75,17 +75,17 @@ proc parseCase(p: var TParser): PNode
proc getTok(p: var TParser) = proc getTok(p: var TParser) =
rawGetTok(p.lex, p.tok) rawGetTok(p.lex, p.tok)
proc OpenParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream) = proc openParser*(p: var TParser, fileIdx: int32, inputStream: PLLStream) =
initToken(p.tok) initToken(p.tok)
OpenLexer(p.lex, fileIdx, inputstream) openLexer(p.lex, fileIdx, inputstream)
getTok(p) # read the first token getTok(p) # read the first token
p.firstTok = true p.firstTok = true
proc OpenParser*(p: var TParser, filename: string, inputStream: PLLStream) = proc openParser*(p: var TParser, filename: string, inputStream: PLLStream) =
openParser(p, filename.fileInfoIdx, inputStream) openParser(p, filename.fileInfoIdx, inputStream)
proc CloseParser(p: var TParser) = proc closeParser(p: var TParser) =
CloseLexer(p.lex) closeLexer(p.lex)
proc parMessage(p: TParser, msg: TMsgKind, arg: string = "") = proc parMessage(p: TParser, msg: TMsgKind, arg: string = "") =
lexMessage(p.lex, msg, arg) lexMessage(p.lex, msg, arg)
@ -135,11 +135,11 @@ proc expectIdentOrKeyw(p: TParser) =
if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType): if p.tok.tokType != tkSymbol and not isKeyword(p.tok.tokType):
lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok))
proc ExpectIdent(p: TParser) = proc expectIdent(p: TParser) =
if p.tok.tokType != tkSymbol: if p.tok.tokType != tkSymbol:
lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok)) lexMessage(p.lex, errIdentifierExpected, prettyTok(p.tok))
proc Eat(p: var TParser, TokType: TTokType) = proc eat(p: var TParser, TokType: TTokType) =
if p.tok.TokType == TokType: getTok(p) if p.tok.TokType == TokType: getTok(p)
else: lexMessage(p.lex, errTokenExpected, TokTypeToStr[tokType]) else: lexMessage(p.lex, errTokenExpected, TokTypeToStr[tokType])
@ -185,10 +185,10 @@ proc relevantOprChar(ident: PIdent): char {.inline.} =
if result == '\\' and L > 1: if result == '\\' and L > 1:
result = ident.s[1] result = ident.s[1]
proc IsSigilLike(tok: TToken): bool {.inline.} = proc isSigilLike(tok: TToken): bool {.inline.} =
result = tok.tokType == tkOpr and relevantOprChar(tok.ident) == '@' result = tok.tokType == tkOpr and relevantOprChar(tok.ident) == '@'
proc IsLeftAssociative(tok: TToken): bool {.inline.} = proc isLeftAssociative(tok: TToken): bool {.inline.} =
result = tok.tokType != tkOpr or relevantOprChar(tok.ident) != '^' result = tok.tokType != tkOpr or relevantOprChar(tok.ident) != '^'
proc getPrecedence(tok: TToken): int = proc getPrecedence(tok: TToken): int =
@ -427,7 +427,7 @@ proc parseCast(p: var TParser): PNode =
proc setBaseFlags(n: PNode, base: TNumericalBase) = proc setBaseFlags(n: PNode, base: TNumericalBase) =
case base case base
of base10: nil of base10: discard
of base2: incl(n.flags, nfBase2) of base2: incl(n.flags, nfBase2)
of base8: incl(n.flags, nfBase8) of base8: incl(n.flags, nfBase8)
of base16: incl(n.flags, nfBase16) of base16: incl(n.flags, nfBase16)
@ -1862,7 +1862,7 @@ proc parseTopLevelStmt(p: var TParser): PNode =
result = ast.emptyNode result = ast.emptyNode
while true: while true:
if p.tok.indent != 0: if p.tok.indent != 0:
if p.firstTok and p.tok.indent < 0: nil if p.firstTok and p.tok.indent < 0: discard
else: parMessage(p, errInvalidIndentation) else: parMessage(p, errInvalidIndentation)
p.firstTok = false p.firstTok = false
case p.tok.tokType case p.tok.tokType
@ -1881,7 +1881,7 @@ proc parseString(s: string, filename: string = "", line: int = 0): PNode =
stream.lineOffset = line stream.lineOffset = line
var parser: TParser var parser: TParser
OpenParser(parser, filename, stream) openParser(parser, filename, stream)
result = parser.parseAll result = parser.parseAll
CloseParser(parser) closeParser(parser)

View file

@ -10,7 +10,7 @@
import import
llstream, lexer, parser, idents, strutils, ast, msgs llstream, lexer, parser, idents, strutils, ast, msgs
proc ParseAll*(p: var TParser): PNode = proc parseAll*(p: var TParser): PNode =
result = nil result = nil
proc parseTopLevelStmt*(p: var TParser): PNode = proc parseTopLevelStmt*(p: var TParser): PNode =

View file

@ -185,13 +185,13 @@ var
targetCPU*, hostCPU*: TSystemCPU targetCPU*, hostCPU*: TSystemCPU
targetOS*, hostOS*: TSystemOS targetOS*, hostOS*: TSystemOS
proc NameToOS*(name: string): TSystemOS proc nameToOS*(name: string): TSystemOS
proc NameToCPU*(name: string): TSystemCPU proc nameToCPU*(name: string): TSystemCPU
var var
IntSize*: int intSize*: int
floatSize*: int floatSize*: int
PtrSize*: int ptrSize*: int
tnl*: string # target newline tnl*: string # target newline
proc setTarget*(o: TSystemOS, c: TSystemCPU) = proc setTarget*(o: TSystemOS, c: TSystemCPU) =
@ -205,13 +205,13 @@ proc setTarget*(o: TSystemOS, c: TSystemCPU) =
ptrSize = cpu[c].bit div 8 ptrSize = cpu[c].bit div 8
tnl = os[o].newLine tnl = os[o].newLine
proc NameToOS(name: string): TSystemOS = proc nameToOS(name: string): TSystemOS =
for i in countup(succ(osNone), high(TSystemOS)): for i in countup(succ(osNone), high(TSystemOS)):
if cmpIgnoreStyle(name, OS[i].name) == 0: if cmpIgnoreStyle(name, OS[i].name) == 0:
return i return i
result = osNone result = osNone
proc NameToCPU(name: string): TSystemCPU = proc nameToCPU(name: string): TSystemCPU =
for i in countup(succ(cpuNone), high(TSystemCPU)): for i in countup(succ(cpuNone), high(TSystemCPU)):
if cmpIgnoreStyle(name, CPU[i].name) == 0: if cmpIgnoreStyle(name, CPU[i].name) == 0:
return i return i

View file

@ -92,12 +92,12 @@ proc setExternName(s: PSym, extname: string) =
# note that '{.importc.}' is transformed into '{.importc: "$1".}' # note that '{.importc.}' is transformed into '{.importc: "$1".}'
s.loc.flags.incl(lfFullExternalName) s.loc.flags.incl(lfFullExternalName)
proc MakeExternImport(s: PSym, extname: string) = proc makeExternImport(s: PSym, extname: string) =
setExternName(s, extname) setExternName(s, extname)
incl(s.flags, sfImportc) incl(s.flags, sfImportc)
excl(s.flags, sfForward) excl(s.flags, sfForward)
proc MakeExternExport(s: PSym, extname: string) = proc makeExternExport(s: PSym, extname: string) =
setExternName(s, extname) setExternName(s, extname)
incl(s.flags, sfExportc) incl(s.flags, sfExportc)
@ -133,7 +133,7 @@ proc getStrLitNode(c: PContext, n: PNode): PNode =
case n.sons[1].kind case n.sons[1].kind
of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1] of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.sons[1]
else: else:
LocalError(n.info, errStringLiteralExpected) localError(n.info, errStringLiteralExpected)
# error correction: # error correction:
result = newEmptyStrNode(n) result = newEmptyStrNode(n)
@ -142,12 +142,12 @@ proc expectStrLit(c: PContext, n: PNode): string =
proc expectIntLit(c: PContext, n: PNode): int = proc expectIntLit(c: PContext, n: PNode): int =
if n.kind != nkExprColonExpr: if n.kind != nkExprColonExpr:
LocalError(n.info, errIntLiteralExpected) localError(n.info, errIntLiteralExpected)
else: else:
n.sons[1] = c.semConstExpr(c, n.sons[1]) n.sons[1] = c.semConstExpr(c, n.sons[1])
case n.sons[1].kind case n.sons[1].kind
of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal) of nkIntLit..nkInt64Lit: result = int(n.sons[1].intVal)
else: LocalError(n.info, errIntLiteralExpected) else: localError(n.info, errIntLiteralExpected)
proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string = proc getOptionalStr(c: PContext, n: PNode, defaultStr: string): string =
if n.kind == nkExprColonExpr: result = expectStrLit(c, n) if n.kind == nkExprColonExpr: result = expectStrLit(c, n)
@ -160,7 +160,7 @@ proc processMagic(c: PContext, n: PNode, s: PSym) =
#if sfSystemModule notin c.module.flags: #if sfSystemModule notin c.module.flags:
# liMessage(n.info, errMagicOnlyInSystem) # liMessage(n.info, errMagicOnlyInSystem)
if n.kind != nkExprColonExpr: if n.kind != nkExprColonExpr:
LocalError(n.info, errStringLiteralExpected) localError(n.info, errStringLiteralExpected)
return return
var v: string var v: string
if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s if n.sons[1].kind == nkIdent: v = n.sons[1].ident.s
@ -176,15 +176,15 @@ proc wordToCallConv(sw: TSpecialWord): TCallingConvention =
# the same # the same
result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall)) result = TCallingConvention(ord(ccDefault) + ord(sw) - ord(wNimcall))
proc IsTurnedOn(c: PContext, n: PNode): bool = proc isTurnedOn(c: PContext, n: PNode): bool =
if n.kind == nkExprColonExpr: if n.kind == nkExprColonExpr:
let x = c.semConstBoolExpr(c, n.sons[1]) let x = c.semConstBoolExpr(c, n.sons[1])
n.sons[1] = x n.sons[1] = x
if x.kind == nkIntLit: return x.intVal != 0 if x.kind == nkIntLit: return x.intVal != 0
LocalError(n.info, errOnOrOffExpected) localError(n.info, errOnOrOffExpected)
proc onOff(c: PContext, n: PNode, op: TOptions) = proc onOff(c: PContext, n: PNode, op: TOptions) =
if IsTurnedOn(c, n): gOptions = gOptions + op if isTurnedOn(c, n): gOptions = gOptions + op
else: gOptions = gOptions - op else: gOptions = gOptions - op
proc pragmaDeadCodeElim(c: PContext, n: PNode) = proc pragmaDeadCodeElim(c: PContext, n: PNode) =
@ -387,16 +387,16 @@ proc processCommonLink(c: PContext, n: PNode, feature: TLinkFeature) =
extccomp.addFileToLink(libpath / completeCFilePath(found, false)) extccomp.addFileToLink(libpath / completeCFilePath(found, false))
else: internalError(n.info, "processCommonLink") else: internalError(n.info, "processCommonLink")
proc PragmaBreakpoint(c: PContext, n: PNode) = proc pragmaBreakpoint(c: PContext, n: PNode) =
discard getOptionalStr(c, n, "") discard getOptionalStr(c, n, "")
proc PragmaCheckpoint(c: PContext, n: PNode) = proc pragmaCheckpoint(c: PContext, n: PNode) =
# checkpoints can be used to debug the compiler; they are not documented # checkpoints can be used to debug the compiler; they are not documented
var info = n.info var info = n.info
inc(info.line) # next line is affected! inc(info.line) # next line is affected!
msgs.addCheckpoint(info) msgs.addCheckpoint(info)
proc PragmaWatchpoint(c: PContext, n: PNode) = proc pragmaWatchpoint(c: PContext, n: PNode) =
if n.kind == nkExprColonExpr: if n.kind == nkExprColonExpr:
n.sons[1] = c.semExpr(c, n.sons[1]) n.sons[1] = c.semExpr(c, n.sons[1])
else: else:
@ -431,14 +431,14 @@ proc semAsmOrEmit*(con: PContext, n: PNode, marker: char): PNode =
a = c + 1 a = c + 1
else: illFormedAst(n) else: illFormedAst(n)
proc PragmaEmit(c: PContext, n: PNode) = proc pragmaEmit(c: PContext, n: PNode) =
discard getStrLitNode(c, n) discard getStrLitNode(c, n)
n.sons[1] = semAsmOrEmit(c, n, '`') n.sons[1] = semAsmOrEmit(c, n, '`')
proc noVal(n: PNode) = proc noVal(n: PNode) =
if n.kind == nkExprColonExpr: invalidPragma(n) if n.kind == nkExprColonExpr: invalidPragma(n)
proc PragmaUnroll(c: PContext, n: PNode) = proc pragmaUnroll(c: PContext, n: PNode) =
if c.p.nestedLoopCounter <= 0: if c.p.nestedLoopCounter <= 0:
invalidPragma(n) invalidPragma(n)
elif n.kind == nkExprColonExpr: elif n.kind == nkExprColonExpr:
@ -448,7 +448,7 @@ proc PragmaUnroll(c: PContext, n: PNode) =
else: else:
invalidPragma(n) invalidPragma(n)
proc PragmaLine(c: PContext, n: PNode) = proc pragmaLine(c: PContext, n: PNode) =
if n.kind == nkExprColonExpr: if n.kind == nkExprColonExpr:
n.sons[1] = c.semConstExpr(c, n.sons[1]) n.sons[1] = c.semConstExpr(c, n.sons[1])
let a = n.sons[1] let a = n.sons[1]
@ -465,7 +465,7 @@ proc PragmaLine(c: PContext, n: PNode) =
n.info.fileIndex = msgs.fileInfoIdx(x.strVal) n.info.fileIndex = msgs.fileInfoIdx(x.strVal)
n.info.line = int16(y.intVal) n.info.line = int16(y.intVal)
else: else:
LocalError(n.info, errXExpected, "tuple") localError(n.info, errXExpected, "tuple")
else: else:
# sensible default: # sensible default:
n.info = getInfoContext(-1) n.info = getInfoContext(-1)

View file

@ -12,7 +12,7 @@
import import
strutils, os, options, ast, astalgo, msgs, ropes, idents, passes, strutils, os, options, ast, astalgo, msgs, ropes, idents, passes,
intsets, strtabs intsets, strtabs, semdata
const const
removeTP = false # when true, "nimrod pretty" converts TTyp to Typ. removeTP = false # when true, "nimrod pretty" converts TTyp to Typ.
@ -50,7 +50,7 @@ proc overwriteFiles*() =
try: try:
var f = open(newFile, fmWrite) var f = open(newFile, fmWrite)
for line in gSourceFiles[i].lines: for line in gSourceFiles[i].lines:
f.writeln(line) f.writeln(line.strip(leading = false, trailing = true))
f.close f.close
except EIO: except EIO:
rawMessage(errCannotOpenFile, newFile) rawMessage(errCannotOpenFile, newFile)
@ -60,6 +60,126 @@ proc `=~`(s: string, a: openArray[string]): bool =
if s.startsWith(x): return true if s.startsWith(x): return true
proc beautifyName(s: string, k: TSymKind): string = proc beautifyName(s: string, k: TSymKind): string =
# minimal set of rules here for transition:
# GC_ is allowed
let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'})
if allUpper and k in {skConst, skEnumField, skType}: return s
result = newStringOfCap(s.len)
var i = 0
case k
of skType, skGenericParam:
# Types should start with a capital unless builtins like 'int' etc.:
when removeTP:
if s[0] == 'T' and s[1] in {'A'..'Z'}:
i = 1
if s =~ ["int", "uint", "cint", "cuint", "clong", "cstring", "string",
"char", "byte", "bool", "openArray", "seq", "array", "void",
"pointer", "float", "csize", "cdouble", "cchar", "cschar",
"cshort", "cu", "nil", "expr", "stmt", "typedesc", "auto", "any",
"range", "openarray", "varargs", "set", "cfloat"
]:
result.add s[i]
else:
result.add toUpper(s[i])
of skConst, skEnumField:
# for 'const' we keep how it's spelt; either upper case or lower case:
result.add s[0]
else:
# as a special rule, don't transform 'L' to 'l'
if s.len == 1 and s[0] == 'L': result.add 'L'
elif '_' in s: result.add(s[i])
else: result.add toLower(s[0])
inc i
while i < s.len:
if s[i] == '_':
if i > 0 and s[i-1] in {'A'..'Z'}:
# don't skip '_' as it's essential for e.g. 'GC_disable'
result.add('_')
inc i
result.add s[i]
else:
inc i
result.add toUpper(s[i])
elif allUpper:
result.add toLower(s[i])
else:
result.add s[i]
inc i
proc checkStyle*(info: TLineInfo, s: string, k: TSymKind) =
let beau = beautifyName(s, k)
if s != beau:
message(info, errGenerated,
"name does not adhere to naming convention; should be: " & beau)
const
Letters = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
proc identLen(line: string, start: int): int =
while start+result < line.len and line[start+result] in Letters:
inc result
proc differ(line: string, a, b: int, x: string): bool =
let y = line[a..b]
result = cmpIgnoreStyle(y, x) == 0 and y != x
when false:
var j = 0
for i in a..b:
if line[i] != x[j]: return true
inc j
return false
var cannotRename = initIntSet()
proc checkDef(c: PGen; n: PNode) =
if n.kind != nkSym: return
let s = n.sym
# operators stay as they are:
if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
checkStyle(n.info, s.name.s, s.kind)
proc checkUse(c: PGen; n: PNode) =
if n.info.fileIndex < 0: return
let s = n.sym
# we simply convert it to what it looks like in the definition
# for consistency
# operators stay as they are:
if s.kind in {skResult, skTemp} or s.name.s[0] notin Letters: return
if s.kind in {skType, skGenericParam} and sfAnon in s.flags: return
let newName = s.name.s
loadFile(n.info)
let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1]
var first = min(n.info.col.int, line.len)
if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first)
while first > 0 and line[first-1] in Letters: dec first
if first < 0: return
if line[first] == '`': inc first
let last = first+identLen(line, first)-1
if differ(line, first, last, newName):
# last-first+1 != newName.len or
var x = line.subStr(0, first-1) & newName & line.substr(last+1)
when removeTP:
# the WinAPI module is full of 'TX = X' which after the substitution
# becomes 'X = X'. We remove those lines:
if x.match(peg"\s* {\ident} \s* '=' \s* y$1 ('#' .*)?"):
x = ""
system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x)
gSourceFiles[n.info.fileIndex].dirty = true
when false:
proc beautifyName(s: string, k: TSymKind): string =
let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'})
result = newStringOfCap(s.len) result = newStringOfCap(s.len)
var i = 0 var i = 0
case k case k
@ -83,7 +203,6 @@ proc beautifyName(s: string, k: TSymKind): string =
if s.len == 1 and s[0] == 'L': result.add 'L' if s.len == 1 and s[0] == 'L': result.add 'L'
else: result.add toLower(s[0]) else: result.add toLower(s[0])
inc i inc i
let allUpper = allCharsInSet(s, {'A'..'Z', '0'..'9', '_'})
while i < s.len: while i < s.len:
if s[i] == '_': if s[i] == '_':
inc i inc i
@ -94,36 +213,7 @@ proc beautifyName(s: string, k: TSymKind): string =
result.add s[i] result.add s[i]
inc i inc i
proc checkStyle*(info: TLineInfo, s: string, k: TSymKind) = proc checkUse(c: PGen; n: PNode) =
let beau = beautifyName(s, k)
if s != beau:
Message(info, errGenerated,
"name does not adhere to naming convention; should be: " & beau)
const
Letters = {'a'..'z', 'A'..'Z', '0'..'9', '\x80'..'\xFF', '_'}
proc identLen(line: string, start: int): int =
while start+result < line.len and line[start+result] in Letters:
inc result
proc differ(line: string, a, b: int, x: string): bool =
let y = line[a..b]
result = cmpIgnoreStyle(y, x) == 0 and y != x
when false:
var j = 0
for i in a..b:
if line[i] != x[j]: return true
inc j
return false
var cannotRename = initIntSet()
proc processSym(c: PPassContext, n: PNode): PNode =
result = n
var g = PGen(c)
case n.kind
of nkSym:
if n.info.fileIndex < 0: return if n.info.fileIndex < 0: return
let s = n.sym let s = n.sym
# operators stay as they are: # operators stay as they are:
@ -138,10 +228,11 @@ proc processSym(c: PPassContext, n: PNode): PNode =
loadFile(n.info) loadFile(n.info)
let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1] let line = gSourceFiles[n.info.fileIndex].lines[n.info.line-1]
var first = n.info.col.int var first = min(n.info.col.int, line.len)
if first < 0: return if first < 0: return
#inc first, skipIgnoreCase(line, "proc ", first) #inc first, skipIgnoreCase(line, "proc ", first)
while first > 0 and line[first-1] in Letters: dec first while first > 0 and line[first-1] in Letters: dec first
if first < 0: return
if line[first] == '`': inc first if line[first] == '`': inc first
if {sfImportc, sfExportc} * s.flags != {}: if {sfImportc, sfExportc} * s.flags != {}:
@ -149,8 +240,8 @@ proc processSym(c: PPassContext, n: PNode): PNode =
# name: # name:
if newName != s.name.s and newName != s.loc.r.ropeToStr and if newName != s.name.s and newName != s.loc.r.ropeToStr and
lfFullExternalName notin s.loc.flags: lfFullExternalName notin s.loc.flags:
Message(n.info, errGenerated, #Message(n.info, errGenerated,
"cannot rename $# to $# due to external name" % [s.name.s, newName]) # "cannot rename $# to $# due to external name" % [s.name.s, newName])
cannotRename.incl(s.id) cannotRename.incl(s.id)
return return
let last = first+identLen(line, first)-1 let last = first+identLen(line, first)-1
@ -165,9 +256,48 @@ proc processSym(c: PPassContext, n: PNode): PNode =
system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x) system.shallowCopy(gSourceFiles[n.info.fileIndex].lines[n.info.line-1], x)
gSourceFiles[n.info.fileIndex].dirty = true gSourceFiles[n.info.fileIndex].dirty = true
proc check(c: PGen, n: PNode) =
case n.kind
of nkSym: checkUse(c, n)
of nkBlockStmt, nkBlockExpr, nkBlockType:
if n.sons[0].kind != nkEmpty: checkDef(c, n[0])
check(c, n.sons[1])
of nkForStmt, nkParForStmt:
let L = n.len
for i in countup(0, L-3):
checkDef(c, n[i])
check(c, n[L-2])
check(c, n[L-1])
of nkProcDef, nkLambdaKinds, nkMethodDef, nkIteratorDef, nkTemplateDef,
nkMacroDef, nkConverterDef:
checkDef(c, n[namePos])
for i in namePos+1 .. <n.len: check(c, n.sons[i])
of nkVarSection, nkLetSection:
for i in countup(0, sonsLen(n) - 1):
let a = n.sons[i]
if a.kind == nkCommentStmt: continue
if a.kind != nkIdentDefs and a.kind != nkVarTuple:
globalError(a.info, errGenerated, "invalid ast")
checkMinSonsLen(a, 3)
let L = len(a)
for j in countup(0, L-3): checkDef(c, a.sons[j])
check(c, a.sons[L-2])
check(c, a.sons[L-1])
of nkTypeSection, nkConstSection:
for i in countup(0, sonsLen(n) - 1):
let a = n.sons[i]
if a.kind == nkCommentStmt: continue
checkSonsLen(a, 3)
checkDef(c, a.sons[0])
check(c, a.sons[1])
check(c, a.sons[2])
else: else:
for i in 0 .. <n.safeLen: for i in 0 .. <n.safeLen: check(c, n.sons[i])
discard processSym(c, n.sons[i])
proc processSym(c: PPassContext, n: PNode): PNode =
result = n
check(PGen(c), n)
proc myOpen(module: PSym): PPassContext = proc myOpen(module: PSym): PPassContext =
var g: PGen var g: PGen

View file

@ -17,20 +17,20 @@ proc equalGenericParams(procA, procB: PNode): bool =
if sonsLen(procA) != sonsLen(procB): return if sonsLen(procA) != sonsLen(procB): return
for i in countup(0, sonsLen(procA) - 1): for i in countup(0, sonsLen(procA) - 1):
if procA.sons[i].kind != nkSym: if procA.sons[i].kind != nkSym:
InternalError(procA.info, "equalGenericParams") internalError(procA.info, "equalGenericParams")
return return
if procB.sons[i].kind != nkSym: if procB.sons[i].kind != nkSym:
InternalError(procB.info, "equalGenericParams") internalError(procB.info, "equalGenericParams")
return return
let a = procA.sons[i].sym let a = procA.sons[i].sym
let b = procB.sons[i].sym let b = procB.sons[i].sym
if a.name.id != b.name.id or if a.name.id != b.name.id or
not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return not sameTypeOrNil(a.typ, b.typ, {TypeDescExactMatch}): return
if a.ast != nil and b.ast != nil: if a.ast != nil and b.ast != nil:
if not ExprStructuralEquivalent(a.ast, b.ast): return if not exprStructuralEquivalent(a.ast, b.ast): return
result = true result = true
proc SearchForProc*(c: PContext, scope: PScope, fn: PSym): PSym = proc searchForProc*(c: PContext, scope: PScope, fn: PSym): PSym =
# Searchs for a forward declaration or a "twin" symbol of fn # Searchs for a forward declaration or a "twin" symbol of fn
# in the symbol table. If the parameter lists are exactly # in the symbol table. If the parameter lists are exactly
# the same the sym in the symbol table is returned, else nil. # the same the sym in the symbol table is returned, else nil.
@ -77,7 +77,7 @@ when false:
dcEqOrDistinctOf): return dcEqOrDistinctOf): return
result = true result = true
proc SearchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym = proc searchForBorrowProc*(c: PContext, startScope: PScope, fn: PSym): PSym =
# Searchs for the fn in the symbol table. If the parameter lists are suitable # Searchs for the fn in the symbol table. If the parameter lists are suitable
# for borrowing the sym in the symbol table is returned, else nil. # for borrowing the sym in the symbol table is returned, else nil.
var it: TIdentIter var it: TIdentIter

View file

@ -62,7 +62,7 @@ const
MaxLineLen = 80 MaxLineLen = 80
LineCommentColumn = 30 LineCommentColumn = 30
proc InitSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) = proc initSrcGen(g: var TSrcGen, renderFlags: TRenderFlags) =
g.comStack = @[] g.comStack = @[]
g.tokens = @[] g.tokens = @[]
g.indent = 0 g.indent = 0
@ -108,12 +108,12 @@ proc indentNL(g: var TSrcGen) =
g.pendingNL = g.indent g.pendingNL = g.indent
g.lineLen = g.indent g.lineLen = g.indent
proc Dedent(g: var TSrcGen) = proc dedent(g: var TSrcGen) =
dec(g.indent, indentWidth) dec(g.indent, indentWidth)
assert(g.indent >= 0) assert(g.indent >= 0)
if g.pendingNL > indentWidth: if g.pendingNL > indentWidth:
Dec(g.pendingNL, indentWidth) dec(g.pendingNL, indentWidth)
Dec(g.lineLen, indentWidth) dec(g.lineLen, indentWidth)
proc put(g: var TSrcGen, kind: TTokType, s: string) = proc put(g: var TSrcGen, kind: TTokType, s: string) =
addPendingNL(g) addPendingNL(g)

View file

@ -184,7 +184,7 @@ proc skipNode(r: PRodReader) =
if par == 0: break if par == 0: break
dec par dec par
of '(': inc par of '(': inc par
else: nil else: discard
inc pos inc pos
r.pos = pos+1 # skip ')' r.pos = pos+1 # skip ')'
@ -248,7 +248,7 @@ proc decodeNodeLazyBody(r: PRodReader, fInfo: TLineInfo,
if r.s[r.pos] == ')': inc(r.pos) if r.s[r.pos] == ')': inc(r.pos)
else: internalError(result.info, "decodeNode: ')' missing") else: internalError(result.info, "decodeNode: ')' missing")
else: else:
InternalError(fInfo, "decodeNode: '(' missing " & $r.pos) internalError(fInfo, "decodeNode: '(' missing " & $r.pos)
proc decodeNode(r: PRodReader, fInfo: TLineInfo): PNode = proc decodeNode(r: PRodReader, fInfo: TLineInfo): PNode =
result = decodeNodeLazyBody(r, fInfo, nil) result = decodeNodeLazyBody(r, fInfo, nil)
@ -286,7 +286,7 @@ proc decodeLoc(r: PRodReader, loc: var TLoc, info: TLineInfo) =
else: else:
loc.a = 0 loc.a = 0
if r.s[r.pos] == '>': inc(r.pos) if r.s[r.pos] == '>': inc(r.pos)
else: InternalError(info, "decodeLoc " & r.s[r.pos]) else: internalError(info, "decodeLoc " & r.s[r.pos])
proc decodeType(r: PRodReader, info: TLineInfo): PType = proc decodeType(r: PRodReader, info: TLineInfo): PType =
result = nil result = nil
@ -303,9 +303,9 @@ proc decodeType(r: PRodReader, info: TLineInfo): PType =
setId(result.id) setId(result.id)
if debugIds: registerID(result) if debugIds: registerID(result)
else: else:
InternalError(info, "decodeType: no id") internalError(info, "decodeType: no id")
# here this also avoids endless recursion for recursive type # here this also avoids endless recursion for recursive type
IdTablePut(gTypeTable, result, result) idTablePut(gTypeTable, result, result)
if r.s[r.pos] == '(': result.n = decodeNode(r, UnknownLineInfo()) if r.s[r.pos] == '(': result.n = decodeNode(r, UnknownLineInfo())
if r.s[r.pos] == '$': if r.s[r.pos] == '$':
inc(r.pos) inc(r.pos)
@ -370,7 +370,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
id = decodeVInt(r.s, r.pos) id = decodeVInt(r.s, r.pos)
setId(id) setId(id)
else: else:
InternalError(info, "decodeSym: no id") internalError(info, "decodeSym: no id")
if r.s[r.pos] == '&': if r.s[r.pos] == '&':
inc(r.pos) inc(r.pos)
ident = getIdent(decodeStr(r.s, r.pos)) ident = getIdent(decodeStr(r.s, r.pos))
@ -384,7 +384,7 @@ proc decodeSym(r: PRodReader, info: TLineInfo): PSym =
IdTablePut(r.syms, result, result) IdTablePut(r.syms, result, result)
if debugIds: registerID(result) if debugIds: registerID(result)
elif result.id != id: elif result.id != id:
InternalError(info, "decodeSym: wrong id") internalError(info, "decodeSym: wrong id")
elif result.kind != skStub and not r.inViewMode: elif result.kind != skStub and not r.inViewMode:
# we already loaded the symbol # we already loaded the symbol
return return
@ -455,7 +455,7 @@ proc skipSection(r: PRodReader) =
elif c > 0: elif c > 0:
dec(c) dec(c)
of '\0': break # end of file of '\0': break # end of file
else: nil else: discard
inc(r.pos) inc(r.pos)
else: else:
InternalError("skipSection " & $r.line) InternalError("skipSection " & $r.line)
@ -799,7 +799,7 @@ proc loadMethods(r: PRodReader) =
r.methods.add(rrGetSym(r, d, UnknownLineInfo())) r.methods.add(rrGetSym(r, d, UnknownLineInfo()))
if r.s[r.pos] == ' ': inc(r.pos) if r.s[r.pos] == ' ': inc(r.pos)
proc GetCRC*(fileIdx: int32): TCrc32 = proc getCRC*(fileIdx: int32): TCrc32 =
InternalAssert fileIdx >= 0 and fileIdx < gMods.len InternalAssert fileIdx >= 0 and fileIdx < gMods.len
if gMods[fileIdx].crcDone: if gMods[fileIdx].crcDone:
@ -818,14 +818,14 @@ proc checkDep(fileIdx: int32): TReasonForRecompile =
# reason has already been computed for this module: # reason has already been computed for this module:
return gMods[fileIdx].reason return gMods[fileIdx].reason
let filename = fileIdx.toFilename let filename = fileIdx.toFilename
var crc = GetCRC(fileIdx) var crc = getCRC(fileIdx)
gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles gMods[fileIdx].reason = rrNone # we need to set it here to avoid cycles
result = rrNone result = rrNone
var r: PRodReader = nil var r: PRodReader = nil
var rodfile = toGeneratedFile(filename.withPackageName, RodExt) var rodfile = toGeneratedFile(filename.withPackageName, RodExt)
r = newRodReader(rodfile, crc, fileIdx) r = newRodReader(rodfile, crc, fileIdx)
if r == nil: if r == nil:
result = (if ExistsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist) result = (if existsFile(rodfile): rrRodInvalid else: rrRodDoesNotExist)
else: else:
processRodFile(r, crc) processRodFile(r, crc)
result = r.reason result = r.reason
@ -880,12 +880,12 @@ proc rawLoadStub(s: PSym) =
if rs != s: if rs != s:
#echo "rs: ", toHex(cast[int](rs.position), int.sizeof * 2), #echo "rs: ", toHex(cast[int](rs.position), int.sizeof * 2),
# "\ns: ", toHex(cast[int](s.position), int.sizeof * 2) # "\ns: ", toHex(cast[int](s.position), int.sizeof * 2)
InternalError(rs.info, "loadStub: wrong symbol") internalError(rs.info, "loadStub: wrong symbol")
elif rs.id != theId: elif rs.id != theId:
InternalError(rs.info, "loadStub: wrong ID") internalError(rs.info, "loadStub: wrong ID")
#MessageOut('loaded stub: ' + s.name.s); #MessageOut('loaded stub: ' + s.name.s);
proc LoadStub*(s: PSym) = proc loadStub*(s: PSym) =
## loads the stub symbol `s`. ## loads the stub symbol `s`.
# deactivate the GC here because we do a deep recursion and generate no # deactivate the GC here because we do a deep recursion and generate no
@ -912,8 +912,8 @@ proc getBody*(s: PSym): PNode =
s.ast.sons[bodyPos] = result s.ast.sons[bodyPos] = result
s.offset = 0 s.offset = 0
InitIdTable(gTypeTable) initIdTable(gTypeTable)
InitStrTable(rodCompilerProcs) initStrTable(rodCompilerProcs)
# viewer: # viewer:
proc writeNode(f: TFile; n: PNode) = proc writeNode(f: TFile; n: PNode) =
@ -1166,7 +1166,7 @@ proc viewFile(rodfile: string) =
if r.s[r.pos] == ')': inc r.pos if r.s[r.pos] == ')': inc r.pos
outf.write("<not supported by viewer>)\n") outf.write("<not supported by viewer>)\n")
else: else:
InternalError("invalid section: '" & section & internalError("invalid section: '" & section &
"' at " & $r.line & " in " & r.filename) "' at " & $r.line & " in " & r.filename)
skipSection(r) skipSection(r)
if r.s[r.pos] == '\x0A': if r.s[r.pos] == '\x0A':

View file

@ -12,7 +12,7 @@ import strutils
proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", nodecl, varargs.} proc c_sprintf(buf, frmt: cstring) {.importc: "sprintf", nodecl, varargs.}
proc ToStrMaxPrecision*(f: BiggestFloat): string = proc toStrMaxPrecision*(f: BiggestFloat): string =
if f != f: if f != f:
result = "NAN" result = "NAN"
elif f == 0.0: elif f == 0.0:
@ -36,7 +36,7 @@ proc hexChar(c: char, xi: var int) =
of '0'..'9': xi = (xi shl 4) or (ord(c) - ord('0')) 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) of 'a'..'f': xi = (xi shl 4) or (ord(c) - ord('a') + 10)
of 'A'..'F': xi = (xi shl 4) or (ord(c) - ord('A') + 10) of 'A'..'F': xi = (xi shl 4) or (ord(c) - ord('A') + 10)
else: nil else: discard
proc decodeStr*(s: cstring, pos: var int): string = proc decodeStr*(s: cstring, pos: var int): string =
var i = pos var i = pos

View file

@ -91,13 +91,13 @@ proc writeRopeIfNotEqual*(r: PRope, filename: string): bool
proc ropeToStr*(p: PRope): string proc ropeToStr*(p: PRope): string
proc ropef*(frmt: TFormatStr, args: varargs[PRope]): PRope proc ropef*(frmt: TFormatStr, args: varargs[PRope]): PRope
proc appf*(c: var PRope, frmt: TFormatStr, args: varargs[PRope]) proc appf*(c: var PRope, frmt: TFormatStr, args: varargs[PRope])
proc RopeEqualsFile*(r: PRope, f: string): bool proc ropeEqualsFile*(r: PRope, f: string): bool
# returns true if the rope r is the same as the contents of file f # returns true if the rope r is the same as the contents of file f
proc RopeInvariant*(r: PRope): bool proc ropeInvariant*(r: PRope): bool
# exported for debugging # exported for debugging
# implementation # implementation
var ErrorHandler*: proc(err: TRopesError, msg: string, useWarning = false) var errorHandler*: proc(err: TRopesError, msg: string, useWarning = false)
# avoid dependency on msgs.nim # avoid dependency on msgs.nim
proc ropeLen(a: PRope): int = proc ropeLen(a: PRope): int =
@ -126,7 +126,7 @@ proc resetRopeCache* =
for i in low(cache)..high(cache): for i in low(cache)..high(cache):
cache[i] = nil cache[i] = nil
proc RopeInvariant(r: PRope): bool = proc ropeInvariant(r: PRope): bool =
if r == nil: if r == nil:
result = true result = true
else: else:
@ -159,7 +159,7 @@ proc toRope(s: string): PRope =
result = insertInCache(s) result = insertInCache(s)
assert(RopeInvariant(result)) assert(RopeInvariant(result))
proc RopeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) = proc ropeSeqInsert(rs: var TRopeSeq, r: PRope, at: Natural) =
var length = len(rs) var length = len(rs)
if at > length: if at > length:
setlen(rs, at + 1) setlen(rs, at + 1)
@ -177,8 +177,8 @@ proc newRecRopeToStr(result: var string, resultLen: var int, r: PRope) =
add(stack, it.right) add(stack, it.right)
it = it.left it = it.left
assert(it.data != nil) assert(it.data != nil)
CopyMem(addr(result[resultLen]), addr(it.data[0]), it.length) copyMem(addr(result[resultLen]), addr(it.data[0]), it.length)
Inc(resultLen, it.length) inc(resultLen, it.length)
assert(resultLen <= len(result)) assert(resultLen <= len(result))
proc ropeToStr(p: PRope): string = proc ropeToStr(p: PRope): string =
@ -227,13 +227,13 @@ proc writeRope*(f: TFile, c: PRope) =
assert(it.data != nil) assert(it.data != nil)
write(f, it.data) write(f, it.data)
proc WriteRope*(head: PRope, filename: string, useWarning = false) = proc writeRope*(head: PRope, filename: string, useWarning = false) =
var f: tfile var f: tfile
if open(f, filename, fmWrite): if open(f, filename, fmWrite):
if head != nil: WriteRope(f, head) if head != nil: WriteRope(f, head)
close(f) close(f)
else: else:
ErrorHandler(rCannotOpenFile, filename, useWarning) errorHandler(rCannotOpenFile, filename, useWarning)
var var
rnl* = tnl.newRope rnl* = tnl.newRope
@ -263,7 +263,7 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break if (i > length + 0 - 1) or not (frmt[i] in {'0'..'9'}): break
num = j num = j
if j > high(args) + 1: if j > high(args) + 1:
ErrorHandler(rInvalidFormatStr, $(j)) errorHandler(rInvalidFormatStr, $(j))
else: else:
app(result, args[j - 1]) app(result, args[j - 1])
of 'n': of 'n':
@ -273,7 +273,7 @@ proc ropef(frmt: TFormatStr, args: varargs[PRope]): PRope =
app(result, rnl) app(result, rnl)
inc(i) inc(i)
else: else:
ErrorHandler(rInvalidFormatStr, $(frmt[i])) errorHandler(rInvalidFormatStr, $(frmt[i]))
var start = i var start = i
while i < length: while i < length:
if frmt[i] != '$': inc(i) if frmt[i] != '$': inc(i)
@ -308,8 +308,8 @@ proc auxRopeEqualsFile(r: PRope, bin: var tfile, buf: Pointer): bool =
result = auxRopeEqualsFile(r.left, bin, buf) result = auxRopeEqualsFile(r.left, bin, buf)
if result: result = auxRopeEqualsFile(r.right, bin, buf) if result: result = auxRopeEqualsFile(r.right, bin, buf)
proc RopeEqualsFile(r: PRope, f: string): bool = proc ropeEqualsFile(r: PRope, f: string): bool =
var bin: tfile var bin: TFile
result = open(bin, f) result = open(bin, f)
if not result: if not result:
return # not equal if file does not exist return # not equal if file does not exist

View file

@ -66,7 +66,7 @@ proc fitNode(c: PContext, formal: PType, arg: PNode): PNode =
result = copyTree(arg) result = copyTree(arg)
result.typ = formal result.typ = formal
var CommonTypeBegin = PType(kind: tyExpr) var commonTypeBegin = PType(kind: tyExpr)
proc commonType*(x, y: PType): PType = proc commonType*(x, y: PType): PType =
# new type relation that is used for array constructors, # new type relation that is used for array constructors,

View file

@ -19,7 +19,7 @@ proc sameMethodDispatcher(a, b: PSym): bool =
if aa.sym == bb.sym: if aa.sym == bb.sym:
result = true result = true
else: else:
nil discard
# generics have no dispatcher yet, so we need to compare the method # generics have no dispatcher yet, so we need to compare the method
# names; however, the names are equal anyway because otherwise we # names; however, the names are equal anyway because otherwise we
# wouldn't even consider them to be overloaded. But even this does # wouldn't even consider them to be overloaded. But even this does
@ -74,13 +74,13 @@ proc pickBestCandidate(c: PContext, headSymbol: PNode,
else: nil else: nil
sym = nextOverloadIter(o, c, headSymbol) sym = nextOverloadIter(o, c, headSymbol)
proc NotFoundError*(c: PContext, n: PNode, errors: seq[string]) = proc notFoundError*(c: PContext, n: PNode, errors: seq[string]) =
# Gives a detailed error message; this is separated from semOverloadedCall, # Gives a detailed error message; this is separated from semOverloadedCall,
# as semOverlodedCall is already pretty slow (and we need this information # as semOverlodedCall is already pretty slow (and we need this information
# only in case of an error). # only in case of an error).
if c.InCompilesContext > 0: if c.inCompilesContext > 0:
# fail fast: # fail fast:
GlobalError(n.info, errTypeMismatch, "") globalError(n.info, errTypeMismatch, "")
var result = msgKindToString(errTypeMismatch) var result = msgKindToString(errTypeMismatch)
add(result, describeArgs(c, n, 1 + ord(nfDelegate in n.flags))) add(result, describeArgs(c, n, 1 + ord(nfDelegate in n.flags)))
add(result, ')') add(result, ')')
@ -93,7 +93,7 @@ proc NotFoundError*(c: PContext, n: PNode, errors: seq[string]) =
if candidates != "": if candidates != "":
add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates) add(result, "\n" & msgKindToString(errButExpected) & "\n" & candidates)
LocalError(n.Info, errGenerated, result) localError(n.Info, errGenerated, result)
proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) = proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) =
for scope in walkScopes(c.currentScope): for scope in walkScopes(c.currentScope):
@ -164,12 +164,12 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
if alt.state == csMatch and cmpCandidates(result, alt) == 0 and if alt.state == csMatch and cmpCandidates(result, alt) == 0 and
not sameMethodDispatcher(result.calleeSym, alt.calleeSym): not sameMethodDispatcher(result.calleeSym, alt.calleeSym):
InternalAssert result.state == csMatch internalAssert result.state == csMatch
#writeMatches(result) #writeMatches(result)
#writeMatches(alt) #writeMatches(alt)
if c.inCompilesContext > 0: if c.inCompilesContext > 0:
# quick error message for performance of 'compiles' built-in: # quick error message for performance of 'compiles' built-in:
GlobalError(n.Info, errGenerated, "ambiguous call") globalError(n.Info, errGenerated, "ambiguous call")
elif gErrorCounter == 0: elif gErrorCounter == 0:
# don't cascade errors # don't cascade errors
var args = "(" var args = "("
@ -178,7 +178,7 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
add(args, typeToString(n.sons[i].typ)) add(args, typeToString(n.sons[i].typ))
add(args, ")") add(args, ")")
LocalError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [ localError(n.Info, errGenerated, msgKindToString(errAmbiguousCallXYZ) % [
getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym), getProcHeader(result.calleeSym), getProcHeader(alt.calleeSym),
args]) args])
@ -197,14 +197,14 @@ proc instGenericConvertersSons*(c: PContext, n: PNode, x: TCandidate) =
for i in 1 .. <n.len: for i in 1 .. <n.len:
instGenericConvertersArg(c, n.sons[i], x) instGenericConvertersArg(c, n.sons[i], x)
proc IndexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode = proc indexTypesMatch(c: PContext, f, a: PType, arg: PNode): PNode =
var m: TCandidate var m: TCandidate
initCandidate(m, f) initCandidate(m, f)
result = paramTypesMatch(c, m, f, a, arg, nil) result = paramTypesMatch(c, m, f, a, arg, nil)
if m.genericConverter and result != nil: if m.genericConverter and result != nil:
instGenericConvertersArg(c, result, m) instGenericConvertersArg(c, result, m)
proc ConvertTo*(c: PContext, f: PType, n: PNode): PNode = proc convertTo*(c: PContext, f: PType, n: PNode): PNode =
var m: TCandidate var m: TCandidate
initCandidate(m, f) initCandidate(m, f)
result = paramTypesMatch(c, m, f, n.typ, n, nil) result = paramTypesMatch(c, m, f, n.typ, n, nil)
@ -239,7 +239,7 @@ proc semOverloadedCall(c: PContext, n, nOrig: PNode,
# else: result = errorNode(c, n) # else: result = errorNode(c, n)
proc explicitGenericInstError(n: PNode): PNode = proc explicitGenericInstError(n: PNode): PNode =
LocalError(n.info, errCannotInstantiateX, renderTree(n)) localError(n.info, errCannotInstantiateX, renderTree(n))
result = n result = n
proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode = proc explicitGenericSym(c: PContext, n: PNode, s: PSym): PNode =
@ -283,7 +283,7 @@ proc explicitGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode =
else: else:
result = explicitGenericInstError(n) result = explicitGenericInstError(n)
proc SearchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym = proc searchForBorrowProc(c: PContext, startScope: PScope, fn: PSym): PSym =
# Searchs for the fn in the symbol table. If the parameter lists are suitable # Searchs for the fn in the symbol table. If the parameter lists are suitable
# for borrowing the sym in the symbol table is returned, else nil. # for borrowing the sym in the symbol table is returned, else nil.
# New approach: generate fn(x, y, z) where x, y, z have the proper types # New approach: generate fn(x, y, z) where x, y, z have the proper types

View file

@ -21,7 +21,7 @@ type
options*: TOptions options*: TOptions
defaultCC*: TCallingConvention defaultCC*: TCallingConvention
dynlib*: PLib dynlib*: PLib
Notes*: TNoteKinds notes*: TNoteKinds
otherPragmas*: PNode # every pragma can be pushed otherPragmas*: PNode # every pragma can be pushed
POptionEntry* = ref TOptionEntry POptionEntry* = ref TOptionEntry
@ -32,7 +32,7 @@ type
resultSym*: PSym # the result symbol (if we are in a proc) resultSym*: PSym # the result symbol (if we are in a proc)
nestedLoopCounter*: int # whether we are in a loop or not nestedLoopCounter*: int # whether we are in a loop or not
nestedBlockCounter*: int # whether we are in a block or not nestedBlockCounter*: int # whether we are in a block or not
InTryStmt*: int # whether we are in a try statement; works also inTryStmt*: int # whether we are in a try statement; works also
# in standalone ``except`` and ``finally`` # in standalone ``except`` and ``finally``
next*: PProcCon # used for stacking procedure contexts next*: PProcCon # used for stacking procedure contexts
@ -55,16 +55,16 @@ type
friendModule*: PSym # current friend module; may access private data; friendModule*: PSym # current friend module; may access private data;
# this is used so that generic instantiations # this is used so that generic instantiations
# can access private object fields # can access private object fields
InstCounter*: int # to prevent endless instantiations instCounter*: int # to prevent endless instantiations
threadEntries*: TSymSeq # list of thread entries to check threadEntries*: TSymSeq # list of thread entries to check
AmbiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot ambiguousSymbols*: TIntSet # ids of all ambiguous symbols (cannot
# store this info in the syms themselves!) # store this info in the syms themselves!)
InTypeClass*: int # > 0 if we are in a user-defined type class inTypeClass*: int # > 0 if we are in a user-defined type class
InGenericContext*: int # > 0 if we are in a generic type inGenericContext*: int # > 0 if we are in a generic type
InUnrolledContext*: int # > 0 if we are unrolling a loop inUnrolledContext*: int # > 0 if we are unrolling a loop
InCompilesContext*: int # > 0 if we are in a ``compiles`` magic inCompilesContext*: int # > 0 if we are in a ``compiles`` magic
InGenericInst*: int # > 0 if we are instantiating a generic inGenericInst*: int # > 0 if we are instantiating a generic
converters*: TSymSeq # sequence of converters converters*: TSymSeq # sequence of converters
patterns*: TSymSeq # sequence of pattern matchers patterns*: TSymSeq # sequence of pattern matchers
optionStack*: TLinkedList optionStack*: TLinkedList
@ -83,7 +83,7 @@ type
includedFiles*: TIntSet # used to detect recursive include files includedFiles*: TIntSet # used to detect recursive include files
userPragmas*: TStrTable userPragmas*: TStrTable
evalContext*: PEvalContext evalContext*: PEvalContext
UnknownIdents*: TIntSet # ids of all unknown identifiers to prevent unknownIdents*: TIntSet # ids of all unknown identifiers to prevent
# naming it multiple times # naming it multiple times
generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile generics*: seq[TInstantiationPair] # pending list of instantiated generics to compile
lastGenericIdx*: int # used for the generics stack lastGenericIdx*: int # used for the generics stack
@ -114,8 +114,8 @@ proc scopeDepth*(c: PContext): int {.inline.} =
# owner handling: # owner handling:
proc getCurrOwner*(): PSym proc getCurrOwner*(): PSym
proc PushOwner*(owner: PSym) proc pushOwner*(owner: PSym)
proc PopOwner*() proc popOwner*()
# implementation # implementation
var gOwners*: seq[PSym] = @[] var gOwners*: seq[PSym] = @[]
@ -128,13 +128,13 @@ proc getCurrOwner(): PSym =
# BUGFIX: global array is needed! # BUGFIX: global array is needed!
result = gOwners[high(gOwners)] result = gOwners[high(gOwners)]
proc PushOwner(owner: PSym) = proc pushOwner(owner: PSym) =
add(gOwners, owner) add(gOwners, owner)
proc PopOwner() = proc popOwner() =
var length = len(gOwners) var length = len(gOwners)
if length > 0: setlen(gOwners, length - 1) if length > 0: setlen(gOwners, length - 1)
else: InternalError("popOwner") else: internalError("popOwner")
proc lastOptionEntry(c: PContext): POptionEntry = proc lastOptionEntry(c: PContext): POptionEntry =
result = POptionEntry(c.optionStack.tail) result = POptionEntry(c.optionStack.tail)
@ -249,7 +249,7 @@ proc markIndirect*(c: PContext, s: PSym) {.inline.} =
# XXX add to 'c' for global analysis # XXX add to 'c' for global analysis
proc illFormedAst*(n: PNode) = proc illFormedAst*(n: PNode) =
GlobalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments})) globalError(n.info, errIllFormedAstX, renderTree(n, {renderNoComments}))
proc checkSonsLen*(n: PNode, length: int) = proc checkSonsLen*(n: PNode, length: int) =
if sonsLen(n) != length: illFormedAst(n) if sonsLen(n) != length: illFormedAst(n)

View file

@ -15,9 +15,9 @@
# generation (needed for recursive types) # generation (needed for recursive types)
# 2) DestructorIsTrivial: completed the analysis before and determined # 2) DestructorIsTrivial: completed the analysis before and determined
# that the type has a trivial destructor # that the type has a trivial destructor
var AnalyzingDestructor, DestructorIsTrivial: PSym var analyzingDestructor, destructorIsTrivial: PSym
new(AnalyzingDestructor) new(analyzingDestructor)
new(DestructorIsTrivial) new(destructorIsTrivial)
var var
destructorName = getIdent"destroy_" destructorName = getIdent"destroy_"

View file

@ -1176,7 +1176,7 @@ proc semAsgn(c: PContext, n: PNode): PNode =
asgnToResultVar(c, n, n.sons[0], n.sons[1]) asgnToResultVar(c, n, n.sons[0], n.sons[1])
result = n result = n
proc SemReturn(c: PContext, n: PNode): PNode = proc semReturn(c: PContext, n: PNode): PNode =
result = n result = n
checkSonsLen(n, 1) checkSonsLen(n, 1)
if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or if c.p.owner.kind in {skConverter, skMethod, skProc, skMacro} or
@ -1223,7 +1223,7 @@ proc semProcBody(c: PContext, n: PNode): PNode =
discardCheck(c, result) discardCheck(c, result)
closeScope(c) closeScope(c)
proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) = proc semYieldVarResult(c: PContext, n: PNode, restype: PType) =
var t = skipTypes(restype, {tyGenericInst}) var t = skipTypes(restype, {tyGenericInst})
case t.kind case t.kind
of tyVar: of tyVar:
@ -1242,7 +1242,7 @@ proc SemYieldVarResult(c: PContext, n: PNode, restype: PType) =
localError(n.sons[0].info, errXExpected, "tuple constructor") localError(n.sons[0].info, errXExpected, "tuple constructor")
else: nil else: nil
proc SemYield(c: PContext, n: PNode): PNode = proc semYield(c: PContext, n: PNode): PNode =
result = n result = n
checkSonsLen(n, 1) checkSonsLen(n, 1)
if c.p.owner == nil or c.p.owner.kind != skIterator: if c.p.owner == nil or c.p.owner.kind != skIterator:
@ -1267,30 +1267,30 @@ proc lookUpForDefined(c: PContext, i: PIdent, onlyCurrentScope: bool): PSym =
else: else:
result = searchInScopes(c, i) # no need for stub loading result = searchInScopes(c, i) # no need for stub loading
proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym =
case n.kind case n.kind
of nkIdent: of nkIdent:
result = LookupForDefined(c, n.ident, onlyCurrentScope) result = lookupForDefined(c, n.ident, onlyCurrentScope)
of nkDotExpr: of nkDotExpr:
result = nil result = nil
if onlyCurrentScope: return if onlyCurrentScope: return
checkSonsLen(n, 2) checkSonsLen(n, 2)
var m = LookupForDefined(c, n.sons[0], onlyCurrentScope) var m = lookupForDefined(c, n.sons[0], onlyCurrentScope)
if (m != nil) and (m.kind == skModule): if (m != nil) and (m.kind == skModule):
if (n.sons[1].kind == nkIdent): if (n.sons[1].kind == nkIdent):
var ident = n.sons[1].ident var ident = n.sons[1].ident
if m == c.module: if m == c.module:
result = StrTableGet(c.topLevelScope.symbols, ident) result = strTableGet(c.topLevelScope.symbols, ident)
else: else:
result = StrTableGet(m.tab, ident) result = strTableGet(m.tab, ident)
else: else:
LocalError(n.sons[1].info, errIdentifierExpected, "") localError(n.sons[1].info, errIdentifierExpected, "")
of nkAccQuoted: of nkAccQuoted:
result = lookupForDefined(c, considerAcc(n), onlyCurrentScope) result = lookupForDefined(c, considerAcc(n), onlyCurrentScope)
of nkSym: of nkSym:
result = n.sym result = n.sym
else: else:
LocalError(n.info, errIdentifierExpected, renderTree(n)) localError(n.info, errIdentifierExpected, renderTree(n))
result = nil result = nil
proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode =

View file

@ -73,7 +73,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode =
result = n result = n
else: result = newSymNode(s, n.info) else: result = newSymNode(s, n.info)
proc Lookup(c: PContext, n: PNode, flags: TSemGenericFlags, proc lookup(c: PContext, n: PNode, flags: TSemGenericFlags,
ctx: var TIntSet): PNode = ctx: var TIntSet): PNode =
result = n result = n
let ident = considerAcc(n) let ident = considerAcc(n)

View file

@ -50,7 +50,7 @@ proc sameInstantiation(a, b: TInstantiation): bool =
flags = {TypeDescExactMatch}): return flags = {TypeDescExactMatch}): return
result = true result = true
proc GenericCacheGet(genericSym: Psym, entry: TInstantiation): PSym = proc genericCacheGet(genericSym: Psym, entry: TInstantiation): PSym =
if genericSym.procInstCache != nil: if genericSym.procInstCache != nil:
for inst in genericSym.procInstCache: for inst in genericSym.procInstCache:
if sameInstantiation(entry, inst[]): if sameInstantiation(entry, inst[]):
@ -257,7 +257,7 @@ proc fixupProcType(c: PContext, genericType: PType,
result.sons[i] = fixupProcType(c, result.sons[i], inst) result.sons[i] = fixupProcType(c, result.sons[i], inst)
result = instGenericContainer(c, getInfoContext(-1), result) result = instGenericContainer(c, getInfoContext(-1), result)
else: nil else: discard
proc generateInstance(c: PContext, fn: PSym, pt: TIdTable, proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
info: TLineInfo): PSym = info: TLineInfo): PSym =
@ -290,7 +290,7 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[]) instantiateGenericParamList(c, n.sons[genericParamsPos], pt, entry[])
result.typ = fixupProcType(c, fn.typ, entry[]) result.typ = fixupProcType(c, fn.typ, entry[])
n.sons[genericParamsPos] = ast.emptyNode n.sons[genericParamsPos] = ast.emptyNode
var oldPrc = GenericCacheGet(fn, entry[]) var oldPrc = genericCacheGet(fn, entry[])
if oldPrc == nil: if oldPrc == nil:
fn.procInstCache.safeAdd(entry) fn.procInstCache.safeAdd(entry)
c.generics.add(makeInstPair(fn, entry)) c.generics.add(makeInstPair(fn, entry))
@ -311,5 +311,3 @@ proc generateInstance(c: PContext, fn: PSym, pt: TIdTable,
c.friendModule = oldFriend c.friendModule = oldFriend
dec(c.InstCounter) dec(c.InstCounter)
if result.kind == skMethod: finishMethod(c, result) if result.kind == skMethod: finishMethod(c, result)

View file

@ -10,7 +10,7 @@
## this module does the semantic checking of statements ## this module does the semantic checking of statements
# included from sem.nim # included from sem.nim
var EnforceVoidContext = PType(kind: tyStmt) var enforceVoidContext = PType(kind: tyStmt)
proc semCommand(c: PContext, n: PNode): PNode = proc semCommand(c: PContext, n: PNode): PNode =
result = semExprNoType(c, n) result = semExprNoType(c, n)
@ -117,7 +117,7 @@ const
nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch, nkElse, nkStmtListExpr, nkTryStmt, nkFinally, nkExceptBranch,
nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr} nkElifBranch, nkElifExpr, nkElseExpr, nkBlockStmt, nkBlockExpr}
proc ImplicitlyDiscardable(n: PNode): bool = proc implicitlyDiscardable(n: PNode): bool =
var n = n var n = n
while n.kind in skipForDiscardable: n = n.lastSon while n.kind in skipForDiscardable: n = n.lastSon
result = isCallExpr(n) and n.sons[0].kind == nkSym and result = isCallExpr(n) and n.sons[0].kind == nkSym and
@ -197,7 +197,7 @@ proc semCase(c: PContext, n: PNode): PNode =
of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32: of tyInt..tyInt64, tyChar, tyEnum, tyUInt..tyUInt32:
chckCovered = true chckCovered = true
of tyFloat..tyFloat128, tyString, tyError: of tyFloat..tyFloat128, tyString, tyError:
nil discard
else: else:
LocalError(n.info, errSelectorMustBeOfCertainTypes) LocalError(n.info, errSelectorMustBeOfCertainTypes)
return return
@ -501,7 +501,7 @@ proc semForObjectFields(c: TFieldsCtx, typ, forLoop, father: PNode) =
father.add(SemStmt(c.c, body)) father.add(SemStmt(c.c, body))
dec c.c.InUnrolledContext dec c.c.InUnrolledContext
closeScope(c.c) closeScope(c.c)
of nkNilLit: nil of nkNilLit: discard
of nkRecCase: of nkRecCase:
let L = forLoop.len let L = forLoop.len
let call = forLoop.sons[L-2] let call = forLoop.sons[L-2]
@ -793,7 +793,7 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
st.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"), st.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
getCurrOwner(), s.info) getCurrOwner(), s.info)
proc SemTypeSection(c: PContext, n: PNode): PNode = proc semTypeSection(c: PContext, n: PNode): PNode =
typeSectionLeftSidePass(c, n) typeSectionLeftSidePass(c, n)
typeSectionRightSidePass(c, n) typeSectionRightSidePass(c, n)
typeSectionFinalPass(c, n) typeSectionFinalPass(c, n)

View file

@ -380,7 +380,7 @@ proc semTemplBodyDirty(c: var TemplCtx, n: PNode): PNode =
of nkBindStmt: of nkBindStmt:
result = semBindStmt(c.c, n, c.toBind) result = semBindStmt(c.c, n, c.toBind)
of nkEmpty, nkSym..nkNilLit: of nkEmpty, nkSym..nkNilLit:
nil discard
else: else:
# dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam', # dotExpr is ambiguous: note that we explicitely allow 'x.TemplateParam',
# so we use the generic code for nkDotExpr too # so we use the generic code for nkDotExpr too
@ -503,7 +503,7 @@ proc semPatternBody(c: var TemplCtx, n: PNode): PNode =
elif templToExpand(s): elif templToExpand(s):
result = semPatternBody(c, semTemplateExpr(c.c, n, s, false)) result = semPatternBody(c, semTemplateExpr(c.c, n, s, false))
else: else:
nil discard
# we keep the ident unbound for matching instantiated symbols and # we keep the ident unbound for matching instantiated symbols and
# more flexibility # more flexibility

View file

@ -356,7 +356,7 @@ proc semBranchRange(c: PContext, t, a, b: PNode, covered: var biggestInt): PNode
if emptyRange(ac, bc): LocalError(b.info, errRangeIsEmpty) if emptyRange(ac, bc): LocalError(b.info, errRangeIsEmpty)
else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1 else: covered = covered + getOrdValue(bc) - getOrdValue(ac) + 1
proc SemCaseBranchRange(c: PContext, t, b: PNode, proc semCaseBranchRange(c: PContext, t, b: PNode,
covered: var biggestInt): PNode = covered: var biggestInt): PNode =
checkSonsLen(b, 3) checkSonsLen(b, 3)
result = semBranchRange(c, t, b.sons[1], b.sons[2], covered) result = semBranchRange(c, t, b.sons[1], b.sons[2], covered)

View file

@ -68,9 +68,9 @@ type
symMap*: TIdTable # map PSym to PSym symMap*: TIdTable # map PSym to PSym
info*: TLineInfo info*: TLineInfo
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType proc replaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType
proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym
proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode
proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
result = copyNode(n) result = copyNode(n)
@ -81,13 +81,13 @@ proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode =
if i == 0: result.add(n[i]) if i == 0: result.add(n[i])
else: result.add(prepareNode(cl, n[i])) else: result.add(prepareNode(cl, n[i]))
proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
if n == nil: return if n == nil: return
result = copyNode(n) result = copyNode(n)
result.typ = ReplaceTypeVarsT(cl, n.typ) result.typ = ReplaceTypeVarsT(cl, n.typ)
case n.kind case n.kind
of nkNone..pred(nkSym), succ(nkSym)..nkNilLit: of nkNone..pred(nkSym), succ(nkSym)..nkNilLit:
nil discard
of nkSym: of nkSym:
result.sym = ReplaceTypeVarsS(cl, n.sym) result.sym = ReplaceTypeVarsS(cl, n.sym)
of nkRecWhen: of nkRecWhen:
@ -118,7 +118,7 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode =
for i in countup(0, length - 1): for i in countup(0, length - 1):
result.sons[i] = ReplaceTypeVarsN(cl, n.sons[i]) result.sons[i] = ReplaceTypeVarsN(cl, n.sons[i])
proc ReplaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym = proc replaceTypeVarsS(cl: var TReplTypeVars, s: PSym): PSym =
if s == nil: return nil if s == nil: return nil
result = PSym(idTableGet(cl.symMap, s)) result = PSym(idTableGet(cl.symMap, s))
if result == nil: if result == nil:
@ -192,11 +192,11 @@ proc handleGenericInvokation(cl: var TReplTypeVars, t: PType): PType =
rawAddSon(result, newbody) rawAddSon(result, newbody)
checkPartialConstructedType(cl.info, newbody) checkPartialConstructedType(cl.info, newbody)
proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType = proc replaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
result = t result = t
if t == nil: return if t == nil: return
case t.kind case t.kind
of tyTypeClass: nil of tyTypeClass: discard
of tyGenericParam: of tyGenericParam:
result = lookupTypeVar(cl, t) result = lookupTypeVar(cl, t)
if result.kind == tyGenericInvokation: if result.kind == tyGenericInvokation:
@ -235,11 +235,10 @@ proc ReplaceTypeVarsT*(cl: var TReplTypeVars, t: PType): PType =
proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode, proc generateTypeInstance*(p: PContext, pt: TIdTable, arg: PNode,
t: PType): PType = t: PType): PType =
var cl: TReplTypeVars var cl: TReplTypeVars
InitIdTable(cl.symMap) initIdTable(cl.symMap)
copyIdTable(cl.typeMap, pt) copyIdTable(cl.typeMap, pt)
cl.info = arg.info cl.info = arg.info
cl.c = p cl.c = p
pushInfoContext(arg.info) pushInfoContext(arg.info)
result = ReplaceTypeVarsT(cl, t) result = replaceTypeVarsT(cl, t)
popInfoContext() popInfoContext()

View file

@ -29,7 +29,7 @@ var
# the arguments to be passed to the program that # the arguments to be passed to the program that
# should be run # should be run
proc ProcessCmdLine*(pass: TCmdLinePass, cmd: string) = proc processCmdLine*(pass: TCmdLinePass, cmd: string) =
var p = parseopt.initOptParser(cmd) var p = parseopt.initOptParser(cmd)
var argsCount = 0 var argsCount = 0
while true: while true:

View file

@ -887,7 +887,7 @@ proc matchUserTypeClass*(c: PContext, m: var TCandidate,
result = arg result = arg
put(m.bindings, f, a) put(m.bindings, f, a)
proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType, proc paramTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType,
argSemantized, argOrig: PNode): PNode = argSemantized, argOrig: PNode): PNode =
var var
r: TTypeRelation r: TTypeRelation
@ -1003,7 +1003,7 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, argType: PType,
else: else:
result = userConvMatch(c, m, base(f), a, arg) result = userConvMatch(c, m, base(f), a, arg)
proc ParamTypesMatch*(c: PContext, m: var TCandidate, f, a: PType, proc paramTypesMatch*(c: PContext, m: var TCandidate, f, a: PType,
arg, argOrig: PNode): PNode = arg, argOrig: PNode): PNode =
if arg == nil or arg.kind notin nkSymChoices: if arg == nil or arg.kind notin nkSymChoices:
result = ParamTypesMatchAux(c, m, f, a, arg, argOrig) result = ParamTypesMatchAux(c, m, f, a, arg, argOrig)
@ -1184,14 +1184,14 @@ proc matchesAux(c: PContext, n, nOrig: PNode,
InternalError(n.sons[a].info, "matches") InternalError(n.sons[a].info, "matches")
return return
formal = m.callee.n.sons[f].sym formal = m.callee.n.sons[f].sym
if ContainsOrIncl(marker, formal.position): if containsOrIncl(marker, formal.position):
# already in namedParams: # already in namedParams:
LocalError(n.sons[a].info, errCannotBindXTwice, formal.name.s) localError(n.sons[a].info, errCannotBindXTwice, formal.name.s)
m.state = csNoMatch m.state = csNoMatch
return return
m.baseTypeMatch = false m.baseTypeMatch = false
n.sons[a] = prepareOperand(c, formal.typ, n.sons[a]) n.sons[a] = prepareOperand(c, formal.typ, n.sons[a])
var arg = ParamTypesMatch(c, m, formal.typ, n.sons[a].typ, var arg = paramTypesMatch(c, m, formal.typ, n.sons[a].typ,
n.sons[a], nOrig.sons[a]) n.sons[a], nOrig.sons[a])
if arg == nil: if arg == nil:
m.state = csNoMatch m.state = csNoMatch
@ -1228,7 +1228,7 @@ proc matches*(c: PContext, n, nOrig: PNode, m: var TCandidate) =
var f = 1 var f = 1
while f < sonsLen(m.callee.n): while f < sonsLen(m.callee.n):
var formal = m.callee.n.sons[f].sym var formal = m.callee.n.sons[f].sym
if not ContainsOrIncl(marker, formal.position): if not containsOrIncl(marker, formal.position):
if formal.ast == nil: if formal.ast == nil:
if formal.typ.kind == tyVarargs: if formal.typ.kind == tyVarargs:
var container = newNodeIT(nkBracket, n.info, arrayConstr(c, n.info)) var container = newNodeIT(nkBracket, n.info, arrayConstr(c, n.info))

View file

@ -28,7 +28,7 @@ proc origModuleName(m: PSym): string =
else: else:
m.name.s m.name.s
proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string = proc symToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string =
result = section result = section
result.add(sep) result.add(sep)
result.add($s.kind) result.add($s.kind)
@ -55,7 +55,7 @@ proc SymToStr(s: PSym, isLocal: bool, section: string, li: TLineInfo): string =
when not defined(noDocgen): when not defined(noDocgen):
result.add(s.extractDocComment.escape) result.add(s.extractDocComment.escape)
proc SymToStr(s: PSym, isLocal: bool, section: string): string = proc symToStr(s: PSym, isLocal: bool, section: string): string =
result = SymToStr(s, isLocal, section, s.info) result = SymToStr(s, isLocal, section, s.info)
proc filterSym(s: PSym): bool {.inline.} = proc filterSym(s: PSym): bool {.inline.} =

View file

@ -40,7 +40,7 @@ proc parseTopLevelStmt*(p: var TParsers): PNode
# implementation # implementation
proc ParseFile(fileIdx: int32): PNode = proc parseFile(fileIdx: int32): PNode =
var var
p: TParsers p: TParsers
f: tfile f: tfile
@ -74,7 +74,7 @@ proc parseTopLevelStmt(p: var TParsers): PNode =
result = ast.emptyNode result = ast.emptyNode
#skinEndX: result := pendx.parseTopLevelStmt(p.parser); #skinEndX: result := pendx.parseTopLevelStmt(p.parser);
proc UTF8_BOM(s: string): int = proc utf8Bom(s: string): int =
if (s[0] == '\xEF') and (s[1] == '\xBB') and (s[2] == '\xBF'): if (s[0] == '\xEF') and (s[1] == '\xBB') and (s[2] == '\xBF'):
result = 3 result = 3
else: else:
@ -92,7 +92,7 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
if s != nil: if s != nil:
var line = newStringOfCap(80) var line = newStringOfCap(80)
discard LLStreamReadLine(s, line) discard LLStreamReadLine(s, line)
var i = UTF8_Bom(line) var i = utf8Bom(line)
if containsShebang(line, i): if containsShebang(line, i):
discard LLStreamReadLine(s, line) discard LLStreamReadLine(s, line)
i = 0 i = 0
@ -100,20 +100,20 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
inc(i, 2) inc(i, 2)
while line[i] in WhiteSpace: inc(i) while line[i] in WhiteSpace: inc(i)
var q: TParser var q: TParser
OpenParser(q, filename, LLStreamOpen(substr(line, i))) openParser(q, filename, LLStreamOpen(substr(line, i)))
result = parser.parseAll(q) result = parser.parseAll(q)
CloseParser(q) closeParser(q)
LLStreamClose(s) LLStreamClose(s)
proc getFilter(ident: PIdent): TFilterKind = proc getFilter(ident: PIdent): TFilterKind =
for i in countup(low(TFilterKind), high(TFilterKind)): for i in countup(low(TFilterKind), high(TFilterKind)):
if IdentEq(ident, filterNames[i]): if identEq(ident, filterNames[i]):
return i return i
result = filtNone result = filtNone
proc getParser(ident: PIdent): TParserKind = proc getParser(ident: PIdent): TParserKind =
for i in countup(low(TParserKind), high(TParserKind)): for i in countup(low(TParserKind), high(TParserKind)):
if IdentEq(ident, parserNames[i]): if identEq(ident, parserNames[i]):
return i return i
rawMessage(errInvalidDirectiveX, ident.s) rawMessage(errInvalidDirectiveX, ident.s)
@ -142,15 +142,15 @@ proc applyFilter(p: var TParsers, n: PNode, filename: string,
if f != filtNone: if f != filtNone:
if gVerbosity >= 2: if gVerbosity >= 2:
rawMessage(hintCodeBegin, []) rawMessage(hintCodeBegin, [])
MsgWriteln(result.s) msgWriteln(result.s)
rawMessage(hintCodeEnd, []) rawMessage(hintCodeEnd, [])
proc evalPipe(p: var TParsers, n: PNode, filename: string, proc evalPipe(p: var TParsers, n: PNode, filename: string,
start: PLLStream): PLLStream = start: PLLStream): PLLStream =
result = start result = start
if n.kind == nkEmpty: return if n.kind == nkEmpty: return
if (n.kind == nkInfix) and (n.sons[0].kind == nkIdent) and if n.kind == nkInfix and n.sons[0].kind == nkIdent and
IdentEq(n.sons[0].ident, "|"): identEq(n.sons[0].ident, "|"):
for i in countup(1, 2): for i in countup(1, 2):
if n.sons[i].kind == nkInfix: if n.sons[i].kind == nkInfix:
result = evalPipe(p, n.sons[i], filename, result) result = evalPipe(p, n.sons[i], filename, result)

View file

@ -719,7 +719,7 @@ proc processTransf(c: PTransf, n: PNode, owner: PSym): PNode =
# Note: For interactive mode we cannot call 'passes.skipCodegen' and skip # Note: For interactive mode we cannot call 'passes.skipCodegen' and skip
# this step! We have to rely that the semantic pass transforms too errornous # this step! We have to rely that the semantic pass transforms too errornous
# nodes into an empty node. # nodes into an empty node.
if passes.skipCodegen(n) or c.fromCache or nfTransf in n.flags: return n if c.fromCache or nfTransf in n.flags: return n
pushTransCon(c, newTransCon(owner)) pushTransCon(c, newTransCon(owner))
result = PNode(transform(c, n)) result = PNode(transform(c, n))
popTransCon(c) popTransCon(c)

View file

@ -36,7 +36,7 @@ proc cyclicTree*(n: PNode): bool =
var s = newNodeI(nkEmpty, n.info) var s = newNodeI(nkEmpty, n.info)
result = cyclicTreeAux(n, s) result = cyclicTreeAux(n, s)
proc ExprStructuralEquivalent*(a, b: PNode): bool = proc exprStructuralEquivalent*(a, b: PNode): bool =
result = false result = false
if a == b: if a == b:
result = true result = true
@ -53,14 +53,14 @@ proc ExprStructuralEquivalent*(a, b: PNode): bool =
else: else:
if sonsLen(a) == sonsLen(b): if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
if not ExprStructuralEquivalent(a.sons[i], b.sons[i]): return if not exprStructuralEquivalent(a.sons[i], b.sons[i]): return
result = true result = true
proc sameTree*(a, b: PNode): bool = proc sameTree*(a, b: PNode): bool =
result = false result = false
if a == b: if a == b:
result = true result = true
elif (a != nil) and (b != nil) and (a.kind == b.kind): elif a != nil and b != nil and a.kind == b.kind:
if a.flags != b.flags: return if a.flags != b.flags: return
if a.info.line != b.info.line: return if a.info.line != b.info.line: return
if a.info.col != b.info.col: if a.info.col != b.info.col:
@ -84,10 +84,10 @@ proc getProcSym*(call: PNode): PSym =
result = call.sons[0].sym result = call.sons[0].sym
proc getOpSym*(op: PNode): PSym = proc getOpSym*(op: PNode): PSym =
if not (op.kind in {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}): if op.kind notin {nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit}:
result = nil result = nil
else: else:
if (sonsLen(op) <= 0): InternalError(op.info, "getOpSym") if sonsLen(op) <= 0: internalError(op.info, "getOpSym")
elif op.sons[0].Kind == nkSym: result = op.sons[0].sym elif op.sons[0].Kind == nkSym: result = op.sons[0].sym
else: result = nil else: result = nil
@ -99,7 +99,7 @@ proc getMagic*(op: PNode): TMagic =
else: result = mNone else: result = mNone
else: result = mNone else: result = mNone
proc TreeToSym*(t: PNode): PSym = proc treeToSym*(t: PNode): PSym =
result = t.sym result = t.sym
proc isConstExpr*(n: PNode): bool = proc isConstExpr*(n: PNode): bool =
@ -118,7 +118,7 @@ proc isDeepConstExpr*(n: PNode): bool =
for i in 0 .. <n.len: for i in 0 .. <n.len:
if not isDeepConstExpr(n.sons[i]): return false if not isDeepConstExpr(n.sons[i]): return false
result = true result = true
else: nil else: discard
proc flattenTreeAux(d, a: PNode, op: TMagic) = proc flattenTreeAux(d, a: PNode, op: TMagic) =
if (getMagic(a) == op): # a is a "leaf", so add it: if (getMagic(a) == op): # a is a "leaf", so add it:
@ -129,17 +129,17 @@ proc flattenTreeAux(d, a: PNode, op: TMagic) =
proc flattenTree*(root: PNode, op: TMagic): PNode = proc flattenTree*(root: PNode, op: TMagic): PNode =
result = copyNode(root) result = copyNode(root)
if (getMagic(root) == op): if getMagic(root) == op:
# BUGFIX: forget to copy prc # BUGFIX: forget to copy prc
addSon(result, copyNode(root.sons[0])) addSon(result, copyNode(root.sons[0]))
flattenTreeAux(result, root, op) flattenTreeAux(result, root, op)
proc SwapOperands*(op: PNode) = proc swapOperands*(op: PNode) =
var tmp = op.sons[1] var tmp = op.sons[1]
op.sons[1] = op.sons[2] op.sons[1] = op.sons[2]
op.sons[2] = tmp op.sons[2] = tmp
proc IsRange*(n: PNode): bool {.inline.} = proc isRange*(n: PNode): bool {.inline.} =
if n.kind == nkInfix: if n.kind == nkInfix:
if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or if n[0].kind == nkIdent and n[0].ident.id == ord(wDotDot) or
n[0].kind in {nkClosedSymChoice, nkOpenSymChoice} and n[0].kind in {nkClosedSymChoice, nkOpenSymChoice} and

View file

@ -17,7 +17,7 @@ proc hashTree(n: PNode): THash =
result = ord(n.kind) result = ord(n.kind)
case n.kind case n.kind
of nkEmpty, nkNilLit, nkType: of nkEmpty, nkNilLit, nkType:
nil discard
of nkIdent: of nkIdent:
result = result !& n.ident.h result = result !& n.ident.h
of nkSym: of nkSym:
@ -34,7 +34,7 @@ proc hashTree(n: PNode): THash =
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = result !& hashTree(n.sons[i]) result = result !& hashTree(n.sons[i])
proc TreesEquivalent(a, b: PNode): bool = proc treesEquivalent(a, b: PNode): bool =
if a == b: if a == b:
result = true result = true
elif (a != nil) and (b != nil) and (a.kind == b.kind): elif (a != nil) and (b != nil) and (a.kind == b.kind):
@ -48,24 +48,24 @@ proc TreesEquivalent(a, b: PNode): bool =
else: else:
if sonsLen(a) == sonsLen(b): if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
if not TreesEquivalent(a.sons[i], b.sons[i]): return if not treesEquivalent(a.sons[i], b.sons[i]): return
result = true result = true
if result: result = sameTypeOrNil(a.typ, b.typ) if result: result = sameTypeOrNil(a.typ, b.typ)
proc NodeTableRawGet(t: TNodeTable, k: THash, key: PNode): int = proc nodeTableRawGet(t: TNodeTable, k: THash, key: PNode): int =
var h: THash = k and high(t.data) var h: THash = k and high(t.data)
while t.data[h].key != nil: while t.data[h].key != nil:
if (t.data[h].h == k) and TreesEquivalent(t.data[h].key, key): if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
return h return h
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = -1 result = -1
proc NodeTableGet*(t: TNodeTable, key: PNode): int = proc nodeTableGet*(t: TNodeTable, key: PNode): int =
var index = NodeTableRawGet(t, hashTree(key), key) var index = nodeTableRawGet(t, hashTree(key), key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: result = low(int) else: result = low(int)
proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode, proc nodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode,
val: int) = val: int) =
var h: THash = k and high(data) var h: THash = k and high(data)
while data[h].key != nil: h = nextTry(h, high(data)) while data[h].key != nil: h = nextTry(h, high(data))
@ -74,7 +74,7 @@ proc NodeTableRawInsert(data: var TNodePairSeq, k: THash, key: PNode,
data[h].key = key data[h].key = key
data[h].val = val 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 n: TNodePairSeq
var k: THash = hashTree(key) var k: THash = hashTree(key)
var index = NodeTableRawGet(t, k, key) var index = NodeTableRawGet(t, k, key)
@ -86,15 +86,15 @@ proc NodeTablePut*(t: var TNodeTable, key: PNode, val: int) =
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].key != nil: if t.data[i].key != nil:
NodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
NodeTableRawInsert(t.data, k, key, val) nodeTableRawInsert(t.data, k, key, val)
inc(t.counter) 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 n: TNodePairSeq
var k: THash = hashTree(key) var k: THash = hashTree(key)
var index = NodeTableRawGet(t, k, key) var index = nodeTableRawGet(t, k, key)
if index >= 0: if index >= 0:
assert(t.data[index].key != nil) assert(t.data[index].key != nil)
result = t.data[index].val result = t.data[index].val
@ -103,8 +103,8 @@ proc NodeTableTestOrSet*(t: var TNodeTable, key: PNode, val: int): int =
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].key != nil: if t.data[i].key != nil:
NodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val) nodeTableRawInsert(n, t.data[i].h, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
NodeTableRawInsert(t.data, k, key, val) nodeTableRawInsert(t.data, k, key, val)
result = val result = val
inc(t.counter) inc(t.counter)

View file

@ -19,7 +19,7 @@ type
TPreferedDesc* = enum TPreferedDesc* = enum
preferName, preferDesc, preferExported preferName, preferDesc, preferExported
proc TypeToString*(typ: PType, prefer: TPreferedDesc = preferName): string proc typeToString*(typ: PType, prefer: TPreferedDesc = preferName): string
proc getProcHeader*(sym: PSym): string proc getProcHeader*(sym: PSym): string
proc base*(t: PType): PType proc base*(t: PType): PType
# ------------------- type iterator: ---------------------------------------- # ------------------- type iterator: ----------------------------------------
@ -28,7 +28,7 @@ type
TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it TTypeMutator* = proc (t: PType, closure: PObject): PType {.nimcall.} # copy t and mutate it
TTypePredicate* = proc (t: PType): bool {.nimcall.} TTypePredicate* = proc (t: PType): bool {.nimcall.}
proc IterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool proc iterOverType*(t: PType, iter: TTypeIter, closure: PObject): bool
# Returns result of `iter`. # Returns result of `iter`.
proc mutateType*(t: PType, iter: TTypeMutator, closure: PObject): PType proc mutateType*(t: PType, iter: TTypeMutator, closure: PObject): PType
# Returns result of `iter`. # Returns result of `iter`.
@ -74,7 +74,7 @@ proc getOrdValue*(n: PNode): biggestInt
proc computeSize*(typ: PType): biggestInt proc computeSize*(typ: PType): biggestInt
proc getSize*(typ: PType): biggestInt proc getSize*(typ: PType): biggestInt
proc isPureObject*(typ: PType): bool proc isPureObject*(typ: PType): bool
proc InvalidGenericInst*(f: PType): bool proc invalidGenericInst*(f: PType): bool
# for debugging # for debugging
type type
TTypeFieldResult* = enum TTypeFieldResult* = enum
@ -89,8 +89,8 @@ proc analyseObjectWithTypeField*(t: PType): TTypeFieldResult
proc typeAllowed*(t: PType, kind: TSymKind): bool proc typeAllowed*(t: PType, kind: TSymKind): bool
# implementation # implementation
proc InvalidGenericInst(f: PType): bool = proc invalidGenericInst(f: PType): bool =
result = (f.kind == tyGenericInst) and (lastSon(f) == nil) result = f.kind == tyGenericInst and lastSon(f) == nil
proc isPureObject(typ: PType): bool = proc isPureObject(typ: PType): bool =
var t = typ var t = typ
@ -132,7 +132,7 @@ proc getProcHeader(sym: PSym): string =
add(result, typeToString(p.sym.typ)) add(result, typeToString(p.sym.typ))
if i != sonsLen(n)-1: add(result, ", ") if i != sonsLen(n)-1: add(result, ", ")
else: else:
InternalError("getProcHeader") internalError("getProcHeader")
add(result, ')') add(result, ')')
if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ)) if n.sons[0].typ != nil: result.add(": " & typeToString(n.sons[0].typ))
@ -194,7 +194,7 @@ proc iterOverTypeAux(marker: var TIntSet, t: PType, iter: TTypeIter,
if result: return if result: return
if t.n != nil: result = iterOverNode(marker, t.n, iter, closure) if t.n != nil: result = iterOverNode(marker, t.n, iter, closure)
proc IterOverType(t: PType, iter: TTypeIter, closure: PObject): bool = proc iterOverType(t: PType, iter: TTypeIter, closure: PObject): bool =
var marker = InitIntSet() var marker = InitIntSet()
result = iterOverTypeAux(marker, t, iter, closure) result = iterOverTypeAux(marker, t, iter, closure)
@ -242,7 +242,7 @@ proc searchTypeForAux(t: PType, predicate: TTypePredicate,
result = searchTypeForAux(t.sons[i], predicate, marker) result = searchTypeForAux(t.sons[i], predicate, marker)
if result: return if result: return
else: else:
nil discard
proc searchTypeFor(t: PType, predicate: TTypePredicate): bool = proc searchTypeFor(t: PType, predicate: TTypePredicate): bool =
var marker = InitIntSet() var marker = InitIntSet()
@ -284,7 +284,7 @@ proc analyseObjectWithTypeFieldAux(t: PType,
if res != frNone: if res != frNone:
return frEmbedded return frEmbedded
else: else:
nil discard
proc analyseObjectWithTypeField(t: PType): TTypeFieldResult = proc analyseObjectWithTypeField(t: PType): TTypeFieldResult =
var marker = InitIntSet() var marker = InitIntSet()
@ -322,7 +322,7 @@ proc canFormAcycleNode(marker: var TIntSet, n: PNode, startId: int): bool =
if not result: if not result:
case n.kind case n.kind
of nkNone..nkNilLit: of nkNone..nkNilLit:
nil discard
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = canFormAcycleNode(marker, n.sons[i], startId) result = canFormAcycleNode(marker, n.sons[i], startId)
@ -367,6 +367,7 @@ proc mutateNode(marker: var TIntSet, n: PNode, iter: TTypeMutator,
case n.kind case n.kind
of nkNone..nkNilLit: of nkNone..nkNilLit:
# a leaf # a leaf
discard
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
addSon(result, mutateNode(marker, n.sons[i], iter, closure)) addSon(result, mutateNode(marker, n.sons[i], iter, closure))
@ -422,7 +423,7 @@ proc constraintsToStr(t: PType): string =
if i > 0: result.add(sep) if i > 0: result.add(sep)
result.add(t.sons[i].consToStr) result.add(t.sons[i].consToStr)
proc TypeToString(typ: PType, prefer: TPreferedDesc = preferName): string = proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
var t = typ var t = typ
result = "" result = ""
if t == nil: return if t == nil: return
@ -553,7 +554,7 @@ proc firstOrd(t: PType): biggestInt =
of tyGenericInst, tyDistinct, tyConst, tyMutable, tyTypeDesc: of tyGenericInst, tyDistinct, tyConst, tyMutable, tyTypeDesc:
result = firstOrd(lastSon(t)) result = firstOrd(lastSon(t))
else: else:
InternalError("invalid kind for first(" & $t.kind & ')') internalError("invalid kind for first(" & $t.kind & ')')
result = 0 result = 0
proc lastOrd(t: PType): biggestInt = proc lastOrd(t: PType): biggestInt =
@ -587,7 +588,7 @@ proc lastOrd(t: PType): biggestInt =
result = lastOrd(lastSon(t)) result = lastOrd(lastSon(t))
of tyProxy: result = 0 of tyProxy: result = 0
else: else:
InternalError("invalid kind for last(" & $t.kind & ')') internalError("invalid kind for last(" & $t.kind & ')')
result = 0 result = 0
proc lengthOrd(t: PType): biggestInt = proc lengthOrd(t: PType): biggestInt =
@ -621,7 +622,7 @@ type
proc initSameTypeClosure: TSameTypeClosure = proc initSameTypeClosure: TSameTypeClosure =
# we do the initialization lazily for performance (avoids memory allocations) # we do the initialization lazily for performance (avoids memory allocations)
nil discard
proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool = proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool =
result = not IsNil(c.s) and c.s.contains((a.id, b.id)) result = not IsNil(c.s) and c.s.contains((a.id, b.id))
@ -629,15 +630,15 @@ proc containsOrIncl(c: var TSameTypeClosure, a, b: PType): bool =
if IsNil(c.s): c.s = @[] if IsNil(c.s): c.s = @[]
c.s.add((a.id, b.id)) c.s.add((a.id, b.id))
proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool
proc SameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool = proc sameTypeOrNilAux(a, b: PType, c: var TSameTypeClosure): bool =
if a == b: if a == b:
result = true result = true
else: else:
if a == nil or b == nil: result = false if a == nil or b == nil: result = false
else: result = SameTypeAux(a, b, c) else: result = SameTypeAux(a, b, c)
proc SameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool = proc sameTypeOrNil*(a, b: PType, flags: TTypeCmpFlags = {}): bool =
if a == b: if a == b:
result = true result = true
else: else:
@ -676,7 +677,7 @@ proc equalParams(a, b: PNode): TParamsEquality =
of paramsNotEqual: of paramsNotEqual:
return paramsNotEqual return paramsNotEqual
of paramsEqual: of paramsEqual:
nil discard
of paramsIncompatible: of paramsIncompatible:
result = paramsIncompatible result = paramsIncompatible
if (m.name.id != n.name.id): if (m.name.id != n.name.id):
@ -730,7 +731,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
else: else:
result = false result = false
template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} = template ifFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} =
if tfFromGeneric notin a.flags + b.flags: if tfFromGeneric notin a.flags + b.flags:
# fast case: id comparison suffices: # fast case: id comparison suffices:
result = a.id == b.id result = a.id == b.id
@ -751,7 +752,7 @@ template IfFastObjectTypeCheckFailed(a, b: PType, body: stmt) {.immediate.} =
proc sameObjectTypes*(a, b: PType): bool = proc sameObjectTypes*(a, b: PType): bool =
# specialized for efficiency (sigmatch uses it) # specialized for efficiency (sigmatch uses it)
IfFastObjectTypeCheckFailed(a, b): ifFastObjectTypeCheckFailed(a, b):
var c = initSameTypeClosure() var c = initSameTypeClosure()
result = sameTypeAux(a, b, c) result = sameTypeAux(a, b, c)
@ -761,7 +762,7 @@ proc sameDistinctTypes*(a, b: PType): bool {.inline.} =
proc sameEnumTypes*(a, b: PType): bool {.inline.} = proc sameEnumTypes*(a, b: PType): bool {.inline.} =
result = a.id == b.id result = a.id == b.id
proc SameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool = proc sameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
if a == b: if a == b:
result = true result = true
elif (a != nil) and (b != nil) and (a.kind == b.kind): elif (a != nil) and (b != nil) and (a.kind == b.kind):
@ -778,26 +779,26 @@ proc SameObjectTree(a, b: PNode, c: var TSameTypeClosure): bool =
else: else:
if sonsLen(a) == sonsLen(b): if sonsLen(a) == sonsLen(b):
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
if not SameObjectTree(a.sons[i], b.sons[i], c): return if not sameObjectTree(a.sons[i], b.sons[i], c): return
result = true result = true
proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool = proc sameObjectStructures(a, b: PType, c: var TSameTypeClosure): bool =
# check base types: # check base types:
if sonsLen(a) != sonsLen(b): return if sonsLen(a) != sonsLen(b): return
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
if not SameTypeOrNilAux(a.sons[i], b.sons[i], c): return if not sameTypeOrNilAux(a.sons[i], b.sons[i], c): return
if not SameObjectTree(a.n, b.n, c): return if not sameObjectTree(a.n, b.n, c): return
result = true result = true
proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool = proc sameChildrenAux(a, b: PType, c: var TSameTypeClosure): bool =
if sonsLen(a) != sonsLen(b): return false if sonsLen(a) != sonsLen(b): return false
result = true result = true
for i in countup(0, sonsLen(a) - 1): for i in countup(0, sonsLen(a) - 1):
result = SameTypeOrNilAux(a.sons[i], b.sons[i], c) result = sameTypeOrNilAux(a.sons[i], b.sons[i], c)
if not result: return if not result: return
proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool = proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
template CycleCheck() = template cycleCheck() =
# believe it or not, the direct check for ``containsOrIncl(c, a, b)`` # believe it or not, the direct check for ``containsOrIncl(c, a, b)``
# increases bootstrapping time from 2.4s to 3.3s on my laptop! So we cheat # increases bootstrapping time from 2.4s to 3.3s on my laptop! So we cheat
# again: Since the recursion check is only to not get caught in an endless # again: Since the recursion check is only to not get caught in an endless
@ -831,16 +832,16 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
tyInt..tyBigNum, tyStmt: tyInt..tyBigNum, tyStmt:
result = sameFlags(a, b) result = sameFlags(a, b)
of tyExpr: of tyExpr:
result = ExprStructuralEquivalent(a.n, b.n) and sameFlags(a, b) result = exprStructuralEquivalent(a.n, b.n) and sameFlags(a, b)
of tyObject: of tyObject:
IfFastObjectTypeCheckFailed(a, b): ifFastObjectTypeCheckFailed(a, b):
CycleCheck() CycleCheck()
result = sameObjectStructures(a, b, c) and sameFlags(a, b) result = sameObjectStructures(a, b, c) and sameFlags(a, b)
of tyDistinct: of tyDistinct:
CycleCheck() cycleCheck()
if c.cmp == dcEq: if c.cmp == dcEq:
if sameFlags(a, b): if sameFlags(a, b):
IfFastObjectTypeCheckFailed(a, b): ifFastObjectTypeCheckFailed(a, b):
result = sameTypeAux(a.sons[0], b.sons[0], c) result = sameTypeAux(a.sons[0], b.sons[0], c)
else: else:
result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b) result = sameTypeAux(a.sons[0], b.sons[0], c) and sameFlags(a, b)
@ -848,14 +849,14 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
# XXX generic enums do not make much sense, but require structural checking # XXX generic enums do not make much sense, but require structural checking
result = a.id == b.id and sameFlags(a, b) result = a.id == b.id and sameFlags(a, b)
of tyTuple: of tyTuple:
CycleCheck() cycleCheck()
result = sameTuple(a, b, c) and sameFlags(a, b) result = sameTuple(a, b, c) and sameFlags(a, b)
of tyGenericInst: of tyGenericInst:
result = sameTypeAux(lastSon(a), lastSon(b), c) result = sameTypeAux(lastSon(a), lastSon(b), c)
of tyTypeDesc: of tyTypeDesc:
if c.cmp == dcEqIgnoreDistinct: result = false if c.cmp == dcEqIgnoreDistinct: result = false
elif TypeDescExactMatch in c.flags: elif TypeDescExactMatch in c.flags:
CycleCheck() cycleCheck()
result = sameChildrenAux(x, y, c) and sameFlags(a, b) result = sameChildrenAux(x, y, c) and sameFlags(a, b)
else: else:
result = sameFlags(a, b) result = sameFlags(a, b)
@ -863,15 +864,15 @@ proc SameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr, tyOpenArray, tySet, tyRef, tyPtr, tyVar, tyArrayConstr,
tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter, tyArray, tyProc, tyConst, tyMutable, tyVarargs, tyIter,
tyOrdinal, tyTypeClasses: tyOrdinal, tyTypeClasses:
CycleCheck() cycleCheck()
result = sameChildrenAux(a, b, c) and sameFlags(a, b) result = sameChildrenAux(a, b, c) and sameFlags(a, b)
if result and (a.kind == tyProc): if result and a.kind == tyProc:
result = a.callConv == b.callConv result = a.callConv == b.callConv
of tyRange: of tyRange:
CycleCheck() cycleCheck()
result = SameTypeOrNilAux(a.sons[0], b.sons[0], c) and result = sameTypeOrNilAux(a.sons[0], b.sons[0], c) and
SameValue(a.n.sons[0], b.n.sons[0]) and sameValue(a.n.sons[0], b.n.sons[0]) and
SameValue(a.n.sons[1], b.n.sons[1]) sameValue(a.n.sons[1], b.n.sons[1])
of tyNone: result = false of tyNone: result = false
proc sameType*(x, y: PType): bool = proc sameType*(x, y: PType): bool =
@ -954,7 +955,7 @@ proc typeAllowedNode(marker: var TIntSet, n: PNode, kind: TSymKind,
if result: if result:
case n.kind case n.kind
of nkNone..nkNilLit: of nkNone..nkNilLit:
nil discard
else: else:
for i in countup(0, sonsLen(n) - 1): for i in countup(0, sonsLen(n) - 1):
result = typeAllowedNode(marker, n.sons[i], kind, flags) result = typeAllowedNode(marker, n.sons[i], kind, flags)

View file

@ -109,7 +109,7 @@ template decodeBx(k: expr) {.immediate, dirty.} =
let rbx = instr.regBx - wordExcess let rbx = instr.regBx - wordExcess
ensureKind(k) ensureKind(k)
template move(a, b: expr) = system.shallowCopy(a, b) template move(a, b: expr) {.immediate, dirty.} = system.shallowCopy(a, b)
# XXX fix minor 'shallowCopy' overloading bug in compiler # XXX fix minor 'shallowCopy' overloading bug in compiler
proc moveConst(x, y: PNode) = proc moveConst(x, y: PNode) =

View file

@ -1295,7 +1295,7 @@ proc gen(c: PCtx; n: PNode; dest: var TDest) =
else: else:
dest = tmp0 dest = tmp0
of nkEmpty, nkCommentStmt, nkTypeSection, nkConstSection, nkPragma, of nkEmpty, nkCommentStmt, nkTypeSection, nkConstSection, nkPragma,
nkTemplateDef, nkIncludeStmt, nkImportStmt: nkTemplateDef, nkIncludeStmt, nkImportStmt, nkFromStmt:
unused(n, dest) unused(n, dest)
of nkStringToCString, nkCStringToString: of nkStringToCString, nkCStringToString:
gen(c, n.sons[0], dest) gen(c, n.sons[0], dest)

View file

@ -4574,6 +4574,8 @@ the support of destructors.
delegator pragma delegator pragma
---------------- ----------------
**Note**: The design of the delegator feature is subject to change.
The delegator pragma can be used to intercept and rewrite proc call and field The delegator pragma can be used to intercept and rewrite proc call and field
access attempts referring to previously undeclared symbol names. It can be used access attempts referring to previously undeclared symbol names. It can be used
to provide a fluent interface to objects lying outside the static confines of to provide a fluent interface to objects lying outside the static confines of

View file

@ -14,13 +14,13 @@
## wanted functionality. ## wanted functionality.
when defined(Windows): when defined(Windows):
proc ReadLineFromStdin*(prompt: string): TaintedString {. proc readLineFromStdin*(prompt: string): TaintedString {.
tags: [FReadIO, FWriteIO].} = tags: [FReadIO, FWriteIO].} =
## Reads a line from stdin. ## Reads a line from stdin.
stdout.write(prompt) stdout.write(prompt)
result = readLine(stdin) result = readLine(stdin)
proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
tags: [FReadIO, FWriteIO].} = tags: [FReadIO, FWriteIO].} =
## Reads a `line` from stdin. `line` must not be ## Reads a `line` from stdin. `line` must not be
## ``nil``! May throw an IO exception. ## ``nil``! May throw an IO exception.
@ -34,7 +34,7 @@ when defined(Windows):
else: else:
import readline, history import readline, history
proc ReadLineFromStdin*(prompt: string): TaintedString {. proc readLineFromStdin*(prompt: string): TaintedString {.
tags: [FReadIO, FWriteIO].} = tags: [FReadIO, FWriteIO].} =
var buffer = readline.readLine(prompt) var buffer = readline.readLine(prompt)
if isNil(buffer): quit(0) if isNil(buffer): quit(0)
@ -43,7 +43,7 @@ else:
add_history(buffer) add_history(buffer)
readline.free(buffer) readline.free(buffer)
proc ReadLineFromStdin*(prompt: string, line: var TaintedString): bool {. proc readLineFromStdin*(prompt: string, line: var TaintedString): bool {.
tags: [FReadIO, FWriteIO].} = tags: [FReadIO, FWriteIO].} =
var buffer = readline.readLine(prompt) var buffer = readline.readLine(prompt)
if isNil(buffer): quit(0) if isNil(buffer): quit(0)

View file

@ -120,11 +120,11 @@ proc renderRstToRst(d: var TRenderContext, n: PRstNode, result: var string) =
let oldLen = result.len let oldLen = result.len
renderRstSons(d, n, result) renderRstSons(d, n, result)
let HeadlineLen = result.len - oldLen let headlineLen = result.len - oldLen
result.add("\n") result.add("\n")
result.add(ind) result.add(ind)
result.add repeatChar(HeadlineLen, lvlToChar[n.level]) result.add repeatChar(headlineLen, lvlToChar[n.level])
of rnOverline: of rnOverline:
result.add("\n") result.add("\n")
result.add(ind) result.add(ind)

View file

@ -263,14 +263,14 @@ proc `<-`(a: var TIndexEntry, b: TIndexEntry) =
proc sortIndex(a: var openArray[TIndexEntry]) = proc sortIndex(a: var openArray[TIndexEntry]) =
# we use shellsort here; fast and simple # we use shellsort here; fast and simple
let N = len(a) let n = len(a)
var h = 1 var h = 1
while true: while true:
h = 3 * h + 1 h = 3 * h + 1
if h > N: break if h > n: break
while true: while true:
h = h div 3 h = h div 3
for i in countup(h, N - 1): for i in countup(h, n - 1):
var v: TIndexEntry var v: TIndexEntry
v <- a[i] v <- a[i]
var j = i var j = i

View file

@ -50,7 +50,7 @@ proc mustRehash(length, counter: int): bool {.inline.} =
proc nextTry(h, maxHash: THash): THash {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} =
result = ((5 * h) + 1) and maxHash result = ((5 * h) + 1) and maxHash
proc IntSetGet(t: TIntSet, key: int): PTrunk = proc intSetGet(t: TIntSet, key: int): PTrunk =
var h = key and t.max var 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:
@ -58,7 +58,7 @@ proc IntSetGet(t: TIntSet, key: int): PTrunk =
h = nextTry(h, t.max) h = nextTry(h, t.max)
result = nil result = nil
proc IntSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) = proc intSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) =
var h = desc.key and t.max var h = desc.key and t.max
while data[h] != nil: while data[h] != nil:
assert(data[h] != desc) assert(data[h] != desc)
@ -66,7 +66,7 @@ proc IntSetRawInsert(t: TIntSet, data: var TTrunkSeq, desc: PTrunk) =
assert(data[h] == nil) assert(data[h] == nil)
data[h] = desc data[h] = desc
proc IntSetEnlarge(t: var TIntSet) = proc intSetEnlarge(t: var TIntSet) =
var n: TTrunkSeq var n: TTrunkSeq
var oldMax = t.max var oldMax = t.max
t.max = ((t.max + 1) * 2) - 1 t.max = ((t.max + 1) * 2) - 1
@ -75,7 +75,7 @@ proc IntSetEnlarge(t: var TIntSet) =
if t.data[i] != nil: IntSetRawInsert(t, n, t.data[i]) if t.data[i] != nil: IntSetRawInsert(t, n, t.data[i])
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 = key and t.max var 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:

View file

@ -41,19 +41,19 @@ type
proc initSinglyLinkedList*[T](): TSinglyLinkedList[T] = proc initSinglyLinkedList*[T](): TSinglyLinkedList[T] =
## creates a new singly linked list that is empty. ## creates a new singly linked list that is empty.
nil discard
proc initDoublyLinkedList*[T](): TDoublyLinkedList[T] = proc initDoublyLinkedList*[T](): TDoublyLinkedList[T] =
## creates a new doubly linked list that is empty. ## creates a new doubly linked list that is empty.
nil discard
proc initSinglyLinkedRing*[T](): TSinglyLinkedRing[T] = proc initSinglyLinkedRing*[T](): TSinglyLinkedRing[T] =
## creates a new singly linked ring that is empty. ## creates a new singly linked ring that is empty.
nil discard
proc initDoublyLinkedRing*[T](): TDoublyLinkedRing[T] = proc initDoublyLinkedRing*[T](): TDoublyLinkedRing[T] =
## creates a new doubly linked ring that is empty. ## creates a new doubly linked ring that is empty.
nil discard
proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] = proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] =
## creates a new doubly linked node with the given `value`. ## creates a new doubly linked node with the given `value`.

View file

@ -85,7 +85,7 @@ template rawInsertImpl() {.dirty.} =
data[h].val = val data[h].val = val
data[h].slot = seFilled data[h].slot = seFilled
proc RawGet[A, B](t: TTable[A, B], key: A): int = proc rawGet[A, B](t: TTable[A, B], key: A): int =
rawGetImpl() rawGetImpl()
proc `[]`*[A, B](t: TTable[A, B], key: A): B = proc `[]`*[A, B](t: TTable[A, B], key: A): B =
@ -93,13 +93,13 @@ proc `[]`*[A, B](t: TTable[A, B], key: A): B =
## default empty value for the type `B` is returned ## default empty value for the type `B` is returned
## and no exception is raised. One can check with ``hasKey`` whether the key ## and no exception is raised. One can check with ``hasKey`` whether the key
## exists. ## exists.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
proc mget*[A, B](t: var TTable[A, B], key: A): var B = proc mget*[A, B](t: var TTable[A, B], key: A): var B =
## retrieves the value at ``t[key]``. The value can be modified. ## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: raise newException(EInvalidKey, "key not found: " & $key) else: raise newException(EInvalidKey, "key not found: " & $key)
@ -107,39 +107,39 @@ proc hasKey*[A, B](t: TTable[A, B], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B], proc rawInsert[A, B](t: var TTable[A, B], data: var TKeyValuePairSeq[A, B],
key: A, val: B) = key: A, val: B) =
rawInsertImpl() rawInsertImpl()
proc Enlarge[A, B](t: var TTable[A, B]) = proc enlarge[A, B](t: var TTable[A, B]) =
var n: TKeyValuePairSeq[A, B] var n: TKeyValuePairSeq[A, B]
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].slot == seFilled: RawInsert(t, n, t.data[i].key, t.data[i].val) if t.data[i].slot == seFilled: rawInsert(t, n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
template AddImpl() {.dirty.} = template addImpl() {.dirty.} =
if mustRehash(len(t.data), t.counter): Enlarge(t) if mustRehash(len(t.data), t.counter): enlarge(t)
RawInsert(t, t.data, key, val) rawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
template PutImpl() {.dirty.} = template putImpl() {.dirty.} =
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].val = val t.data[index].val = val
else: else:
AddImpl() addImpl()
when false: when false:
# not yet used: # not yet used:
template HasKeyOrPutImpl() {.dirty.} = template hasKeyOrPutImpl() {.dirty.} =
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].val = val t.data[index].val = val
result = true result = true
else: else:
if mustRehash(len(t.data), t.counter): Enlarge(t) if mustRehash(len(t.data), t.counter): enlarge(t)
RawInsert(t, t.data, key, val) rawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
result = false result = false
@ -149,11 +149,11 @@ proc `[]=`*[A, B](t: var TTable[A, B], key: A, val: B) =
proc add*[A, B](t: var TTable[A, B], key: A, val: B) = proc add*[A, B](t: var TTable[A, B], key: A, val: B) =
## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
AddImpl() addImpl()
proc del*[A, B](t: var TTable[A, B], key: A) = proc del*[A, B](t: var TTable[A, B], key: A) =
## deletes `key` from hash table `t`. ## deletes `key` from hash table `t`.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: if index >= 0:
t.data[index].slot = seDeleted t.data[index].slot = seDeleted
dec(t.counter) dec(t.counter)
@ -240,7 +240,7 @@ iterator mvalues*[A, B](t: var TOrderedTable[A, B]): var B =
forAllOrderedPairs: forAllOrderedPairs:
yield t.data[h].val yield t.data[h].val
proc RawGet[A, B](t: TOrderedTable[A, B], key: A): int = proc rawGet[A, B](t: TOrderedTable[A, B], key: A): int =
rawGetImpl() rawGetImpl()
proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B = proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B =
@ -248,13 +248,13 @@ proc `[]`*[A, B](t: TOrderedTable[A, B], key: A): B =
## default empty value for the type `B` is returned ## default empty value for the type `B` is returned
## and no exception is raised. One can check with ``hasKey`` whether the key ## and no exception is raised. One can check with ``hasKey`` whether the key
## exists. ## exists.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B = proc mget*[A, B](t: var TOrderedTable[A, B], key: A): var B =
## retrieves the value at ``t[key]``. The value can be modified. ## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: raise newException(EInvalidKey, "key not found: " & $key) else: raise newException(EInvalidKey, "key not found: " & $key)
@ -262,7 +262,7 @@ proc hasKey*[A, B](t: TOrderedTable[A, B], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert[A, B](t: var TOrderedTable[A, B], proc rawInsert[A, B](t: var TOrderedTable[A, B],
data: var TOrderedKeyValuePairSeq[A, B], data: var TOrderedKeyValuePairSeq[A, B],
key: A, val: B) = key: A, val: B) =
rawInsertImpl() rawInsertImpl()
@ -271,7 +271,7 @@ proc RawInsert[A, B](t: var TOrderedTable[A, B],
if t.last >= 0: data[t.last].next = h if t.last >= 0: data[t.last].next = h
t.last = h t.last = h
proc Enlarge[A, B](t: var TOrderedTable[A, B]) = proc enlarge[A, B](t: var TOrderedTable[A, B]) =
var n: TOrderedKeyValuePairSeq[A, B] var n: TOrderedKeyValuePairSeq[A, B]
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
var h = t.first var h = t.first
@ -280,7 +280,7 @@ proc Enlarge[A, B](t: var TOrderedTable[A, B]) =
while h >= 0: while h >= 0:
var nxt = t.data[h].next var nxt = t.data[h].next
if t.data[h].slot == seFilled: if t.data[h].slot == seFilled:
RawInsert(t, n, t.data[h].key, t.data[h].val) rawInsert(t, n, t.data[h].key, t.data[h].val)
h = nxt h = nxt
swap(t.data, n) swap(t.data, n)
@ -290,7 +290,7 @@ proc `[]=`*[A, B](t: var TOrderedTable[A, B], key: A, val: B) =
proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) = proc add*[A, B](t: var TOrderedTable[A, B], key: A, val: B) =
## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists. ## puts a new (key, value)-pair into `t` even if ``t[key]`` already exists.
AddImpl() addImpl()
proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] = proc initOrderedTable*[A, B](initialSize=64): TOrderedTable[A, B] =
## creates a new ordered hash table that is empty. ## creates a new ordered hash table that is empty.
@ -398,7 +398,7 @@ iterator mvalues*[A](t: TCountTable[A]): var int =
for h in 0..high(t.data): for h in 0..high(t.data):
if t.data[h].val != 0: yield t.data[h].val if t.data[h].val != 0: yield t.data[h].val
proc RawGet[A](t: TCountTable[A], key: A): int = proc rawGet[A](t: TCountTable[A], key: A): int =
var h: THash = hash(key) and high(t.data) # start with real hash value var h: THash = hash(key) and high(t.data) # start with real hash value
while t.data[h].val != 0: while t.data[h].val != 0:
if t.data[h].key == key: return h if t.data[h].key == key: return h
@ -409,13 +409,13 @@ proc `[]`*[A](t: TCountTable[A], key: A): int =
## retrieves the value at ``t[key]``. If `key` is not in `t`, ## retrieves the value at ``t[key]``. If `key` is not in `t`,
## 0 is returned. One can check with ``hasKey`` whether the key ## 0 is returned. One can check with ``hasKey`` whether the key
## exists. ## exists.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
proc mget*[A](t: var TCountTable[A], key: A): var int = proc mget*[A](t: var TCountTable[A], key: A): var int =
## retrieves the value at ``t[key]``. The value can be modified. ## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``EInvalidKey`` exception is raised. ## If `key` is not in `t`, the ``EInvalidKey`` exception is raised.
var index = RawGet(t, key) var index = rawGet(t, key)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
else: raise newException(EInvalidKey, "key not found: " & $key) else: raise newException(EInvalidKey, "key not found: " & $key)
@ -423,24 +423,24 @@ proc hasKey*[A](t: TCountTable[A], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]], proc rawInsert[A](t: TCountTable[A], data: var seq[tuple[key: A, val: int]],
key: A, val: int) = key: A, val: int) =
var h: THash = hash(key) and high(data) var h: THash = hash(key) and high(data)
while data[h].val != 0: h = nextTry(h, high(data)) while data[h].val != 0: h = nextTry(h, high(data))
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc Enlarge[A](t: var TCountTable[A]) = proc enlarge[A](t: var TCountTable[A]) =
var n: seq[tuple[key: A, val: int]] var n: seq[tuple[key: A, val: int]]
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
if t.data[i].val != 0: RawInsert(t, n, t.data[i].key, t.data[i].val) if t.data[i].val != 0: rawInsert(t, n, t.data[i].key, t.data[i].val)
swap(t.data, n) swap(t.data, n)
proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) = proc `[]=`*[A](t: var TCountTable[A], key: A, val: int) =
## puts a (key, value)-pair into `t`. `val` has to be positive. ## puts a (key, value)-pair into `t`. `val` has to be positive.
assert val > 0 assert val > 0
PutImpl() putImpl()
proc initCountTable*[A](initialSize=64): TCountTable[A] = proc initCountTable*[A](initialSize=64): TCountTable[A] =
## creates a new count table that is empty. ## creates a new count table that is empty.
@ -467,11 +467,11 @@ proc inc*[A](t: var TCountTable[A], key: A, val = 1) =
if index >= 0: if index >= 0:
inc(t.data[index].val, val) inc(t.data[index].val, val)
else: else:
if mustRehash(len(t.data), t.counter): Enlarge(t) if mustRehash(len(t.data), t.counter): enlarge(t)
RawInsert(t, t.data, key, val) rawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] = proc smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
## returns the largest (key,val)-pair. Efficiency: O(n) ## returns the largest (key,val)-pair. Efficiency: O(n)
assert t.len > 0 assert t.len > 0
var minIdx = 0 var minIdx = 0
@ -480,7 +480,7 @@ proc Smallest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
result.key = t.data[minIdx].key result.key = t.data[minIdx].key
result.val = t.data[minIdx].val result.val = t.data[minIdx].val
proc Largest*[A](t: TCountTable[A]): tuple[key: A, val: int] = proc largest*[A](t: TCountTable[A]): tuple[key: A, val: int] =
## returns the (key,val)-pair with the largest `val`. Efficiency: O(n) ## returns the (key,val)-pair with the largest `val`. Efficiency: O(n)
assert t.len > 0 assert t.len > 0
var maxIdx = 0 var maxIdx = 0

View file

@ -48,11 +48,11 @@ proc getCurrentLine*(L: TBaseLexer, marker: bool = true): string
proc getColNumber*(L: TBaseLexer, pos: int): int proc getColNumber*(L: TBaseLexer, pos: int): int
## retrieves the current column. ## retrieves the current column.
proc HandleCR*(L: var TBaseLexer, pos: int): int proc handleCR*(L: var TBaseLexer, pos: int): int
## Call this if you scanned over '\c' in the buffer; it returns the the ## Call this if you scanned over '\c' in the buffer; it returns the the
## position to continue the scanning from. `pos` must be the position ## position to continue the scanning from. `pos` must be the position
## of the '\c'. ## of the '\c'.
proc HandleLF*(L: var TBaseLexer, pos: int): int proc handleLF*(L: var TBaseLexer, pos: int): int
## Call this if you scanned over '\L' in the buffer; it returns the the ## Call this if you scanned over '\L' in the buffer; it returns the the
## position to continue the scanning from. `pos` must be the position ## position to continue the scanning from. `pos` must be the position
## of the '\L'. ## of the '\L'.
@ -66,7 +66,7 @@ proc close(L: var TBaseLexer) =
dealloc(L.buf) dealloc(L.buf)
close(L.input) close(L.input)
proc FillBuffer(L: var TBaseLexer) = proc fillBuffer(L: var TBaseLexer) =
var var
charsRead, toCopy, s: int # all are in characters, charsRead, toCopy, s: int # all are in characters,
# not bytes (in case this # not bytes (in case this
@ -78,7 +78,7 @@ proc FillBuffer(L: var TBaseLexer) =
toCopy = L.BufLen - L.sentinel - 1 toCopy = L.BufLen - L.sentinel - 1
assert(toCopy >= 0) assert(toCopy >= 0)
if toCopy > 0: if toCopy > 0:
MoveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize) moveMem(L.buf, addr(L.buf[L.sentinel + 1]), toCopy * chrSize)
# "moveMem" handles overlapping regions # "moveMem" handles overlapping regions
charsRead = readData(L.input, addr(L.buf[toCopy]), charsRead = readData(L.input, addr(L.buf[toCopy]),
(L.sentinel + 1) * chrSize) div chrSize (L.sentinel + 1) * chrSize) div chrSize
@ -103,7 +103,7 @@ proc FillBuffer(L: var TBaseLexer) =
L.bufLen = L.BufLen * 2 L.bufLen = L.BufLen * 2
L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize)) L.buf = cast[cstring](realloc(L.buf, L.bufLen * chrSize))
assert(L.bufLen - oldBuflen == oldBufLen) assert(L.bufLen - oldBuflen == oldBufLen)
charsRead = ReadData(L.input, addr(L.buf[oldBufLen]), charsRead = readData(L.input, addr(L.buf[oldBufLen]),
oldBufLen * chrSize) div chrSize oldBufLen * chrSize) div chrSize
if charsRead < oldBufLen: if charsRead < oldBufLen:
L.buf[oldBufLen + charsRead] = EndOfFile L.buf[oldBufLen + charsRead] = EndOfFile
@ -121,19 +121,19 @@ proc fillBaseLexer(L: var TBaseLexer, pos: int): int =
result = 0 result = 0
L.lineStart = result L.lineStart = result
proc HandleCR(L: var TBaseLexer, pos: int): int = proc handleCR(L: var TBaseLexer, pos: int): int =
assert(L.buf[pos] == '\c') assert(L.buf[pos] == '\c')
inc(L.linenumber) inc(L.linenumber)
result = fillBaseLexer(L, pos) result = fillBaseLexer(L, pos)
if L.buf[result] == '\L': if L.buf[result] == '\L':
result = fillBaseLexer(L, result) result = fillBaseLexer(L, result)
proc HandleLF(L: var TBaseLexer, pos: int): int = proc handleLF(L: var TBaseLexer, pos: int): int =
assert(L.buf[pos] == '\L') assert(L.buf[pos] == '\L')
inc(L.linenumber) inc(L.linenumber)
result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result; result = fillBaseLexer(L, pos) #L.lastNL := result-1; // BUGFIX: was: result;
proc skip_UTF_8_BOM(L: var TBaseLexer) = proc skipUtf8Bom(L: var TBaseLexer) =
if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'): if (L.buf[0] == '\xEF') and (L.buf[1] == '\xBB') and (L.buf[2] == '\xBF'):
inc(L.bufpos, 3) inc(L.bufpos, 3)
inc(L.lineStart, 3) inc(L.lineStart, 3)
@ -149,7 +149,7 @@ proc open(L: var TBaseLexer, input: PStream, bufLen: int = 8192) =
L.lineStart = 0 L.lineStart = 0
L.linenumber = 1 # lines start at 1 L.linenumber = 1 # lines start at 1
fillBuffer(L) fillBuffer(L)
skip_UTF_8_BOM(L) skipUtf8Bom(L)
proc getColNumber(L: TBaseLexer, pos: int): int = proc getColNumber(L: TBaseLexer, pos: int): int =
result = abs(pos - L.lineStart) result = abs(pos - L.lineStart)

View file

@ -93,11 +93,11 @@ when defined(Nimdoc): # only for proper documentation:
elif defined(macos): elif defined(macos):
const const
curdir* = ':' CurDir* = ':'
pardir* = "::" ParDir* = "::"
dirsep* = ':' Dirsep* = ':'
altsep* = dirsep Altsep* = dirsep
pathsep* = ',' Pathsep* = ','
FileSystemCaseSensitive* = false FileSystemCaseSensitive* = false
ExeExt* = "" ExeExt* = ""
ScriptExt* = "" ScriptExt* = ""
@ -123,42 +123,42 @@ elif defined(macos):
# grandparent etc. # grandparent etc.
elif doslike: elif doslike:
const const
curdir* = '.' Curdir* = '.'
pardir* = ".." Pardir* = ".."
dirsep* = '\\' # seperator within paths Dirsep* = '\\' # seperator within paths
altsep* = '/' Altsep* = '/'
pathSep* = ';' # seperator between paths PathSep* = ';' # seperator between paths
FileSystemCaseSensitive* = false FileSystemCaseSensitive* = false
ExeExt* = "exe" ExeExt* = "exe"
ScriptExt* = "bat" ScriptExt* = "bat"
DynlibFormat* = "$1.dll" DynlibFormat* = "$1.dll"
elif defined(PalmOS) or defined(MorphOS): elif defined(PalmOS) or defined(MorphOS):
const const
dirsep* = '/' Dirsep* = '/'
altsep* = dirsep Altsep* = dirsep
PathSep* = ';' PathSep* = ';'
pardir* = ".." Pardir* = ".."
FileSystemCaseSensitive* = false FileSystemCaseSensitive* = false
ExeExt* = "" ExeExt* = ""
ScriptExt* = "" ScriptExt* = ""
DynlibFormat* = "$1.prc" DynlibFormat* = "$1.prc"
elif defined(RISCOS): elif defined(RISCOS):
const const
dirsep* = '.' Dirsep* = '.'
altsep* = '.' Altsep* = '.'
pardir* = ".." # is this correct? Pardir* = ".." # is this correct?
pathSep* = ',' PathSep* = ','
FileSystemCaseSensitive* = true FileSystemCaseSensitive* = true
ExeExt* = "" ExeExt* = ""
ScriptExt* = "" ScriptExt* = ""
DynlibFormat* = "lib$1.so" DynlibFormat* = "lib$1.so"
else: # UNIX-like operating system else: # UNIX-like operating system
const const
curdir* = '.' Curdir* = '.'
pardir* = ".." Pardir* = ".."
dirsep* = '/' Dirsep* = '/'
altsep* = dirsep Altsep* = dirsep
pathSep* = ':' PathSep* = ':'
FileSystemCaseSensitive* = true FileSystemCaseSensitive* = true
ExeExt* = "" ExeExt* = ""
ScriptExt* = "" ScriptExt* = ""
@ -186,20 +186,20 @@ proc OSErrorMsg*(): string {.rtl, extern: "nos$1", deprecated.} =
result = "" result = ""
when defined(Windows): when defined(Windows):
var err = GetLastError() var err = getLastError()
if err != 0'i32: if err != 0'i32:
when useWinUnicode: when useWinUnicode:
var msgbuf: widecstring var msgbuf: widecstring
if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200, if formatMessageW(0x00000100 or 0x00001000 or 0x00000200,
nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: nil, err, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf result = $msgbuf
if msgbuf != nil: LocalFree(cast[pointer](msgbuf)) if msgbuf != nil: localFree(cast[pointer](msgbuf))
else: else:
var msgbuf: cstring var msgbuf: cstring
if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, if formatMessageA(0x00000100 or 0x00001000 or 0x00000200,
nil, err, 0, addr(msgbuf), 0, nil) != 0'i32: nil, err, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf result = $msgbuf
if msgbuf != nil: LocalFree(msgbuf) if msgbuf != nil: localFree(msgbuf)
if errno != 0'i32: if errno != 0'i32:
result = $os.strerror(errno) result = $os.strerror(errno)
@ -238,16 +238,16 @@ proc OSErrorMsg*(errorCode: TOSErrorCode): string =
if errorCode != TOSErrorCode(0'i32): if errorCode != TOSErrorCode(0'i32):
when useWinUnicode: when useWinUnicode:
var msgbuf: widecstring var msgbuf: widecstring
if FormatMessageW(0x00000100 or 0x00001000 or 0x00000200, if formatMessageW(0x00000100 or 0x00001000 or 0x00000200,
nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32: nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf result = $msgbuf
if msgbuf != nil: LocalFree(cast[pointer](msgbuf)) if msgbuf != nil: localFree(cast[pointer](msgbuf))
else: else:
var msgbuf: cstring var msgbuf: cstring
if FormatMessageA(0x00000100 or 0x00001000 or 0x00000200, if formatMessageA(0x00000100 or 0x00001000 or 0x00000200,
nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32: nil, errorCode.int32, 0, addr(msgbuf), 0, nil) != 0'i32:
result = $msgbuf result = $msgbuf
if msgbuf != nil: LocalFree(msgbuf) if msgbuf != nil: localFree(msgbuf)
else: else:
if errorCode != TOSErrorCode(0'i32): if errorCode != TOSErrorCode(0'i32):
result = $os.strerror(errorCode.int32) result = $os.strerror(errorCode.int32)
@ -287,7 +287,7 @@ proc OSLastError*(): TOSErrorCode =
result = TOSErrorCode(errno) result = TOSErrorCode(errno)
{.pop.} {.pop.}
proc UnixToNativePath*(path: string): string {. proc unixToNativePath*(path: string): string {.
noSideEffect, rtl, extern: "nos$1".} = noSideEffect, rtl, extern: "nos$1".} =
## Converts an UNIX-like path to a native one. ## Converts an UNIX-like path to a native one.
## ##
@ -340,16 +340,16 @@ when defined(windows):
template wrapBinary(varname, winApiProc, arg, arg2: expr) {.immediate.} = template wrapBinary(varname, winApiProc, arg, arg2: expr) {.immediate.} =
var varname = winApiProc(newWideCString(arg), arg2) var varname = winApiProc(newWideCString(arg), arg2)
proc FindFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle = proc findFirstFile(a: string, b: var TWIN32_FIND_DATA): THandle =
result = FindFirstFileW(newWideCString(a), b) result = findFirstFileW(newWideCString(a), b)
template FindNextFile(a, b: expr): expr = FindNextFileW(a, b) template findNextFile(a, b: expr): expr = findNextFileW(a, b)
template getCommandLine(): expr = getCommandLineW() template getCommandLine(): expr = getCommandLineW()
template getFilename(f: expr): expr = template getFilename(f: expr): expr =
$cast[WideCString](addr(f.cFilename[0])) $cast[WideCString](addr(f.cFilename[0]))
else: else:
template FindFirstFile(a, b: expr): expr = FindFirstFileA(a, b) template findFirstFile(a, b: expr): expr = findFirstFileA(a, b)
template FindNextFile(a, b: expr): expr = FindNextFileA(a, b) template findNextFile(a, b: expr): expr = findNextFileA(a, b)
template getCommandLine(): expr = getCommandLineA() template getCommandLine(): expr = getCommandLineA()
template getFilename(f: expr): expr = $f.cFilename template getFilename(f: expr): expr = $f.cFilename
@ -364,9 +364,9 @@ proc existsFile*(filename: string): bool {.rtl, extern: "nos$1",
## Returns true if the file exists, false otherwise. ## Returns true if the file exists, false otherwise.
when defined(windows): when defined(windows):
when useWinUnicode: when useWinUnicode:
wrapUnary(a, GetFileAttributesW, filename) wrapUnary(a, getFileAttributesW, filename)
else: else:
var a = GetFileAttributesA(filename) var a = getFileAttributesA(filename)
if a != -1'i32: if a != -1'i32:
result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32 result = (a and FILE_ATTRIBUTE_DIRECTORY) == 0'i32
else: else:
@ -378,9 +378,9 @@ proc existsDir*(dir: string): bool {.rtl, extern: "nos$1", tags: [FReadDir].} =
## is returned. ## is returned.
when defined(windows): when defined(windows):
when useWinUnicode: when useWinUnicode:
wrapUnary(a, GetFileAttributesW, dir) wrapUnary(a, getFileAttributesW, dir)
else: else:
var a = GetFileAttributesA(dir) var a = getFileAttributesA(dir)
if a != -1'i32: if a != -1'i32:
result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32 result = (a and FILE_ATTRIBUTE_DIRECTORY) != 0'i32
else: else:
@ -395,7 +395,7 @@ proc getLastModificationTime*(file: string): TTime {.rtl, extern: "nos$1".} =
return res.st_mtime return res.st_mtime
else: else:
var f: TWIN32_Find_Data var f: TWIN32_Find_Data
var h = findfirstFile(file, f) var h = findFirstFile(file, f)
if h == -1'i32: OSError(OSLastError()) if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime)) result = winTimeToUnixTime(rdFileTime(f.ftLastWriteTime))
findclose(h) findclose(h)
@ -408,7 +408,7 @@ proc getLastAccessTime*(file: string): TTime {.rtl, extern: "nos$1".} =
return res.st_atime return res.st_atime
else: else:
var f: TWIN32_Find_Data var f: TWIN32_Find_Data
var h = findfirstFile(file, f) var h = findFirstFile(file, f)
if h == -1'i32: OSError(OSLastError()) if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime)) result = winTimeToUnixTime(rdFileTime(f.ftLastAccessTime))
findclose(h) findclose(h)
@ -421,7 +421,7 @@ proc getCreationTime*(file: string): TTime {.rtl, extern: "nos$1".} =
return res.st_ctime return res.st_ctime
else: else:
var f: TWIN32_Find_Data var f: TWIN32_Find_Data
var h = findfirstFile(file, f) var h = findFirstFile(file, f)
if h == -1'i32: OSError(OSLastError()) if h == -1'i32: OSError(OSLastError())
result = winTimeToUnixTime(rdFileTime(f.ftCreationTime)) result = winTimeToUnixTime(rdFileTime(f.ftCreationTime))
findclose(h) findclose(h)
@ -437,12 +437,12 @@ proc getCurrentDir*(): string {.rtl, extern: "nos$1", tags: [].} =
when defined(windows): when defined(windows):
when useWinUnicode: when useWinUnicode:
var res = newWideCString("", bufsize) var res = newWideCString("", bufsize)
var L = GetCurrentDirectoryW(bufsize, res) var L = getCurrentDirectoryW(bufsize, res)
if L == 0'i32: OSError(OSLastError()) if L == 0'i32: OSError(OSLastError())
result = res$L result = res$L
else: else:
result = newString(bufsize) result = newString(bufsize)
var L = GetCurrentDirectoryA(bufsize, result) var L = getCurrentDirectoryA(bufsize, result)
if L == 0'i32: OSError(OSLastError()) if L == 0'i32: OSError(OSLastError())
setLen(result, L) setLen(result, L)
else: else:
@ -457,10 +457,10 @@ proc setCurrentDir*(newDir: string) {.inline, tags: [].} =
## `newDir` cannot been set. ## `newDir` cannot been set.
when defined(Windows): when defined(Windows):
when useWinUnicode: when useWinUnicode:
if SetCurrentDirectoryW(newWideCString(newDir)) == 0'i32: if setCurrentDirectoryW(newWideCString(newDir)) == 0'i32:
OSError(OSLastError()) OSError(OSLastError())
else: else:
if SetCurrentDirectoryA(newDir) == 0'i32: OSError(OSLastError()) if setCurrentDirectoryA(newDir) == 0'i32: OSError(OSLastError())
else: else:
if chdir(newDir) != 0'i32: OSError(OSLastError()) if chdir(newDir) != 0'i32: OSError(OSLastError())
@ -512,7 +512,7 @@ proc joinPath*(parts: varargs[string]): string {.noSideEffect,
result = joinPath(result, parts[i]) result = joinPath(result, parts[i])
proc `/` * (head, tail: string): string {.noSideEffect.} = proc `/` * (head, tail: string): string {.noSideEffect.} =
## The same as ``JoinPath(head, tail)`` ## The same as ``joinPath(head, tail)``
## ##
## Here are some examples for Unix: ## Here are some examples for Unix:
## ##
@ -526,7 +526,7 @@ proc `/` * (head, tail: string): string {.noSideEffect.} =
proc splitPath*(path: string): tuple[head, tail: string] {. proc splitPath*(path: string): tuple[head, tail: string] {.
noSideEffect, rtl, extern: "nos$1".} = noSideEffect, rtl, extern: "nos$1".} =
## Splits a directory into (head, tail), so that ## Splits a directory into (head, tail), so that
## ``JoinPath(head, tail) == path``. ## ``joinPath(head, tail) == path``.
## ##
## Examples: ## Examples:
## ##
@ -672,14 +672,14 @@ proc expandFilename*(filename: string): string {.rtl, extern: "nos$1",
when useWinUnicode: when useWinUnicode:
var unused: widecstring var unused: widecstring
var res = newWideCString("", bufsize div 2) var res = newWideCString("", bufsize div 2)
var L = GetFullPathNameW(newWideCString(filename), bufsize, res, unused) var L = getFullPathNameW(newWideCString(filename), bufsize, res, unused)
if L <= 0'i32 or L >= bufsize: if L <= 0'i32 or L >= bufsize:
OSError(OSLastError()) OSError(OSLastError())
result = res$L result = res$L
else: else:
var unused: cstring var unused: cstring
result = newString(bufsize) result = newString(bufsize)
var L = GetFullPathNameA(filename, bufsize, result, unused) var L = getFullPathNameA(filename, bufsize, result, unused)
if L <= 0'i32 or L >= bufsize: OSError(OSLastError()) if L <= 0'i32 or L >= bufsize: OSError(OSLastError())
setLen(result, L) setLen(result, L)
else: else:
@ -758,29 +758,29 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
when useWinUnicode: when useWinUnicode:
var p1 = newWideCString(path1) var p1 = newWideCString(path1)
var p2 = newWideCString(path2) var p2 = newWideCString(path2)
template OpenHandle(path: expr): expr = template openHandle(path: expr): expr =
CreateFileW(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or createFileW(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or
FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0)
var f1 = OpenHandle(p1) var f1 = openHandle(p1)
var f2 = OpenHandle(p2) var f2 = openHandle(p2)
else: else:
template OpenHandle(path: expr): expr = template openHandle(path: expr): expr =
CreateFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or createFileA(path, 0'i32, FILE_SHARE_DELETE or FILE_SHARE_READ or
FILE_SHARE_WRITE, nil, OPEN_EXISTING, FILE_SHARE_WRITE, nil, OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0) FILE_FLAG_BACKUP_SEMANTICS or FILE_ATTRIBUTE_NORMAL, 0)
var f1 = OpenHandle(path1) var f1 = openHandle(path1)
var f2 = OpenHandle(path2) var f2 = openHandle(path2)
var lastErr: TOSErrorCode var lastErr: TOSErrorCode
if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE: if f1 != INVALID_HANDLE_VALUE and f2 != INVALID_HANDLE_VALUE:
var fi1, fi2: TBY_HANDLE_FILE_INFORMATION var fi1, fi2: TBY_HANDLE_FILE_INFORMATION
if GetFileInformationByHandle(f1, addr(fi1)) != 0 and if getFileInformationByHandle(f1, addr(fi1)) != 0 and
GetFileInformationByHandle(f2, addr(fi2)) != 0: getFileInformationByHandle(f2, addr(fi2)) != 0:
result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and result = fi1.dwVolumeSerialNumber == fi2.dwVolumeSerialNumber and
fi1.nFileIndexHigh == fi2.nFileIndexHigh and fi1.nFileIndexHigh == fi2.nFileIndexHigh and
fi1.nFileIndexLow == fi2.nFileIndexLow fi1.nFileIndexLow == fi2.nFileIndexLow
@ -791,8 +791,8 @@ proc sameFile*(path1, path2: string): bool {.rtl, extern: "nos$1",
lastErr = OSLastError() lastErr = OSLastError()
success = false success = false
discard CloseHandle(f1) discard closeHandle(f1)
discard CloseHandle(f2) discard closeHandle(f2)
if not success: OSError(lastErr) if not success: OSError(lastErr)
else: else:
@ -867,9 +867,9 @@ proc getFilePermissions*(filename: string): set[TFilePermission] {.
if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec) if (a.st_mode and S_IXOTH) != 0'i32: result.incl(fpOthersExec)
else: else:
when useWinUnicode: when useWinUnicode:
wrapUnary(res, GetFileAttributesW, filename) wrapUnary(res, getFileAttributesW, filename)
else: else:
var res = GetFileAttributesA(filename) var res = getFileAttributesA(filename)
if res == -1'i32: OSError(OSLastError()) if res == -1'i32: OSError(OSLastError())
if (res and FILE_ATTRIBUTE_READONLY) != 0'i32: if (res and FILE_ATTRIBUTE_READONLY) != 0'i32:
result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead, result = {fpUserExec, fpUserRead, fpGroupExec, fpGroupRead,
@ -899,18 +899,18 @@ proc setFilePermissions*(filename: string, permissions: set[TFilePermission]) {.
if chmod(filename, p) != 0: OSError(OSLastError()) if chmod(filename, p) != 0: OSError(OSLastError())
else: else:
when useWinUnicode: when useWinUnicode:
wrapUnary(res, GetFileAttributesW, filename) wrapUnary(res, getFileAttributesW, filename)
else: else:
var res = GetFileAttributesA(filename) var res = getFileAttributesA(filename)
if res == -1'i32: OSError(OSLastError()) if res == -1'i32: OSError(OSLastError())
if fpUserWrite in permissions: if fpUserWrite in permissions:
res = res and not FILE_ATTRIBUTE_READONLY res = res and not FILE_ATTRIBUTE_READONLY
else: else:
res = res or FILE_ATTRIBUTE_READONLY res = res or FILE_ATTRIBUTE_READONLY
when useWinUnicode: when useWinUnicode:
wrapBinary(res2, SetFileAttributesW, filename, res) wrapBinary(res2, setFileAttributesW, filename, res)
else: else:
var res2 = SetFileAttributesA(filename, res) var res2 = setFileAttributesA(filename, res)
if res2 == - 1'i32: OSError(OSLastError()) if res2 == - 1'i32: OSError(OSLastError())
proc copyFile*(source, dest: string) {.rtl, extern: "nos$1", proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
@ -928,9 +928,9 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
when useWinUnicode: when useWinUnicode:
let s = newWideCString(source) let s = newWideCString(source)
let d = newWideCString(dest) let d = newWideCString(dest)
if CopyFileW(s, d, 0'i32) == 0'i32: OSError(OSLastError()) if copyFileW(s, d, 0'i32) == 0'i32: OSError(OSLastError())
else: else:
if CopyFileA(source, dest, 0'i32) == 0'i32: OSError(OSLastError()) if copyFileA(source, dest, 0'i32) == 0'i32: OSError(OSLastError())
else: else:
# generic version of copyFile which works for any platform: # generic version of copyFile which works for any platform:
const bufSize = 8000 # better for memory manager const bufSize = 8000 # better for memory manager
@ -940,7 +940,7 @@ proc copyFile*(source, dest: string) {.rtl, extern: "nos$1",
close(s) close(s)
OSError(OSLastError()) OSError(OSLastError())
var buf = alloc(bufsize) var buf = alloc(bufsize)
while True: while true:
var bytesread = readBuffer(s, buf, bufsize) var bytesread = readBuffer(s, buf, bufsize)
if bytesread > 0: if bytesread > 0:
var byteswritten = writeBuffer(d, buf, bytesread) var byteswritten = writeBuffer(d, buf, bytesread)
@ -968,13 +968,13 @@ when not defined(ENOENT) and not defined(Windows):
when defined(Windows): when defined(Windows):
when useWinUnicode: when useWinUnicode:
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileW(file) template deleteFile(file: expr): expr {.immediate.} = deleteFileW(file)
template SetFileAttributes(file, attrs: expr): expr {.immediate.} = template setFileAttributes(file, attrs: expr): expr {.immediate.} =
SetFileAttributesW(file, attrs) setFileAttributesW(file, attrs)
else: else:
template DeleteFile(file: expr): expr {.immediate.} = DeleteFileA(file) template deleteFile(file: expr): expr {.immediate.} = deleteFileA(file)
template SetFileAttributes(file, attrs: expr): expr {.immediate.} = template setFileAttributes(file, attrs: expr): expr {.immediate.} =
SetFileAttributesA(file, attrs) setFileAttributesA(file, attrs)
proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
## Removes the `file`. If this fails, `EOS` is raised. This does not fail ## Removes the `file`. If this fails, `EOS` is raised. This does not fail
@ -985,11 +985,11 @@ proc removeFile*(file: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
let f = newWideCString(file) let f = newWideCString(file)
else: else:
let f = file let f = file
if DeleteFile(f) == 0: if deleteFile(f) == 0:
if GetLastError() == ERROR_ACCESS_DENIED: if getLastError() == ERROR_ACCESS_DENIED:
if SetFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0: if setFileAttributes(f, FILE_ATTRIBUTE_NORMAL) == 0:
OSError(OSLastError()) OSError(OSLastError())
if DeleteFile(f) == 0: if deleteFile(f) == 0:
OSError(OSLastError()) OSError(OSLastError())
else: else:
if cremove(file) != 0'i32 and errno != ENOENT: if cremove(file) != 0'i32 and errno != ENOENT:
@ -1076,7 +1076,7 @@ else:
when useNSGetEnviron: when useNSGetEnviron:
var gEnv = NSGetEnviron()[] var gEnv = NSGetEnviron()[]
var i = 0 var i = 0
while True: while true:
if gEnv[i] == nil: break if gEnv[i] == nil: break
add environment, $gEnv[i] add environment, $gEnv[i]
inc(i) inc(i)
@ -1130,9 +1130,9 @@ proc putEnv*(key, val: string) {.tags: [FWriteEnv].} =
when useWinUnicode: when useWinUnicode:
var k = newWideCString(key) var k = newWideCString(key)
var v = newWideCString(val) var v = newWideCString(val)
if SetEnvironmentVariableW(k, v) == 0'i32: OSError(OSLastError()) if setEnvironmentVariableW(k, v) == 0'i32: OSError(OSLastError())
else: else:
if SetEnvironmentVariableA(key, val) == 0'i32: OSError(OSLastError()) if setEnvironmentVariableA(key, val) == 0'i32: OSError(OSLastError())
iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} = iterator envPairs*(): tuple[key, value: TaintedString] {.tags: [FReadEnv].} =
## Iterate over all `environments variables`:idx:. In the first component ## Iterate over all `environments variables`:idx:. In the first component
@ -1259,9 +1259,9 @@ iterator walkDirRec*(dir: string, filter={pcFile, pcDir}): string {.
proc rawRemoveDir(dir: string) = proc rawRemoveDir(dir: string) =
when defined(windows): when defined(windows):
when useWinUnicode: when useWinUnicode:
wrapUnary(res, RemoveDirectoryW, dir) wrapUnary(res, removeDirectoryW, dir)
else: else:
var res = RemoveDirectoryA(dir) var res = removeDirectoryA(dir)
let lastError = OSLastError() let lastError = OSLastError()
if res == 0'i32 and lastError.int32 != 3'i32 and if res == 0'i32 and lastError.int32 != 3'i32 and
lastError.int32 != 18'i32 and lastError.int32 != 2'i32: lastError.int32 != 18'i32 and lastError.int32 != 2'i32:
@ -1291,10 +1291,10 @@ proc rawCreateDir(dir: string) =
OSError(OSLastError()) OSError(OSLastError())
else: else:
when useWinUnicode: when useWinUnicode:
wrapUnary(res, CreateDirectoryW, dir) wrapUnary(res, createDirectoryW, dir)
else: else:
var res = CreateDirectoryA(dir) var res = createDirectoryA(dir)
if res == 0'i32 and GetLastError() != 183'i32: if res == 0'i32 and getLastError() != 183'i32:
OSError(OSLastError()) OSError(OSLastError())
proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} = proc createDir*(dir: string) {.rtl, extern: "nos$1", tags: [FWriteDir].} =
@ -1584,8 +1584,8 @@ proc getAppFilename*(): string {.rtl, extern: "nos$1", tags: [FReadIO].} =
if len(result) > 0 and result[0] != DirSep: # not an absolute path? if len(result) > 0 and result[0] != DirSep: # not an absolute path?
# iterate over any path in the $PATH environment variable # iterate over any path in the $PATH environment variable
for p in split(string(getEnv("PATH")), {PathSep}): for p in split(string(getEnv("PATH")), {PathSep}):
var x = JoinPath(p, result) var x = joinPath(p, result)
if ExistsFile(x): return x if existsFile(x): return x
proc getApplicationFilename*(): string {.rtl, extern: "nos$1", deprecated.} = proc getApplicationFilename*(): string {.rtl, extern: "nos$1", deprecated.} =
## Returns the filename of the application's executable. ## Returns the filename of the application's executable.
@ -1636,11 +1636,11 @@ proc findExe*(exe: string): string {.tags: [FReadDir, FReadEnv].} =
## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe` ## Returns "" if the `exe` cannot be found. On DOS-like platforms, `exe`
## is added an ``.exe`` file extension if it has no extension. ## is added an ``.exe`` file extension if it has no extension.
result = addFileExt(exe, os.exeExt) result = addFileExt(exe, os.exeExt)
if ExistsFile(result): return if existsFile(result): return
var path = string(os.getEnv("PATH")) var path = string(os.getEnv("PATH"))
for candidate in split(path, pathSep): for candidate in split(path, pathSep):
var x = candidate / result var x = candidate / result
if ExistsFile(x): return x if existsFile(x): return x
result = "" result = ""
proc expandTilde*(path: string): string = proc expandTilde*(path: string): string =

View file

@ -383,16 +383,16 @@ when defined(Windows) and not defined(useNimRtl):
# O_WRONLY {.importc: "_O_WRONLY", header: "<fcntl.h>".}: int # O_WRONLY {.importc: "_O_WRONLY", header: "<fcntl.h>".}: int
# O_RDONLY {.importc: "_O_RDONLY", header: "<fcntl.h>".}: int # O_RDONLY {.importc: "_O_RDONLY", header: "<fcntl.h>".}: int
proc CreatePipeHandles(Rdhandle, WrHandle: var THandle) = proc createPipeHandles(Rdhandle, WrHandle: var THandle) =
var piInheritablePipe: TSecurityAttributes var piInheritablePipe: TSecurityAttributes
piInheritablePipe.nlength = SizeOF(TSecurityAttributes).cint piInheritablePipe.nlength = SizeOf(TSecurityAttributes).cint
piInheritablePipe.lpSecurityDescriptor = nil piInheritablePipe.lpSecurityDescriptor = nil
piInheritablePipe.Binherithandle = 1 piInheritablePipe.Binherithandle = 1
if CreatePipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32: if createPipe(Rdhandle, Wrhandle, piInheritablePipe, 1024) == 0'i32:
OSError(OSLastError()) OSError(OSLastError())
proc fileClose(h: THandle) {.inline.} = proc fileClose(h: THandle) {.inline.} =
if h > 4: discard CloseHandle(h) if h > 4: discard closeHandle(h)
proc startProcess(command: string, proc startProcess(command: string,
workingDir: string = "", workingDir: string = "",
@ -400,8 +400,8 @@ when defined(Windows) and not defined(useNimRtl):
env: PStringTable = nil, env: PStringTable = nil,
options: set[TProcessOption] = {poStdErrToStdOut}): PProcess = options: set[TProcessOption] = {poStdErrToStdOut}): PProcess =
var var
SI: TStartupInfo si: TStartupInfo
ProcInfo: TProcessInformation procInfo: TProcessInformation
success: int success: int
hi, ho, he: THandle hi, ho, he: THandle
new(result) new(result)
@ -511,8 +511,8 @@ when defined(Windows) and not defined(useNimRtl):
proc execCmd(command: string): int = proc execCmd(command: string): int =
var var
SI: TStartupInfo si: TStartupInfo
ProcInfo: TProcessInformation procInfo: TProcessInformation
process: THandle process: THandle
L: int32 L: int32
SI.cb = SizeOf(SI).cint SI.cb = SizeOf(SI).cint

View file

@ -51,7 +51,7 @@ proc parseHex*(s: string, number: var int, start = 0): int {.
elif s[i] == '#': inc(i) elif s[i] == '#': inc(i)
while true: while true:
case s[i] case s[i]
of '_': nil of '_': discard
of '0'..'9': of '0'..'9':
number = number shl 4 or (ord(s[i]) - ord('0')) number = number shl 4 or (ord(s[i]) - ord('0'))
foundDigit = true foundDigit = true
@ -74,7 +74,7 @@ proc parseOct*(s: string, number: var int, start = 0): int {.
if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2) if s[i] == '0' and (s[i+1] == 'o' or s[i+1] == 'O'): inc(i, 2)
while true: while true:
case s[i] case s[i]
of '_': nil of '_': discard
of '0'..'7': of '0'..'7':
number = number shl 3 or (ord(s[i]) - ord('0')) number = number shl 3 or (ord(s[i]) - ord('0'))
foundDigit = true foundDigit = true

View file

@ -132,17 +132,17 @@ type
ETimeout* = object of ESynch ETimeout* = object of ESynch
let let
InvalidSocket*: TSocket = nil ## invalid socket invalidSocket*: TSocket = nil ## invalid socket
when defined(windows): when defined(windows):
let let
OSInvalidSocket = winlean.INVALID_SOCKET osInvalidSocket = winlean.INVALID_SOCKET
else: else:
let let
OSInvalidSocket = posix.INVALID_SOCKET osInvalidSocket = posix.INVALID_SOCKET
proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket = proc newTSocket(fd: TSocketHandle, isBuff: bool): TSocket =
if fd == OSInvalidSocket: if fd == osInvalidSocket:
return nil return nil
new(result) new(result)
result.fd = fd result.fd = fd
@ -187,14 +187,14 @@ proc htons*(x: int16): int16 =
result = sockets.ntohs(x) result = sockets.ntohs(x)
when defined(Posix): when defined(Posix):
proc ToInt(domain: TDomain): cint = proc toInt(domain: TDomain): cint =
case domain case domain
of AF_UNIX: result = posix.AF_UNIX of AF_UNIX: result = posix.AF_UNIX
of AF_INET: result = posix.AF_INET of AF_INET: result = posix.AF_INET
of AF_INET6: result = posix.AF_INET6 of AF_INET6: result = posix.AF_INET6
else: nil else: nil
proc ToInt(typ: TType): cint = proc toInt(typ: TType): cint =
case typ case typ
of SOCK_STREAM: result = posix.SOCK_STREAM of SOCK_STREAM: result = posix.SOCK_STREAM
of SOCK_DGRAM: result = posix.SOCK_DGRAM of SOCK_DGRAM: result = posix.SOCK_DGRAM
@ -202,7 +202,7 @@ when defined(Posix):
of SOCK_RAW: result = posix.SOCK_RAW of SOCK_RAW: result = posix.SOCK_RAW
else: nil else: nil
proc ToInt(p: TProtocol): cint = proc toInt(p: TProtocol): cint =
case p case p
of IPPROTO_TCP: result = posix.IPPROTO_TCP of IPPROTO_TCP: result = posix.IPPROTO_TCP
of IPPROTO_UDP: result = posix.IPPROTO_UDP of IPPROTO_UDP: result = posix.IPPROTO_UDP
@ -216,10 +216,10 @@ else:
proc toInt(domain: TDomain): cint = proc toInt(domain: TDomain): cint =
result = toU16(ord(domain)) result = toU16(ord(domain))
proc ToInt(typ: TType): cint = proc toInt(typ: TType): cint =
result = cint(ord(typ)) result = cint(ord(typ))
proc ToInt(p: TProtocol): cint = proc toInt(p: TProtocol): cint =
result = cint(ord(p)) result = cint(ord(p))
proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM, proc socket*(domain: TDomain = AF_INET, typ: TType = SOCK_STREAM,
@ -333,7 +333,7 @@ when defined(ssl):
if SSLSetFd(socket.sslHandle, socket.fd) != 1: if SSLSetFd(socket.sslHandle, socket.fd) != 1:
SSLError() SSLError()
proc SocketError*(socket: TSocket, err: int = -1, async = false) = proc socketError*(socket: TSocket, err: int = -1, async = false) =
## Raises proper errors based on return values of ``recv`` functions. ## Raises proper errors based on return values of ``recv`` functions.
## ##
## If ``async`` is ``True`` no error will be thrown in the case when the ## If ``async`` is ``True`` no error will be thrown in the case when the
@ -471,7 +471,7 @@ template acceptAddrPlain(noClientRet, successRet: expr,
var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)), var sock = accept(server.fd, cast[ptr TSockAddr](addr(sockAddress)),
addr(addrLen)) addr(addrLen))
if sock == OSInvalidSocket: if sock == osInvalidSocket:
let err = OSLastError() let err = OSLastError()
when defined(windows): when defined(windows):
if err.int32 == WSAEINPROGRESS: if err.int32 == WSAEINPROGRESS:
@ -1661,7 +1661,7 @@ when defined(Windows):
proc setBlocking(s: TSocket, blocking: bool) = proc setBlocking(s: TSocket, blocking: bool) =
when defined(Windows): when defined(Windows):
var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking var mode = clong(ord(not blocking)) # 1 for non-blocking, 0 for blocking
if ioctlsocket(TSocketHandle(s.fd), FIONBIO, addr(mode)) == -1: if ioctlsocket(s.fd, FIONBIO, addr(mode)) == -1:
OSError(OSLastError()) OSError(OSLastError())
else: # BSD sockets else: # BSD sockets
var x: int = fcntl(s.fd, F_GETFL, 0) var x: int = fcntl(s.fd, F_GETFL, 0)

View file

@ -88,7 +88,7 @@ proc mustRehash(length, counter: int): bool =
proc nextTry(h, maxHash: THash): THash {.inline.} = proc nextTry(h, maxHash: THash): THash {.inline.} =
result = ((5 * h) + 1) and maxHash result = ((5 * h) + 1) and maxHash
proc RawGet(t: PStringTable, key: string): int = proc rawGet(t: PStringTable, key: string): int =
var h: THash = myhash(t, key) and high(t.data) # start with real hash value var h: THash = myhash(t, key) and high(t.data) # start with real hash value
while not isNil(t.data[h].key): while not isNil(t.data[h].key):
if mycmp(t, t.data[h].key, key): if mycmp(t, t.data[h].key, key):
@ -116,14 +116,14 @@ proc hasKey*(t: PStringTable, key: string): bool {.rtl, extern: "nst$1".} =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0 result = rawGet(t, key) >= 0
proc RawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) = proc rawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) =
var h: THash = myhash(t, key) and high(data) var h: THash = myhash(t, key) and high(data)
while not isNil(data[h].key): while not isNil(data[h].key):
h = nextTry(h, high(data)) h = nextTry(h, high(data))
data[h].key = key data[h].key = key
data[h].val = val data[h].val = val
proc Enlarge(t: PStringTable) = proc enlarge(t: PStringTable) =
var n: TKeyValuePairSeq var n: TKeyValuePairSeq
newSeq(n, len(t.data) * growthFactor) newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)): for i in countup(0, high(t.data)):
@ -140,7 +140,7 @@ proc `[]=`*(t: PStringTable, key, val: string) {.rtl, extern: "nstPut".} =
RawInsert(t, t.data, key, val) RawInsert(t, t.data, key, val)
inc(t.counter) inc(t.counter)
proc RaiseFormatException(s: string) = proc raiseFormatException(s: string) =
var e: ref EInvalidValue var e: ref EInvalidValue
new(e) new(e)
e.msg = "format string: key not found: " & s e.msg = "format string: key not found: " & s

View file

@ -128,7 +128,7 @@ proc cmpIgnoreStyle*(a, b: string): int {.noSideEffect,
## | > 0 iff a > b ## | > 0 iff a > b
var i = 0 var i = 0
var j = 0 var j = 0
while True: while true:
while a[i] == '_': inc(i) while a[i] == '_': inc(i)
while b[j] == '_': inc(j) # BUGFIX: typo while b[j] == '_': inc(j) # BUGFIX: typo
var aa = toLower(a[i]) var aa = toLower(a[i])
@ -344,7 +344,7 @@ proc intToStr*(x: int, minchars: int = 1): string {.noSideEffect,
if x < 0: if x < 0:
result = '-' & result result = '-' & result
proc ParseInt*(s: string): int {.noSideEffect, procvar, proc parseInt*(s: string): int {.noSideEffect, procvar,
rtl, extern: "nsuParseInt".} = rtl, extern: "nsuParseInt".} =
## Parses a decimal integer value contained in `s`. If `s` is not ## Parses a decimal integer value contained in `s`. If `s` is not
## a valid integer, `EInvalidValue` is raised. ## a valid integer, `EInvalidValue` is raised.
@ -352,7 +352,7 @@ proc ParseInt*(s: string): int {.noSideEffect, procvar,
if L != s.len or L == 0: if L != s.len or L == 0:
raise newException(EInvalidValue, "invalid integer: " & s) raise newException(EInvalidValue, "invalid integer: " & s)
proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect, procvar, proc parseBiggestInt*(s: string): biggestInt {.noSideEffect, procvar,
rtl, extern: "nsuParseBiggestInt".} = rtl, extern: "nsuParseBiggestInt".} =
## Parses a decimal integer value contained in `s`. If `s` is not ## Parses a decimal integer value contained in `s`. If `s` is not
## a valid integer, `EInvalidValue` is raised. ## a valid integer, `EInvalidValue` is raised.
@ -360,7 +360,7 @@ proc ParseBiggestInt*(s: string): biggestInt {.noSideEffect, procvar,
if L != s.len or L == 0: if L != s.len or L == 0:
raise newException(EInvalidValue, "invalid integer: " & s) raise newException(EInvalidValue, "invalid integer: " & s)
proc ParseFloat*(s: string): float {.noSideEffect, procvar, proc parseFloat*(s: string): float {.noSideEffect, procvar,
rtl, extern: "nsuParseFloat".} = rtl, extern: "nsuParseFloat".} =
## Parses a decimal floating point value contained in `s`. If `s` is not ## Parses a decimal floating point value contained in `s`. If `s` is not
## a valid floating point number, `EInvalidValue` is raised. ``NAN``, ## a valid floating point number, `EInvalidValue` is raised. ``NAN``,
@ -369,7 +369,7 @@ proc ParseFloat*(s: string): float {.noSideEffect, procvar,
if L != s.len or L == 0: if L != s.len or L == 0:
raise newException(EInvalidValue, "invalid float: " & s) raise newException(EInvalidValue, "invalid float: " & s)
proc ParseHexInt*(s: string): int {.noSideEffect, procvar, proc parseHexInt*(s: string): int {.noSideEffect, procvar,
rtl, extern: "nsuParseHexInt".} = rtl, extern: "nsuParseHexInt".} =
## Parses a hexadecimal integer value contained in `s`. If `s` is not ## Parses a hexadecimal integer value contained in `s`. If `s` is not
## a valid integer, `EInvalidValue` is raised. `s` can have one of the ## a valid integer, `EInvalidValue` is raised. `s` can have one of the
@ -455,7 +455,7 @@ proc align*(s: string, count: int, padding = ' '): string {.
## assert align("1232", 6, '#') == "##1232" ## assert align("1232", 6, '#') == "##1232"
if s.len < count: if s.len < count:
result = newString(count) result = newString(count)
var spaces = count - s.len let spaces = count - s.len
for i in 0..spaces-1: result[i] = padding for i in 0..spaces-1: result[i] = padding
for i in spaces..count-1: result[i] = s[i-spaces] for i in spaces..count-1: result[i] = s[i-spaces]
else: else:
@ -649,7 +649,7 @@ proc join*(a: openArray[string]): string {.
result = "" result = ""
type type
TSkipTable = array[Char, int] TSkipTable = array[char, int]
proc preprocessSub(sub: string, a: var TSkipTable) = proc preprocessSub(sub: string, a: var TSkipTable) =
var m = len(sub) var m = len(sub)
@ -795,7 +795,7 @@ proc delete*(s: var string, first, last: int) {.noSideEffect,
inc(j) inc(j)
setlen(s, newLen) setlen(s, newLen)
proc ParseOctInt*(s: string): int {.noSideEffect, proc parseOctInt*(s: string): int {.noSideEffect,
rtl, extern: "nsuParseOctInt".} = rtl, extern: "nsuParseOctInt".} =
## Parses an octal integer value contained in `s`. If `s` is not ## Parses an octal integer value contained in `s`. If `s` is not
## a valid integer, `EInvalidValue` is raised. `s` can have one of the ## a valid integer, `EInvalidValue` is raised. `s` can have one of the
@ -896,7 +896,7 @@ proc unescape*(s: string, prefix = "\"", suffix = "\""): string {.noSideEffect,
raise newException(EInvalidValue, raise newException(EInvalidValue,
"String does not start with a prefix of: " & prefix) "String does not start with a prefix of: " & prefix)
i.inc() i.inc()
while True: while true:
if i == s.len-suffix.len: break if i == s.len-suffix.len: break
case s[i] case s[i]
of '\\': of '\\':

View file

@ -146,7 +146,7 @@ proc getGMTime*(t: TTime): TTimeInfo {.tags: [FTime], raises: [].}
## converts the calendar time `t` to broken-down time representation, ## converts the calendar time `t` to broken-down time representation,
## expressed in Coordinated Universal Time (UTC). ## expressed in Coordinated Universal Time (UTC).
proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [].} proc timeInfoToTime*(timeInfo: TTimeInfo): TTime {.tags: [].}
## converts a broken-down time structure to ## converts a broken-down time structure to
## calendar time representation. The function ignores the specified ## calendar time representation. The function ignores the specified
## contents of the structure members `weekday` and `yearday` and recomputes ## contents of the structure members `weekday` and `yearday` and recomputes
@ -297,7 +297,7 @@ when not defined(JS):
when not defined(JS): when not defined(JS):
# C wrapper: # C wrapper:
type type
structTM {.importc: "struct tm", final.} = object StructTM {.importc: "struct tm", final.} = object
second {.importc: "tm_sec".}, second {.importc: "tm_sec".},
minute {.importc: "tm_min".}, minute {.importc: "tm_min".},
hour {.importc: "tm_hour".}, hour {.importc: "tm_hour".},
@ -308,7 +308,7 @@ when not defined(JS):
yearday {.importc: "tm_yday".}, yearday {.importc: "tm_yday".},
isdst {.importc: "tm_isdst".}: cint isdst {.importc: "tm_isdst".}: cint
PTimeInfo = ptr structTM PTimeInfo = ptr StructTM
PTime = ptr TTime PTime = ptr TTime
TClock {.importc: "clock_t".} = distinct int TClock {.importc: "clock_t".} = distinct int
@ -401,7 +401,7 @@ when not defined(JS):
# copying is needed anyway to provide reentrancity; thus # copying is needed anyway to provide reentrancity; thus
# the conversion is not expensive # the conversion is not expensive
proc TimeInfoToTime(timeInfo: TTimeInfo): TTime = proc timeInfoToTime(timeInfo: TTimeInfo): TTime =
var cTimeInfo = timeInfo # for C++ we have to make a copy, var cTimeInfo = timeInfo # for C++ we have to make a copy,
# because the header of mktime is broken in my version of libc # because the header of mktime is broken in my version of libc
return mktime(timeInfoToTM(cTimeInfo)) return mktime(timeInfoToTM(cTimeInfo))
@ -498,7 +498,7 @@ elif defined(JS):
result.weekday = weekDays[t.getUTCDay()] result.weekday = weekDays[t.getUTCDay()]
result.yearday = 0 result.yearday = 0
proc TimeInfoToTime*(timeInfo: TTimeInfo): TTime = proc timeInfoToTime*(timeInfo: TTimeInfo): TTime =
result = internGetTime() result = internGetTime()
result.setSeconds(timeInfo.second) result.setSeconds(timeInfo.second)
result.setMinutes(timeInfo.minute) result.setMinutes(timeInfo.minute)

View file

@ -14,8 +14,8 @@
include "system/inclrtl" include "system/inclrtl"
type type
irune = int # underlying type of TRune IRune = int # underlying type of TRune
TRune* = distinct irune ## type that can hold any Unicode character TRune* = distinct IRune ## type that can hold any Unicode character
TRune16* = distinct int16 ## 16 bit Unicode character TRune16* = distinct int16 ## 16 bit Unicode character
proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b) proc `<=%`*(a, b: TRune): bool = return int(a) <=% int(b)

View file

@ -1963,20 +1963,20 @@ when not defined(JS): #and not defined(NimrodVM):
## Template which expands to either stdout or stderr depending on ## Template which expands to either stdout or stderr depending on
## `useStdoutAsStdmsg` compile-time switch. ## `useStdoutAsStdmsg` compile-time switch.
proc Open*(f: var TFile, filename: string, proc open*(f: var TFile, filename: string,
mode: TFileMode = fmRead, bufSize: int = -1): Bool {.tags: [].} mode: TFileMode = fmRead, bufSize: int = -1): Bool {.tags: [].}
## Opens a file named `filename` with given `mode`. ## Opens a file named `filename` with given `mode`.
## ##
## Default mode is readonly. Returns true iff the file could be opened. ## Default mode is readonly. Returns true iff the file could be opened.
## This throws no exception if the file could not be opened. ## This throws no exception if the file could not be opened.
proc Open*(f: var TFile, filehandle: TFileHandle, proc open*(f: var TFile, filehandle: TFileHandle,
mode: TFileMode = fmRead): Bool {.tags: [].} mode: TFileMode = fmRead): Bool {.tags: [].}
## Creates a ``TFile`` from a `filehandle` with given `mode`. ## Creates a ``TFile`` from a `filehandle` with given `mode`.
## ##
## Default mode is readonly. Returns true iff the file could be opened. ## Default mode is readonly. Returns true iff the file could be opened.
proc Open*(filename: string, proc open*(filename: string,
mode: TFileMode = fmRead, bufSize: int = -1): TFile = mode: TFileMode = fmRead, bufSize: int = -1): TFile =
## Opens a file named `filename` with given `mode`. ## Opens a file named `filename` with given `mode`.
## ##
@ -1993,16 +1993,16 @@ when not defined(JS): #and not defined(NimrodVM):
## ##
## Default mode is readonly. Returns true iff the file could be reopened. ## Default mode is readonly. Returns true iff the file could be reopened.
proc Close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].} proc close*(f: TFile) {.importc: "fclose", header: "<stdio.h>", tags: [].}
## Closes the file. ## Closes the file.
proc EndOfFile*(f: TFile): Bool {.tags: [].} proc endOfFile*(f: TFile): Bool {.tags: [].}
## Returns true iff `f` is at the end. ## Returns true iff `f` is at the end.
proc readChar*(f: TFile): char {. proc readChar*(f: TFile): char {.
importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].} importc: "fgetc", header: "<stdio.h>", tags: [FReadIO].}
## Reads a single character from the stream `f`. ## Reads a single character from the stream `f`.
proc FlushFile*(f: TFile) {. proc flushFile*(f: TFile) {.
importc: "fflush", header: "<stdio.h>", tags: [FWriteIO].} importc: "fflush", header: "<stdio.h>", tags: [FWriteIO].}
## Flushes `f`'s buffer. ## Flushes `f`'s buffer.
@ -2051,13 +2051,13 @@ when not defined(JS): #and not defined(NimrodVM):
proc getFileSize*(f: TFile): int64 {.tags: [FReadIO].} proc getFileSize*(f: TFile): int64 {.tags: [FReadIO].}
## retrieves the file size (in bytes) of `f`. ## retrieves the file size (in bytes) of `f`.
proc ReadBytes*(f: TFile, a: var openarray[int8], start, len: int): int {. proc readBytes*(f: TFile, a: var openarray[int8], start, len: int): int {.
tags: [FReadIO].} tags: [FReadIO].}
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
## the actual number of bytes that have been read which may be less than ## the actual number of bytes that have been read which may be less than
## `len` (if not as many bytes are remaining), but not greater. ## `len` (if not as many bytes are remaining), but not greater.
proc ReadChars*(f: TFile, a: var openarray[char], start, len: int): int {. proc readChars*(f: TFile, a: var openarray[char], start, len: int): int {.
tags: [FReadIO].} tags: [FReadIO].}
## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns ## reads `len` bytes into the buffer `a` starting at ``a[start]``. Returns
## the actual number of bytes that have been read which may be less than ## the actual number of bytes that have been read which may be less than
@ -2655,7 +2655,7 @@ proc compiles*(x: expr): bool {.magic: "Compiles", noSideEffect.} =
## .. code-block:: Nimrod ## .. code-block:: Nimrod
## when not compiles(3 + 4): ## when not compiles(3 + 4):
## echo "'+' for integers is available" ## echo "'+' for integers is available"
nil discard
when defined(initDebugger): when defined(initDebugger):
initDebugger() initDebugger()
@ -2680,4 +2680,4 @@ proc locals*(): TObject {.magic: "Locals", noSideEffect.} =
## on any debug or runtime information. Note that in constrast to what ## on any debug or runtime information. Note that in constrast to what
## the official signature says, the return type is not ``TObject`` but a ## the official signature says, the return type is not ``TObject`` but a
## tuple of a structure that depends on the current scope. ## tuple of a structure that depends on the current scope.
nil discard

View file

@ -59,15 +59,16 @@ elif defined(windows):
MEM_DECOMMIT = 0x4000 MEM_DECOMMIT = 0x4000
MEM_RELEASE = 0x8000 MEM_RELEASE = 0x8000
proc VirtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType, proc virtualAlloc(lpAddress: pointer, dwSize: int, flAllocationType,
flProtect: int32): pointer {. flProtect: int32): pointer {.
header: "<windows.h>", stdcall.} header: "<windows.h>", stdcall, importc: "VirtualAlloc".}
proc VirtualFree(lpAddress: pointer, dwSize: int, proc virtualFree(lpAddress: pointer, dwSize: int,
dwFreeType: int32) {.header: "<windows.h>", stdcall.} dwFreeType: int32) {.header: "<windows.h>", stdcall,
importc: "VirtualFree".}
proc osAllocPages(size: int): pointer {.inline.} = proc osAllocPages(size: int): pointer {.inline.} =
result = VirtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT, result = virtualAlloc(nil, size, MEM_RESERVE or MEM_COMMIT,
PAGE_READWRITE) PAGE_READWRITE)
if result == nil: raiseOutOfMem() if result == nil: raiseOutOfMem()
@ -78,7 +79,7 @@ elif defined(windows):
# Windows :-(. We have to live with MEM_DECOMMIT instead. # Windows :-(. We have to live with MEM_DECOMMIT instead.
# Well that used to be the case but MEM_DECOMMIT fragments the address # Well that used to be the case but MEM_DECOMMIT fragments the address
# space heavily, so we now treat Windows as a strange unmap target. # space heavily, so we now treat Windows as a strange unmap target.
when reallyOsDealloc: VirtualFree(p, 0, MEM_RELEASE) when reallyOsDealloc: virtualFree(p, 0, MEM_RELEASE)
#VirtualFree(p, size, MEM_DECOMMIT) #VirtualFree(p, size, MEM_DECOMMIT)
else: else:
@ -251,14 +252,14 @@ proc llDeallocAll(a: var TMemRegion) =
osDeallocPages(it, PageSize) osDeallocPages(it, PageSize)
it = next it = next
proc IntSetGet(t: TIntSet, key: int): PTrunk = proc intSetGet(t: TIntSet, key: int): PTrunk =
var it = t.data[key and high(t.data)] var it = t.data[key and high(t.data)]
while it != nil: while it != nil:
if it.key == key: return it if it.key == key: return it
it = it.next it = it.next
result = nil result = nil
proc IntSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk = proc intSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk =
result = IntSetGet(t, key) result = IntSetGet(t, key)
if result == nil: if result == nil:
result = cast[PTrunk](llAlloc(a, sizeof(result[]))) result = cast[PTrunk](llAlloc(a, sizeof(result[])))
@ -266,7 +267,7 @@ proc IntSetPut(a: var TMemRegion, t: var TIntSet, key: int): PTrunk =
t.data[key and high(t.data)] = result t.data[key and high(t.data)] = result
result.key = key result.key = key
proc Contains(s: TIntSet, key: int): bool = proc contains(s: TIntSet, key: int): bool =
var t = IntSetGet(s, key shr TrunkShift) var t = IntSetGet(s, key shr TrunkShift)
if t != nil: if t != nil:
var u = key and TrunkMask var u = key and TrunkMask
@ -274,12 +275,12 @@ proc Contains(s: TIntSet, key: int): bool =
else: else:
result = false result = false
proc Incl(a: var TMemRegion, s: var TIntSet, key: int) = proc incl(a: var TMemRegion, s: var TIntSet, key: int) =
var t = IntSetPut(a, s, key shr TrunkShift) var t = IntSetPut(a, s, key shr TrunkShift)
var u = key and TrunkMask var u = key and TrunkMask
t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask))
proc Excl(s: var TIntSet, key: int) = proc excl(s: var TIntSet, key: int) =
var t = IntSetGet(s, key shr TrunkShift) var t = IntSetGet(s, key shr TrunkShift)
if t != nil: if t != nil:
var u = key and TrunkMask var u = key and TrunkMask
@ -387,7 +388,7 @@ proc freeOsChunks(a: var TMemRegion, p: pointer, size: int) =
#c_fprintf(c_stdout, "[Alloc] back to OS: %ld\n", size) #c_fprintf(c_stdout, "[Alloc] back to OS: %ld\n", size)
proc isAccessible(a: TMemRegion, p: pointer): bool {.inline.} = proc isAccessible(a: TMemRegion, p: pointer): bool {.inline.} =
result = Contains(a.chunkStarts, pageIndex(p)) result = contains(a.chunkStarts, pageIndex(p))
proc contains[T](list, x: T): bool = proc contains[T](list, x: T): bool =
var it = list var it = list
@ -403,7 +404,7 @@ proc writeFreeList(a: TMemRegion) =
it, it.next, it.prev) it, it.next, it.prev)
it = it.next it = it.next
proc ListAdd[T](head: var T, c: T) {.inline.} = proc listAdd[T](head: var T, c: T) {.inline.} =
sysAssert(c notin head, "listAdd 1") sysAssert(c notin head, "listAdd 1")
sysAssert c.prev == nil, "listAdd 2" sysAssert c.prev == nil, "listAdd 2"
sysAssert c.next == nil, "listAdd 3" sysAssert c.next == nil, "listAdd 3"
@ -413,7 +414,7 @@ proc ListAdd[T](head: var T, c: T) {.inline.} =
head.prev = c head.prev = c
head = c head = c
proc ListRemove[T](head: var T, c: T) {.inline.} = proc listRemove[T](head: var T, c: T) {.inline.} =
sysAssert(c in head, "listRemove") sysAssert(c in head, "listRemove")
if c == head: if c == head:
head = c.next head = c.next
@ -759,7 +760,7 @@ proc getOccupiedMem(a: TMemRegion): int {.inline.} =
# ---------------------- thread memory region ------------------------------- # ---------------------- thread memory region -------------------------------
template InstantiateForRegion(allocator: expr) = template instantiateForRegion(allocator: expr) =
when defined(fulldebug): when defined(fulldebug):
proc interiorAllocatedPtr*(p: pointer): pointer = proc interiorAllocatedPtr*(p: pointer): pointer =
result = interiorAllocatedPtr(allocator, p) result = interiorAllocatedPtr(allocator, p)
@ -801,13 +802,13 @@ template InstantiateForRegion(allocator: expr) =
when hasThreadSupport: when hasThreadSupport:
var sharedHeap: TMemRegion var sharedHeap: TMemRegion
var heapLock: TSysLock var heapLock: TSysLock
InitSysLock(HeapLock) initSysLock(HeapLock)
proc allocShared(size: int): pointer = proc allocShared(size: int): pointer =
when hasThreadSupport: when hasThreadSupport:
AcquireSys(HeapLock) acquireSys(HeapLock)
result = alloc(sharedHeap, size) result = alloc(sharedHeap, size)
ReleaseSys(HeapLock) releaseSys(HeapLock)
else: else:
result = alloc(size) result = alloc(size)
@ -817,17 +818,17 @@ template InstantiateForRegion(allocator: expr) =
proc deallocShared(p: pointer) = proc deallocShared(p: pointer) =
when hasThreadSupport: when hasThreadSupport:
AcquireSys(HeapLock) acquireSys(HeapLock)
dealloc(sharedHeap, p) dealloc(sharedHeap, p)
ReleaseSys(HeapLock) releaseSys(HeapLock)
else: else:
dealloc(p) dealloc(p)
proc reallocShared(p: pointer, newsize: int): pointer = proc reallocShared(p: pointer, newsize: int): pointer =
when hasThreadSupport: when hasThreadSupport:
AcquireSys(HeapLock) acquireSys(HeapLock)
result = realloc(sharedHeap, p, newsize) result = realloc(sharedHeap, p, newsize)
ReleaseSys(HeapLock) releaseSys(HeapLock)
else: else:
result = realloc(p, newsize) result = realloc(p, newsize)

View file

@ -168,12 +168,12 @@ proc objectInit(dest: Pointer, typ: PNimType) =
of tyArray, tyArrayConstr: of tyArray, tyArrayConstr:
for i in 0..(typ.size div typ.base.size)-1: for i in 0..(typ.size div typ.base.size)-1:
objectInit(cast[pointer](d +% i * typ.base.size), typ.base) objectInit(cast[pointer](d +% i * typ.base.size), typ.base)
else: nil # nothing to do else: discard # nothing to do
# ---------------------- assign zero ----------------------------------------- # ---------------------- assign zero -----------------------------------------
when not defined(nimmixin): when not defined(nimmixin):
proc destroy(x: int) = nil proc destroy(x: int) = discard
proc nimDestroyRange*[T](r: T) = proc nimDestroyRange*[T](r: T) =
# internal proc used for destroying sequences and arrays # internal proc used for destroying sequences and arrays
for i in countup(0, r.len - 1): destroy(r[i]) for i in countup(0, r.len - 1): destroy(r[i])

View file

@ -7,62 +7,60 @@
# distribution, for details about the copyright. # distribution, for details about the copyright.
# #
# Atomic operations for Nimrod. ## Atomic operations for Nimrod.
when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport: when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
type type
AtomMemModel* = enum AtomMemModel* = enum
ATOMIC_RELAXED, ATOMIC_RELAXED, ## No barriers or synchronization.
## No barriers or synchronization. ATOMIC_CONSUME, ## Data dependency only for both barrier and
ATOMIC_CONSUME, ## synchronization with another thread.
## Data dependency only for both barrier and synchronization with another thread. ATOMIC_ACQUIRE, ## Barrier to hoisting of code and synchronizes with
ATOMIC_ACQUIRE, ## release (or stronger)
## Barrier to hoisting of code and synchronizes with release (or stronger)
## semantic stores from another thread. ## semantic stores from another thread.
ATOMIC_RELEASE, ATOMIC_RELEASE, ## Barrier to sinking of code and synchronizes with
## Barrier to sinking of code and synchronizes with acquire (or stronger) ## acquire (or stronger)
## semantic loads from another thread. ## semantic loads from another thread.
ATOMIC_ACQ_REL, ATOMIC_ACQ_REL, ## Full barrier in both directions and synchronizes
## Full barrier in both directions and synchronizes with acquire loads ## with acquire loads
## and release stores in another thread. ## and release stores in another thread.
ATOMIC_SEQ_CST ATOMIC_SEQ_CST ## Full barrier in both directions and synchronizes
## Full barrier in both directions and synchronizes with acquire loads ## with acquire loads
## and release stores in all threads. ## and release stores in all threads.
TAtomType* = TNumber|pointer|ptr|char TAtomType* = TNumber|pointer|ptr|char
## Type Class representing valid types for use with atomic procs ## Type Class representing valid types for use with atomic procs
proc atomic_load_n*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {. proc atomicLoadN*[T: TAtomType](p: ptr T, mem: AtomMemModel): T {.
importc: "__atomic_load_n", nodecl.} importc: "__atomic_load_n", nodecl.}
## This proc implements an atomic load operation. It returns the contents at p. ## This proc implements an atomic load operation. It returns the contents at p.
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_CONSUME. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_CONSUME.
proc atomic_load*[T: TAtomType](p: ptr T, ret: ptr T, mem: AtomMemModel) {. proc atomicLoad*[T: TAtomType](p: ptr T, ret: ptr T, mem: AtomMemModel) {.
importc: "__atomic_load", nodecl.} importc: "__atomic_load", nodecl.}
## This is the generic version of an atomic load. It returns the contents at p in ret. ## This is the generic version of an atomic load. It returns the contents at p in ret.
proc atomic_store_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {. proc atomicStoreN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel) {.
importc: "__atomic_store_n", nodecl.} importc: "__atomic_store_n", nodecl.}
## This proc implements an atomic store operation. It writes val at p. ## This proc implements an atomic store operation. It writes val at p.
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, and ATOMIC_RELEASE. ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, and ATOMIC_RELEASE.
proc atomic_store*[T: TAtomType](p: ptr T, val: ptr T, mem: AtomMemModel) {. proc atomicStore*[T: TAtomType](p: ptr T, val: ptr T, mem: AtomMemModel) {.
importc: "__atomic_store", nodecl.} importc: "__atomic_store", nodecl.}
## This is the generic version of an atomic store. It stores the value of val at p ## This is the generic version of an atomic store. It stores the value of val at p
proc atomic_exchange_n*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicExchangeN*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_exchange_n", nodecl.} importc: "__atomic_exchange_n", nodecl.}
## This proc implements an atomic exchange operation. It writes val at p, ## This proc implements an atomic exchange operation. It writes val at p,
## and returns the previous contents at p. ## and returns the previous contents at p.
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_RELEASE, ATOMIC_ACQ_REL ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_ACQUIRE, ATOMIC_RELEASE, ATOMIC_ACQ_REL
proc atomic_exchange*[T: TAtomType](p: ptr T, val: ptr T, ret: ptr T, mem: AtomMemModel) {. proc atomicExchange*[T: TAtomType](p: ptr T, val: ptr T, ret: ptr T, mem: AtomMemModel) {.
importc: "__atomic_exchange", nodecl.} importc: "__atomic_exchange", nodecl.}
## This is the generic version of an atomic exchange. It stores the contents at val at p. ## This is the generic version of an atomic exchange. It stores the contents at val at p.
## The original value at p is copied into ret. ## The original value at p is copied into ret.
proc atomic_compare_exchange_n*[T: TAtomType](p: ptr T, expected: ptr T, desired: T, proc atomicCompareExchangeN*[T: TAtomType](p: ptr T, expected: ptr T, desired: T,
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {. weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
importc: "__atomic_compare_exchange_n ", nodecl.} importc: "__atomic_compare_exchange_n ", nodecl.}
## This proc implements an atomic compare and exchange operation. This compares the ## This proc implements an atomic compare and exchange operation. This compares the
@ -78,7 +76,7 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
## cannot be __ATOMIC_RELEASE nor __ATOMIC_ACQ_REL. It also cannot be a stronger model ## cannot be __ATOMIC_RELEASE nor __ATOMIC_ACQ_REL. It also cannot be a stronger model
## than that specified by success_memmodel. ## than that specified by success_memmodel.
proc atomic_compare_exchange*[T: TAtomType](p: ptr T, expected: ptr T, desired: ptr T, proc atomicCompareExchange*[T: TAtomType](p: ptr T, expected: ptr T, desired: ptr T,
weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {. weak: bool, success_memmodel: AtomMemModel, failure_memmodel: AtomMemModel): bool {.
importc: "__atomic_compare_exchange_n ", nodecl.} importc: "__atomic_compare_exchange_n ", nodecl.}
## This proc implements the generic version of atomic_compare_exchange. ## This proc implements the generic version of atomic_compare_exchange.
@ -86,58 +84,58 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
## value is also a pointer. ## value is also a pointer.
## Perform the operation return the new value, all memory models are valid ## Perform the operation return the new value, all memory models are valid
proc atomic_add_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicAddFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_add_fetch", nodecl.} importc: "__atomic_add_fetch", nodecl.}
proc atomic_sub_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicSubFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_sub_fetch", nodecl.} importc: "__atomic_sub_fetch", nodecl.}
proc atomic_or_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicOrFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_or_fetch ", nodecl.} importc: "__atomic_or_fetch ", nodecl.}
proc atomic_and_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicAndFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_and_fetch", nodecl.} importc: "__atomic_and_fetch", nodecl.}
proc atomic_xor_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicXorFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_xor_fetch", nodecl.} importc: "__atomic_xor_fetch", nodecl.}
proc atomic_nand_fetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicNandFetch*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_nand_fetch ", nodecl.} importc: "__atomic_nand_fetch ", nodecl.}
## Perform the operation return the old value, all memory models are valid ## Perform the operation return the old value, all memory models are valid
proc atomic_fetch_add*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchAdd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_add ", nodecl.} importc: "__atomic_fetch_add", nodecl.}
proc atomic_fetch_sub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchSub*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_sub ", nodecl.} importc: "__atomic_fetch_sub", nodecl.}
proc atomic_fetch_or*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchOr*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_or ", nodecl.} importc: "__atomic_fetch_or", nodecl.}
proc atomic_fetch_and*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchAnd*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_and ", nodecl.} importc: "__atomic_fetch_and", nodecl.}
proc atomic_fetch_xor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchXor*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_xor ", nodecl.} importc: "__atomic_fetch_xor", nodecl.}
proc atomic_fetch_nand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {. proc atomicFetchAand*[T: TAtomType](p: ptr T, val: T, mem: AtomMemModel): T {.
importc: "__atomic_fetch_nand", nodecl.} importc: "__atomic_fetch_nand", nodecl.}
proc atomic_test_and_set*(p: pointer, mem: AtomMemModel): bool {. proc atomicTestAndSet*(p: pointer, mem: AtomMemModel): bool {.
importc: "__atomic_test_and_set ", nodecl.} importc: "__atomic_test_and_set", nodecl.}
## This built-in function performs an atomic test-and-set operation on the byte at p. ## This built-in function performs an atomic test-and-set operation on the byte at p.
## The byte is set to some implementation defined nonzero “set” value and the return ## The byte is set to some implementation defined nonzero “set” value and the return
## value is true if and only if the previous contents were “set”. ## value is true if and only if the previous contents were “set”.
## All memory models are valid. ## All memory models are valid.
proc atomic_clear*(p: pointer, mem: AtomMemModel) {. proc atomicClear*(p: pointer, mem: AtomMemModel) {.
importc: "__atomic_clear", nodecl.} importc: "__atomic_clear", nodecl.}
## This built-in function performs an atomic clear operation at p. ## This built-in function performs an atomic clear operation at p.
## After the operation, at p contains 0. ## After the operation, at p contains 0.
## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_RELEASE ## ATOMIC_RELAXED, ATOMIC_SEQ_CST, ATOMIC_RELEASE
proc atomic_thread_fence*(mem: AtomMemModel) {. proc atomicThreadFence*(mem: AtomMemModel) {.
importc: "__atomic_thread_fence ", nodecl.} importc: "__atomic_thread_fence", nodecl.}
## This built-in function acts as a synchronization fence between threads based ## This built-in function acts as a synchronization fence between threads based
## on the specified memory model. All memory orders are valid. ## on the specified memory model. All memory orders are valid.
proc atomic_signal_fence*(mem: AtomMemModel) {. proc atomicSignalFence*(mem: AtomMemModel) {.
importc: "__atomic_signal_fence ", nodecl.} importc: "__atomic_signal_fence", nodecl.}
## This built-in function acts as a synchronization fence between a thread and ## This built-in function acts as a synchronization fence between a thread and
## signal handlers based in the same thread. All memory orders are valid. ## signal handlers based in the same thread. All memory orders are valid.
proc atomic_always_lock_free*(size: int, p: pointer): bool {. proc atomicAlwaysLockFree*(size: int, p: pointer): bool {.
importc: "__atomic_always_lock_free ", nodecl.} importc: "__atomic_always_lock_free", nodecl.}
## This built-in function returns true if objects of size bytes always generate ## This built-in function returns true if objects of size bytes always generate
## lock free atomic instructions for the target architecture. size must resolve ## lock free atomic instructions for the target architecture. size must resolve
## to a compile-time constant and the result also resolves to a compile-time constant. ## to a compile-time constant and the result also resolves to a compile-time constant.
@ -145,8 +143,8 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
## A value of 0 indicates typical alignment should be used. The compiler may also ## A value of 0 indicates typical alignment should be used. The compiler may also
## ignore this parameter. ## ignore this parameter.
proc atomic_is_lock_free*(size: int, p: pointer): bool {. proc atomicIsLockFree*(size: int, p: pointer): bool {.
importc: "__atomic_is_lock_free ", nodecl.} importc: "__atomic_is_lock_free", nodecl.}
## This built-in function returns true if objects of size bytes always generate ## This built-in function returns true if objects of size bytes always generate
## lock free atomic instructions for the target architecture. If it is not known ## lock free atomic instructions for the target architecture. If it is not known
## to be lock free a call is made to a runtime routine named __atomic_is_lock_free. ## to be lock free a call is made to a runtime routine named __atomic_is_lock_free.
@ -154,19 +152,14 @@ when (defined(gcc) or defined(llvm_gcc)) and hasThreadSupport:
## A value of 0 indicates typical alignment should be used. The compiler may also ## A value of 0 indicates typical alignment should be used. The compiler may also
## ignore this parameter. ## ignore this parameter.
elif defined(vcc) and hasThreadSupport: elif defined(vcc) and hasThreadSupport:
proc add_and_fetch*(p: ptr int, val: int): int {. proc addAndFetch*(p: ptr int, val: int): int {.
importc: "NimXadd", nodecl.} importc: "NimXadd", nodecl.}
else: else:
proc add_and_fetch*(p: ptr int, val: int): int {.inline.} = proc addAndFetch*(p: ptr int, val: int): int {.inline.} =
inc(p[], val) inc(p[], val)
result = p[] result = p[]
# atomic compare and swap (CAS) funcitons to implement lock-free algorithms # atomic compare and swap (CAS) funcitons to implement lock-free algorithms
#if defined(windows) and not defined(gcc) and hasThreadSupport: #if defined(windows) and not defined(gcc) and hasThreadSupport:
@ -210,6 +203,3 @@ proc atomicDec*(memLoc: var int, x: int = 1): int =
else: else:
dec(memLoc, x) dec(memLoc, x)
result = memLoc result = memLoc

View file

@ -9,30 +9,30 @@
# not really an AVL tree anymore, but still balanced ... # not really an AVL tree anymore, but still balanced ...
template IsBottom(n: PAvlNode): bool = n == bottom template isBottom(n: PAvlNode): bool = n == bottom
proc lowGauge(n: PAvlNode): int = proc lowGauge(n: PAvlNode): int =
var it = n var it = n
while not IsBottom(it): while not isBottom(it):
result = it.key result = it.key
it = it.link[0] it = it.link[0]
proc highGauge(n: PAvlNode): int = proc highGauge(n: PAvlNode): int =
result = -1 result = -1
var it = n var it = n
while not IsBottom(it): while not isBottom(it):
result = it.upperBound result = it.upperBound
it = it.link[1] it = it.link[1]
proc find(root: PAvlNode, key: int): PAvlNode = proc find(root: PAvlNode, key: int): PAvlNode =
var it = root var it = root
while not IsBottom(it): while not isBottom(it):
if it.key == key: return it if it.key == key: return it
it = it.link[ord(it.key <% key)] it = it.link[ord(it.key <% key)]
proc inRange(root: PAvlNode, key: int): PAvlNode = proc inRange(root: PAvlNode, key: int): PAvlNode =
var it = root var it = root
while not IsBottom(it): while not isBottom(it):
if it.key <=% key and key <% it.upperBound: return it if it.key <=% key and key <% it.upperBound: return it
it = it.link[ord(it.key <% key)] it = it.link[ord(it.key <% key)]

View file

@ -43,15 +43,15 @@ type
proc contains(s: TCellSeq, c: PCell): bool {.inline.} = proc contains(s: TCellSeq, c: PCell): bool {.inline.} =
for i in 0 .. s.len-1: for i in 0 .. s.len-1:
if s.d[i] == c: return True if s.d[i] == c: return true
return False return false
proc add(s: var TCellSeq, c: PCell) {.inline.} = proc add(s: var TCellSeq, c: PCell) {.inline.} =
if s.len >= s.cap: if s.len >= s.cap:
s.cap = s.cap * 3 div 2 s.cap = s.cap * 3 div 2
var d = cast[PCellArray](Alloc(s.cap * sizeof(PCell))) var d = cast[PCellArray](alloc(s.cap * sizeof(PCell)))
copyMem(d, s.d, s.len * sizeof(PCell)) copyMem(d, s.d, s.len * sizeof(PCell))
Dealloc(s.d) dealloc(s.d)
s.d = d s.d = d
# XXX: realloc? # XXX: realloc?
s.d[s.len] = c s.d[s.len] = c
@ -60,10 +60,10 @@ proc add(s: var TCellSeq, c: PCell) {.inline.} =
proc init(s: var TCellSeq, cap: int = 1024) = proc init(s: var TCellSeq, cap: int = 1024) =
s.len = 0 s.len = 0
s.cap = cap s.cap = cap
s.d = cast[PCellArray](Alloc0(cap * sizeof(PCell))) s.d = cast[PCellArray](alloc0(cap * sizeof(PCell)))
proc deinit(s: var TCellSeq) = proc deinit(s: var TCellSeq) =
Dealloc(s.d) dealloc(s.d)
s.d = nil s.d = nil
s.len = 0 s.len = 0
s.cap = 0 s.cap = 0
@ -73,20 +73,20 @@ proc deinit(s: var TCellSeq) =
const const
InitCellSetSize = 1024 # must be a power of two! InitCellSetSize = 1024 # must be a power of two!
proc Init(s: var TCellSet) = proc init(s: var TCellSet) =
s.data = cast[PPageDescArray](Alloc0(InitCellSetSize * sizeof(PPageDesc))) s.data = cast[PPageDescArray](alloc0(InitCellSetSize * sizeof(PPageDesc)))
s.max = InitCellSetSize-1 s.max = InitCellSetSize-1
s.counter = 0 s.counter = 0
s.head = nil s.head = nil
proc Deinit(s: var TCellSet) = proc deinit(s: var TCellSet) =
var it = s.head var it = s.head
while it != nil: while it != nil:
var n = it.next var n = it.next
Dealloc(it) dealloc(it)
it = n it = n
s.head = nil # play it safe here s.head = nil # play it safe here
Dealloc(s.data) dealloc(s.data)
s.data = nil s.data = nil
s.counter = 0 s.counter = 0
@ -96,14 +96,14 @@ proc nextTry(h, maxHash: int): int {.inline.} =
# generates each int in range(maxHash) exactly once (see any text on # generates each int in range(maxHash) exactly once (see any text on
# random-number generation for proof). # random-number generation for proof).
proc CellSetGet(t: TCellSet, key: TAddress): PPageDesc = proc cellSetGet(t: TCellSet, key: TAddress): PPageDesc =
var h = cast[int](key) and t.max var h = cast[int](key) and t.max
while t.data[h] != nil: while t.data[h] != nil:
if t.data[h].key == key: return t.data[h] if t.data[h].key == key: return t.data[h]
h = nextTry(h, t.max) h = nextTry(h, t.max)
return nil return nil
proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) = proc cellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
var h = cast[int](desc.key) and t.max var h = cast[int](desc.key) and t.max
while data[h] != nil: while data[h] != nil:
sysAssert(data[h] != desc, "CellSetRawInsert 1") sysAssert(data[h] != desc, "CellSetRawInsert 1")
@ -111,17 +111,17 @@ proc CellSetRawInsert(t: TCellSet, data: PPageDescArray, desc: PPageDesc) =
sysAssert(data[h] == nil, "CellSetRawInsert 2") sysAssert(data[h] == nil, "CellSetRawInsert 2")
data[h] = desc data[h] = desc
proc CellSetEnlarge(t: var TCellSet) = proc cellSetEnlarge(t: var TCellSet) =
var oldMax = t.max var oldMax = t.max
t.max = ((t.max+1)*2)-1 t.max = ((t.max+1)*2)-1
var n = cast[PPageDescArray](Alloc0((t.max + 1) * sizeof(PPageDesc))) var n = cast[PPageDescArray](alloc0((t.max + 1) * sizeof(PPageDesc)))
for i in 0 .. oldmax: for i in 0 .. oldmax:
if t.data[i] != nil: if t.data[i] != nil:
CellSetRawInsert(t, n, t.data[i]) cellSetRawInsert(t, n, t.data[i])
Dealloc(t.data) dealloc(t.data)
t.data = n t.data = n
proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc = proc cellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
var h = cast[int](key) and t.max var h = cast[int](key) and t.max
while true: while true:
var x = t.data[h] var x = t.data[h]
@ -130,13 +130,13 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
h = nextTry(h, t.max) h = nextTry(h, t.max)
if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4): if ((t.max+1)*2 < t.counter*3) or ((t.max+1)-t.counter < 4):
CellSetEnlarge(t) cellSetEnlarge(t)
inc(t.counter) inc(t.counter)
h = cast[int](key) and t.max h = cast[int](key) and t.max
while t.data[h] != nil: h = nextTry(h, t.max) while t.data[h] != nil: h = nextTry(h, t.max)
sysAssert(t.data[h] == nil, "CellSetPut") sysAssert(t.data[h] == nil, "CellSetPut")
# the new page descriptor goes into result # the new page descriptor goes into result
result = cast[PPageDesc](Alloc0(sizeof(TPageDesc))) result = cast[PPageDesc](alloc0(sizeof(TPageDesc)))
result.next = t.head result.next = t.head
result.key = key result.key = key
t.head = result t.head = result
@ -146,7 +146,7 @@ proc CellSetPut(t: var TCellSet, key: TAddress): PPageDesc =
proc contains(s: TCellSet, cell: PCell): bool = proc contains(s: TCellSet, cell: PCell): bool =
var u = cast[TAddress](cell) var u = cast[TAddress](cell)
var t = CellSetGet(s, u shr PageShift) var t = cellSetGet(s, u shr PageShift)
if t != nil: if t != nil:
u = (u %% PageSize) /% MemAlign u = (u %% PageSize) /% MemAlign
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0 result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
@ -155,13 +155,13 @@ proc contains(s: TCellSet, cell: PCell): bool =
proc incl(s: var TCellSet, cell: PCell) {.noinline.} = proc incl(s: var TCellSet, cell: PCell) {.noinline.} =
var u = cast[TAddress](cell) var u = cast[TAddress](cell)
var t = CellSetPut(s, u shr PageShift) var t = cellSetPut(s, u shr PageShift)
u = (u %% PageSize) /% MemAlign u = (u %% PageSize) /% MemAlign
t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask)) t.bits[u shr IntShift] = t.bits[u shr IntShift] or (1 shl (u and IntMask))
proc excl(s: var TCellSet, cell: PCell) = proc excl(s: var TCellSet, cell: PCell) =
var u = cast[TAddress](cell) var u = cast[TAddress](cell)
var t = CellSetGet(s, u shr PageShift) var t = cellSetGet(s, u shr PageShift)
if t != nil: if t != nil:
u = (u %% PageSize) /% MemAlign u = (u %% PageSize) /% MemAlign
t.bits[u shr IntShift] = (t.bits[u shr IntShift] and t.bits[u shr IntShift] = (t.bits[u shr IntShift] and
@ -169,7 +169,7 @@ proc excl(s: var TCellSet, cell: PCell) =
proc containsOrIncl(s: var TCellSet, cell: PCell): bool = proc containsOrIncl(s: var TCellSet, cell: PCell): bool =
var u = cast[TAddress](cell) var u = cast[TAddress](cell)
var t = CellSetGet(s, u shr PageShift) var t = cellSetGet(s, u shr PageShift)
if t != nil: if t != nil:
u = (u %% PageSize) /% MemAlign u = (u %% PageSize) /% MemAlign
result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0 result = (t.bits[u shr IntShift] and (1 shl (u and IntMask))) != 0
@ -177,7 +177,7 @@ proc containsOrIncl(s: var TCellSet, cell: PCell): bool =
t.bits[u shr IntShift] = t.bits[u shr IntShift] or t.bits[u shr IntShift] = t.bits[u shr IntShift] or
(1 shl (u and IntMask)) (1 shl (u and IntMask))
else: else:
Incl(s, cell) incl(s, cell)
result = false result = false
iterator elements(t: TCellSet): PCell {.inline.} = iterator elements(t: TCellSet): PCell {.inline.} =

View file

@ -28,7 +28,7 @@ proc nimLoadLibraryError(path: string) =
stdout.rawWrite("\n") stdout.rawWrite("\n")
quit(1) quit(1)
proc ProcAddrError(name: cstring) {.noinline.} = proc procAddrError(name: cstring) {.noinline.} =
# carefully written to avoid memory allocation: # carefully written to avoid memory allocation:
stdout.rawWrite("could not import: ") stdout.rawWrite("could not import: ")
stdout.write(name) stdout.write(name)
@ -83,21 +83,22 @@ elif defined(windows) or defined(dos):
type type
THINSTANCE {.importc: "HINSTANCE".} = pointer THINSTANCE {.importc: "HINSTANCE".} = pointer
proc FreeLibrary(lib: THINSTANCE) {.importc, header: "<windows.h>", stdcall.} proc freeLibrary(lib: THINSTANCE) {.
importc: "FreeLibrary", header: "<windows.h>", stdcall.}
proc winLoadLibrary(path: cstring): THINSTANCE {. proc winLoadLibrary(path: cstring): THINSTANCE {.
importc: "LoadLibraryA", header: "<windows.h>", stdcall.} importc: "LoadLibraryA", header: "<windows.h>", stdcall.}
proc GetProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {. proc getProcAddress(lib: THINSTANCE, name: cstring): TProcAddr {.
importc: "GetProcAddress", header: "<windows.h>", stdcall.} importc: "GetProcAddress", header: "<windows.h>", stdcall.}
proc nimUnloadLibrary(lib: TLibHandle) = proc nimUnloadLibrary(lib: TLibHandle) =
FreeLibrary(cast[THINSTANCE](lib)) freeLibrary(cast[THINSTANCE](lib))
proc nimLoadLibrary(path: string): TLibHandle = proc nimLoadLibrary(path: string): TLibHandle =
result = cast[TLibHandle](winLoadLibrary(path)) result = cast[TLibHandle](winLoadLibrary(path))
proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr = proc nimGetProcAddr(lib: TLibHandle, name: cstring): TProcAddr =
result = GetProcAddress(cast[THINSTANCE](lib), name) result = getProcAddress(cast[THINSTANCE](lib), name)
if result == nil: ProcAddrError(name) if result == nil: procAddrError(name)
elif defined(mac): elif defined(mac):
# #

View file

@ -151,7 +151,7 @@ template gcTrace(cell, state: expr): stmt {.immediate.} =
# forward declarations: # forward declarations:
proc collectCT(gch: var TGcHeap) proc collectCT(gch: var TGcHeap)
proc IsOnStack*(p: pointer): bool {.noinline.} proc isOnStack*(p: pointer): bool {.noinline.}
proc forAllChildren(cell: PCell, op: TWalkOp) proc forAllChildren(cell: PCell, op: TWalkOp)
proc doOperation(p: pointer, op: TWalkOp) proc doOperation(p: pointer, op: TWalkOp)
proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp) proc forAllChildrenAux(dest: Pointer, mt: PNimType, op: TWalkOp)
@ -669,7 +669,7 @@ proc doOperation(p: pointer, op: TWalkOp) =
proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} = proc nimGCvisit(d: pointer, op: int) {.compilerRtl.} =
doOperation(d, TWalkOp(op)) doOperation(d, TWalkOp(op))
proc CollectZCT(gch: var TGcHeap): bool proc collectZCT(gch: var TGcHeap): bool
when useMarkForDebug or useBackupGc: when useMarkForDebug or useBackupGc:
proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl.} proc markStackAndRegistersForSweep(gch: var TGcHeap) {.noinline, cdecl.}

View file

@ -72,7 +72,7 @@ proc reprEnum(e: int, typ: PNimType): string {.compilerRtl.} =
result = $e & " (invalid data!)" result = $e & " (invalid data!)"
type type
pbyteArray = ptr array[0.. 0xffff, int8] PByteArray = ptr array[0.. 0xffff, int8]
proc addSetElem(result: var string, elem: int, typ: PNimType) = proc addSetElem(result: var string, elem: int, typ: PNimType) =
case typ.kind case typ.kind

View file

@ -22,48 +22,48 @@ when defined(Windows):
TSysCond = THandle TSysCond = THandle
proc InitSysLock(L: var TSysLock) {.stdcall, noSideEffect, proc initSysLock(L: var TSysLock) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "InitializeCriticalSection".} dynlib: "kernel32", importc: "InitializeCriticalSection".}
## Initializes the lock `L`. ## Initializes the lock `L`.
proc TryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect, proc tryAcquireSysAux(L: var TSysLock): int32 {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "TryEnterCriticalSection".} dynlib: "kernel32", importc: "TryEnterCriticalSection".}
## Tries to acquire the lock `L`. ## Tries to acquire the lock `L`.
proc TryAcquireSys(L: var TSysLock): bool {.inline.} = proc tryAcquireSys(L: var TSysLock): bool {.inline.} =
result = TryAcquireSysAux(L) != 0'i32 result = TryAcquireSysAux(L) != 0'i32
proc AcquireSys(L: var TSysLock) {.stdcall, noSideEffect, proc acquireSys(L: var TSysLock) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "EnterCriticalSection".} dynlib: "kernel32", importc: "EnterCriticalSection".}
## Acquires the lock `L`. ## Acquires the lock `L`.
proc ReleaseSys(L: var TSysLock) {.stdcall, noSideEffect, proc releaseSys(L: var TSysLock) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "LeaveCriticalSection".} dynlib: "kernel32", importc: "LeaveCriticalSection".}
## Releases the lock `L`. ## Releases the lock `L`.
proc DeinitSys(L: var TSysLock) {.stdcall, noSideEffect, proc deinitSys(L: var TSysLock) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "DeleteCriticalSection".} dynlib: "kernel32", importc: "DeleteCriticalSection".}
proc CreateEvent(lpEventAttributes: pointer, proc createEvent(lpEventAttributes: pointer,
bManualReset, bInitialState: int32, bManualReset, bInitialState: int32,
lpName: cstring): TSysCond {.stdcall, noSideEffect, lpName: cstring): TSysCond {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "CreateEventA".} dynlib: "kernel32", importc: "CreateEventA".}
proc CloseHandle(hObject: THandle) {.stdcall, noSideEffect, proc closeHandle(hObject: THandle) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "CloseHandle".} dynlib: "kernel32", importc: "CloseHandle".}
proc WaitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {. proc waitForSingleObject(hHandle: THandle, dwMilliseconds: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
proc SignalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect, proc signalSysCond(hEvent: TSysCond) {.stdcall, noSideEffect,
dynlib: "kernel32", importc: "SetEvent".} dynlib: "kernel32", importc: "SetEvent".}
proc InitSysCond(cond: var TSysCond) {.inline.} = proc initSysCond(cond: var TSysCond) {.inline.} =
cond = CreateEvent(nil, 0'i32, 0'i32, nil) cond = createEvent(nil, 0'i32, 0'i32, nil)
proc DeinitSysCond(cond: var TSysCond) {.inline.} = proc deinitSysCond(cond: var TSysCond) {.inline.} =
CloseHandle(cond) closeHandle(cond)
proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) = proc waitSysCond(cond: var TSysCond, lock: var TSysLock) =
releaseSys(lock) releaseSys(lock)
discard WaitForSingleObject(cond, -1'i32) discard waitForSingleObject(cond, -1'i32)
acquireSys(lock) acquireSys(lock)
else: else:
@ -73,29 +73,29 @@ else:
TSysCond {.importc: "pthread_cond_t", pure, final, TSysCond {.importc: "pthread_cond_t", pure, final,
header: "<sys/types.h>".} = object header: "<sys/types.h>".} = object
proc InitSysLock(L: var TSysLock, attr: pointer = nil) {. proc initSysLock(L: var TSysLock, attr: pointer = nil) {.
importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.} importc: "pthread_mutex_init", header: "<pthread.h>", noSideEffect.}
proc AcquireSys(L: var TSysLock) {.noSideEffect, proc acquireSys(L: var TSysLock) {.noSideEffect,
importc: "pthread_mutex_lock", header: "<pthread.h>".} importc: "pthread_mutex_lock", header: "<pthread.h>".}
proc TryAcquireSysAux(L: var TSysLock): cint {.noSideEffect, proc tryAcquireSysAux(L: var TSysLock): cint {.noSideEffect,
importc: "pthread_mutex_trylock", header: "<pthread.h>".} importc: "pthread_mutex_trylock", header: "<pthread.h>".}
proc TryAcquireSys(L: var TSysLock): bool {.inline.} = proc tryAcquireSys(L: var TSysLock): bool {.inline.} =
result = TryAcquireSysAux(L) == 0'i32 result = tryAcquireSysAux(L) == 0'i32
proc ReleaseSys(L: var TSysLock) {.noSideEffect, proc releaseSys(L: var TSysLock) {.noSideEffect,
importc: "pthread_mutex_unlock", header: "<pthread.h>".} importc: "pthread_mutex_unlock", header: "<pthread.h>".}
proc DeinitSys(L: var TSysLock) {. proc deinitSys(L: var TSysLock) {.
importc: "pthread_mutex_destroy", header: "<pthread.h>".} importc: "pthread_mutex_destroy", header: "<pthread.h>".}
proc InitSysCond(cond: var TSysCond, cond_attr: pointer = nil) {. proc initSysCond(cond: var TSysCond, cond_attr: pointer = nil) {.
importc: "pthread_cond_init", header: "<pthread.h>".} importc: "pthread_cond_init", header: "<pthread.h>".}
proc WaitSysCond(cond: var TSysCond, lock: var TSysLock) {. proc waitSysCond(cond: var TSysCond, lock: var TSysLock) {.
importc: "pthread_cond_wait", header: "<pthread.h>".} importc: "pthread_cond_wait", header: "<pthread.h>".}
proc SignalSysCond(cond: var TSysCond) {. proc signalSysCond(cond: var TSysCond) {.
importc: "pthread_cond_signal", header: "<pthread.h>".} importc: "pthread_cond_signal", header: "<pthread.h>".}
proc DeinitSysCond(cond: var TSysCond) {. proc deinitSysCond(cond: var TSysCond) {.
importc: "pthread_cond_destroy", header: "<pthread.h>".} importc: "pthread_cond_destroy", header: "<pthread.h>".}

View file

@ -96,25 +96,25 @@ const
CREATE_UNICODE_ENVIRONMENT* = 1024'i32 CREATE_UNICODE_ENVIRONMENT* = 1024'i32
proc CloseHandle*(hObject: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", proc closeHandle*(hObject: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "CloseHandle".} importc: "CloseHandle".}
proc ReadFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32, proc readFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToRead: int32,
lpNumberOfBytesRead: var int32, lpOverlapped: pointer): WINBOOL{. lpNumberOfBytesRead: var int32, lpOverlapped: pointer): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "ReadFile".} stdcall, dynlib: "kernel32", importc: "ReadFile".}
proc WriteFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32, proc writeFile*(hFile: THandle, Buffer: pointer, nNumberOfBytesToWrite: int32,
lpNumberOfBytesWritten: var int32, lpNumberOfBytesWritten: var int32,
lpOverlapped: pointer): WINBOOL{. lpOverlapped: pointer): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "WriteFile".} stdcall, dynlib: "kernel32", importc: "WriteFile".}
proc CreatePipe*(hReadPipe, hWritePipe: var THandle, proc createPipe*(hReadPipe, hWritePipe: var THandle,
lpPipeAttributes: var TSECURITY_ATTRIBUTES, lpPipeAttributes: var TSECURITY_ATTRIBUTES,
nSize: int32): WINBOOL{. nSize: int32): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "CreatePipe".} stdcall, dynlib: "kernel32", importc: "CreatePipe".}
when useWinUnicode: when useWinUnicode:
proc CreateProcessW*(lpApplicationName, lpCommandLine: widecstring, proc createProcessW*(lpApplicationName, lpCommandLine: widecstring,
lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, lpProcessAttributes: ptr TSECURITY_ATTRIBUTES,
lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, lpThreadAttributes: ptr TSECURITY_ATTRIBUTES,
bInheritHandles: WINBOOL, dwCreationFlags: int32, bInheritHandles: WINBOOL, dwCreationFlags: int32,
@ -124,7 +124,7 @@ when useWinUnicode:
stdcall, dynlib: "kernel32", importc: "CreateProcessW".} stdcall, dynlib: "kernel32", importc: "CreateProcessW".}
else: else:
proc CreateProcessA*(lpApplicationName, lpCommandLine: cstring, proc createProcessA*(lpApplicationName, lpCommandLine: cstring,
lpProcessAttributes: ptr TSECURITY_ATTRIBUTES, lpProcessAttributes: ptr TSECURITY_ATTRIBUTES,
lpThreadAttributes: ptr TSECURITY_ATTRIBUTES, lpThreadAttributes: ptr TSECURITY_ATTRIBUTES,
bInheritHandles: WINBOOL, dwCreationFlags: int32, bInheritHandles: WINBOOL, dwCreationFlags: int32,
@ -134,74 +134,76 @@ else:
stdcall, dynlib: "kernel32", importc: "CreateProcessA".} stdcall, dynlib: "kernel32", importc: "CreateProcessA".}
proc SuspendThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32", proc suspendThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32",
importc: "SuspendThread".} importc: "SuspendThread".}
proc ResumeThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32", proc resumeThread*(hThread: THANDLE): int32 {.stdcall, dynlib: "kernel32",
importc: "ResumeThread".} importc: "ResumeThread".}
proc WaitForSingleObject*(hHandle: THANDLE, dwMilliseconds: int32): int32 {. proc waitForSingleObject*(hHandle: THANDLE, dwMilliseconds: int32): int32 {.
stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".} stdcall, dynlib: "kernel32", importc: "WaitForSingleObject".}
proc TerminateProcess*(hProcess: THANDLE, uExitCode: int): WINBOOL {.stdcall, proc terminateProcess*(hProcess: THANDLE, uExitCode: int): WINBOOL {.stdcall,
dynlib: "kernel32", importc: "TerminateProcess".} dynlib: "kernel32", importc: "TerminateProcess".}
proc GetExitCodeProcess*(hProcess: THANDLE, lpExitCode: var int32): WINBOOL {. proc getExitCodeProcess*(hProcess: THANDLE, lpExitCode: var int32): WINBOOL {.
stdcall, dynlib: "kernel32", importc: "GetExitCodeProcess".} stdcall, dynlib: "kernel32", importc: "GetExitCodeProcess".}
proc GetStdHandle*(nStdHandle: int32): THANDLE {.stdcall, dynlib: "kernel32", proc getStdHandle*(nStdHandle: int32): THANDLE {.stdcall, dynlib: "kernel32",
importc: "GetStdHandle".} importc: "GetStdHandle".}
proc SetStdHandle*(nStdHandle: int32, hHandle: THANDLE): WINBOOL {.stdcall, proc setStdHandle*(nStdHandle: int32, hHandle: THANDLE): WINBOOL {.stdcall,
dynlib: "kernel32", importc: "SetStdHandle".} dynlib: "kernel32", importc: "SetStdHandle".}
proc FlushFileBuffers*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", proc flushFileBuffers*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "FlushFileBuffers".} importc: "FlushFileBuffers".}
proc GetLastError*(): int32 {.importc, stdcall, dynlib: "kernel32".} proc getLastError*(): int32 {.importc: "GetLastError",
stdcall, dynlib: "kernel32".}
when useWinUnicode: when useWinUnicode:
proc FormatMessageW*(dwFlags: int32, lpSource: pointer, proc formatMessageW*(dwFlags: int32, lpSource: pointer,
dwMessageId, dwLanguageId: int32, dwMessageId, dwLanguageId: int32,
lpBuffer: pointer, nSize: int32, lpBuffer: pointer, nSize: int32,
Arguments: pointer): int32 {. Arguments: pointer): int32 {.
importc, stdcall, dynlib: "kernel32".} importc: "FormatMessageW", stdcall, dynlib: "kernel32".}
else: else:
proc FormatMessageA*(dwFlags: int32, lpSource: pointer, proc formatMessageA*(dwFlags: int32, lpSource: pointer,
dwMessageId, dwLanguageId: int32, dwMessageId, dwLanguageId: int32,
lpBuffer: pointer, nSize: int32, lpBuffer: pointer, nSize: int32,
Arguments: pointer): int32 {. Arguments: pointer): int32 {.
importc, stdcall, dynlib: "kernel32".} importc: "FormatMessageA", stdcall, dynlib: "kernel32".}
proc LocalFree*(p: pointer) {.importc, stdcall, dynlib: "kernel32".} proc localFree*(p: pointer) {.
importc: "LocalFree", stdcall, dynlib: "kernel32".}
when useWinUnicode: when useWinUnicode:
proc GetCurrentDirectoryW*(nBufferLength: int32, proc getCurrentDirectoryW*(nBufferLength: int32,
lpBuffer: widecstring): int32 {. lpBuffer: widecstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "GetCurrentDirectoryW", dynlib: "kernel32", stdcall.}
proc SetCurrentDirectoryW*(lpPathName: widecstring): int32 {. proc setCurrentDirectoryW*(lpPathName: widecstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "SetCurrentDirectoryW", dynlib: "kernel32", stdcall.}
proc CreateDirectoryW*(pathName: widecstring, security: Pointer=nil): int32 {. proc createDirectoryW*(pathName: widecstring, security: Pointer=nil): int32 {.
importc: "CreateDirectoryW", dynlib: "kernel32", stdcall.} importc: "CreateDirectoryW", dynlib: "kernel32", stdcall.}
proc RemoveDirectoryW*(lpPathName: widecstring): int32 {. proc removeDirectoryW*(lpPathName: widecstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "RemoveDirectoryW", dynlib: "kernel32", stdcall.}
proc SetEnvironmentVariableW*(lpName, lpValue: widecstring): int32 {. proc setEnvironmentVariableW*(lpName, lpValue: widecstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableW".}
proc GetModuleFileNameW*(handle: THandle, buf: wideCString, proc getModuleFileNameW*(handle: THandle, buf: wideCString,
size: int32): int32 {.importc, size: int32): int32 {.importc: "GetModuleFileNameW",
dynlib: "kernel32", stdcall.} dynlib: "kernel32", stdcall.}
else: else:
proc GetCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {. proc getCurrentDirectoryA*(nBufferLength: int32, lpBuffer: cstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "GetCurrentDirectoryA", dynlib: "kernel32", stdcall.}
proc SetCurrentDirectoryA*(lpPathName: cstring): int32 {. proc setCurrentDirectoryA*(lpPathName: cstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "SetCurrentDirectoryA", dynlib: "kernel32", stdcall.}
proc CreateDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {. proc createDirectoryA*(pathName: cstring, security: Pointer=nil): int32 {.
importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.} importc: "CreateDirectoryA", dynlib: "kernel32", stdcall.}
proc RemoveDirectoryA*(lpPathName: cstring): int32 {. proc removeDirectoryA*(lpPathName: cstring): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "RemoveDirectoryA", dynlib: "kernel32", stdcall.}
proc SetEnvironmentVariableA*(lpName, lpValue: cstring): int32 {. proc setEnvironmentVariableA*(lpName, lpValue: cstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "SetEnvironmentVariableA".}
proc GetModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {. proc getModuleFileNameA*(handle: THandle, buf: CString, size: int32): int32 {.
importc, dynlib: "kernel32", stdcall.} importc: "GetModuleFileNameA", dynlib: "kernel32", stdcall.}
const const
FILE_ATTRIBUTE_ARCHIVE* = 32'i32 FILE_ATTRIBUTE_ARCHIVE* = 32'i32
@ -228,65 +230,71 @@ type
cAlternateFileName*: array[0..13, TWinChar] cAlternateFileName*: array[0..13, TWinChar]
when useWinUnicode: when useWinUnicode:
proc FindFirstFileW*(lpFileName: widecstring, proc findFirstFileW*(lpFileName: widecstring,
lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. lpFindFileData: var TWIN32_FIND_DATA): THANDLE {.
stdcall, dynlib: "kernel32", importc: "FindFirstFileW".} stdcall, dynlib: "kernel32", importc: "FindFirstFileW".}
proc FindNextFileW*(hFindFile: THANDLE, proc findNextFileW*(hFindFile: THANDLE,
lpFindFileData: var TWIN32_FIND_DATA): int32 {. lpFindFileData: var TWIN32_FIND_DATA): int32 {.
stdcall, dynlib: "kernel32", importc: "FindNextFileW".} stdcall, dynlib: "kernel32", importc: "FindNextFileW".}
else: else:
proc FindFirstFileA*(lpFileName: cstring, proc findFirstFileA*(lpFileName: cstring,
lpFindFileData: var TWIN32_FIND_DATA): THANDLE {. lpFindFileData: var TWIN32_FIND_DATA): THANDLE {.
stdcall, dynlib: "kernel32", importc: "FindFirstFileA".} stdcall, dynlib: "kernel32", importc: "FindFirstFileA".}
proc FindNextFileA*(hFindFile: THANDLE, proc findNextFileA*(hFindFile: THANDLE,
lpFindFileData: var TWIN32_FIND_DATA): int32 {. lpFindFileData: var TWIN32_FIND_DATA): int32 {.
stdcall, dynlib: "kernel32", importc: "FindNextFileA".} stdcall, dynlib: "kernel32", importc: "FindNextFileA".}
proc FindClose*(hFindFile: THANDLE) {.stdcall, dynlib: "kernel32", proc findClose*(hFindFile: THANDLE) {.stdcall, dynlib: "kernel32",
importc: "FindClose".} importc: "FindClose".}
when useWinUnicode: when useWinUnicode:
proc GetFullPathNameW*(lpFileName: widecstring, nBufferLength: int32, proc getFullPathNameW*(lpFileName: widecstring, nBufferLength: int32,
lpBuffer: widecstring, lpBuffer: widecstring,
lpFilePart: var widecstring): int32 {. lpFilePart: var widecstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32",
proc GetFileAttributesW*(lpFileName: widecstring): int32 {. importc: "GetFullPathNameW".}
stdcall, dynlib: "kernel32", importc.} proc getFileAttributesW*(lpFileName: widecstring): int32 {.
proc SetFileAttributesW*(lpFileName: widecstring, stdcall, dynlib: "kernel32",
importc: "GetFileAttributesW".}
proc setFileAttributesW*(lpFileName: widecstring,
dwFileAttributes: int32): WINBOOL {. dwFileAttributes: int32): WINBOOL {.
stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".} stdcall, dynlib: "kernel32", importc: "SetFileAttributesW".}
proc CopyFileW*(lpExistingFileName, lpNewFileName: wideCString, proc copyFileW*(lpExistingFileName, lpNewFileName: wideCString,
bFailIfExists: cint): cint {. bFailIfExists: cint): cint {.
importc, stdcall, dynlib: "kernel32".} importc: "CopyFileW", stdcall, dynlib: "kernel32".}
proc GetEnvironmentStringsW*(): widecstring {. proc getEnvironmentStringsW*(): widecstring {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsW".}
proc FreeEnvironmentStringsW*(para1: widecstring): int32 {. proc freeEnvironmentStringsW*(para1: widecstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsW".}
proc GetCommandLineW*(): wideCString {.importc, stdcall, dynlib: "kernel32".} proc getCommandLineW*(): wideCString {.importc: "GetCommandLineW",
stdcall, dynlib: "kernel32".}
else: else:
proc GetFullPathNameA*(lpFileName: cstring, nBufferLength: int32, proc getFullPathNameA*(lpFileName: cstring, nBufferLength: int32,
lpBuffer: cstring, lpFilePart: var cstring): int32 {. lpBuffer: cstring, lpFilePart: var cstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32",
proc GetFileAttributesA*(lpFileName: cstring): int32 {. importc: "GetFullPathNameA".}
stdcall, dynlib: "kernel32", importc.} proc getFileAttributesA*(lpFileName: cstring): int32 {.
proc SetFileAttributesA*(lpFileName: cstring, stdcall, dynlib: "kernel32",
importc: "GetFileAttributesA".}
proc setFileAttributesA*(lpFileName: cstring,
dwFileAttributes: int32): WINBOOL {. dwFileAttributes: int32): WINBOOL {.
stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".} stdcall, dynlib: "kernel32", importc: "SetFileAttributesA".}
proc CopyFileA*(lpExistingFileName, lpNewFileName: CString, proc copyFileA*(lpExistingFileName, lpNewFileName: CString,
bFailIfExists: cint): cint {. bFailIfExists: cint): cint {.
importc, stdcall, dynlib: "kernel32".} importc: "CopyFileA", stdcall, dynlib: "kernel32".}
proc GetEnvironmentStringsA*(): cstring {. proc getEnvironmentStringsA*(): cstring {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "GetEnvironmentStringsA".}
proc FreeEnvironmentStringsA*(para1: cstring): int32 {. proc freeEnvironmentStringsA*(para1: cstring): int32 {.
stdcall, dynlib: "kernel32", importc.} stdcall, dynlib: "kernel32", importc: "FreeEnvironmentStringsA".}
proc GetCommandLineA*(): CString {.importc, stdcall, dynlib: "kernel32".} proc getCommandLineA*(): cstring {.
importc: "GetCommandLineA", stdcall, dynlib: "kernel32".}
proc rdFileTime*(f: TFILETIME): int64 = proc rdFileTime*(f: TFILETIME): int64 =
result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32) result = ze64(f.dwLowDateTime) or (ze64(f.dwHighDateTime) shl 32)
@ -294,25 +302,25 @@ proc rdFileTime*(f: TFILETIME): int64 =
proc rdFileSize*(f: TWin32FindData): int64 = proc rdFileSize*(f: TWin32FindData): int64 =
result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32) result = ze64(f.nFileSizeLow) or (ze64(f.nFileSizeHigh) shl 32)
proc GetSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {. proc getSystemTimeAsFileTime*(lpSystemTimeAsFileTime: var TFILETIME) {.
importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.} importc: "GetSystemTimeAsFileTime", dynlib: "kernel32", stdcall.}
proc Sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32", proc sleep*(dwMilliseconds: int32){.stdcall, dynlib: "kernel32",
importc: "Sleep".} importc: "Sleep".}
when useWinUnicode: when useWinUnicode:
proc ShellExecuteW*(HWND: THandle, lpOperation, lpFile, proc shellExecuteW*(HWND: THandle, lpOperation, lpFile,
lpParameters, lpDirectory: widecstring, lpParameters, lpDirectory: widecstring,
nShowCmd: int32): THandle{. nShowCmd: int32): THandle{.
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".} stdcall, dynlib: "shell32.dll", importc: "ShellExecuteW".}
else: else:
proc ShellExecuteA*(HWND: THandle, lpOperation, lpFile, proc shellExecuteA*(HWND: THandle, lpOperation, lpFile,
lpParameters, lpDirectory: cstring, lpParameters, lpDirectory: cstring,
nShowCmd: int32): THandle{. nShowCmd: int32): THandle{.
stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".} stdcall, dynlib: "shell32.dll", importc: "ShellExecuteA".}
proc GetFileInformationByHandle*(hFile: THandle, proc getFileInformationByHandle*(hFile: THandle,
lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{. lpFileInformation: ptr TBY_HANDLE_FILE_INFORMATION): WINBOOL{.
stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".} stdcall, dynlib: "kernel32", importc: "GetFileInformationByHandle".}
@ -526,7 +534,7 @@ type
TWOHandleArray* = array[0..MAXIMUM_WAIT_OBJECTS - 1, THANDLE] TWOHandleArray* = array[0..MAXIMUM_WAIT_OBJECTS - 1, THANDLE]
PWOHandleArray* = ptr TWOHandleArray PWOHandleArray* = ptr TWOHandleArray
proc WaitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray, proc waitForMultipleObjects*(nCount: DWORD, lpHandles: PWOHandleArray,
bWaitAll: WINBOOL, dwMilliseconds: DWORD): DWORD{. bWaitAll: WINBOOL, dwMilliseconds: DWORD): DWORD{.
stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".} stdcall, dynlib: "kernel32", importc: "WaitForMultipleObjects".}
@ -558,40 +566,40 @@ const
ERROR_ACCESS_DENIED* = 5 ERROR_ACCESS_DENIED* = 5
when useWinUnicode: when useWinUnicode:
proc CreateFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD, proc createFileW*(lpFileName: widecstring, dwDesiredAccess, dwShareMode: DWORD,
lpSecurityAttributes: pointer, lpSecurityAttributes: pointer,
dwCreationDisposition, dwFlagsAndAttributes: DWORD, dwCreationDisposition, dwFlagsAndAttributes: DWORD,
hTemplateFile: THANDLE): THANDLE {. hTemplateFile: THANDLE): THANDLE {.
stdcall, dynlib: "kernel32", importc: "CreateFileW".} stdcall, dynlib: "kernel32", importc: "CreateFileW".}
proc DeleteFileW*(pathName: widecstring): int32 {. proc deleteFileW*(pathName: widecstring): int32 {.
importc: "DeleteFileW", dynlib: "kernel32", stdcall.} importc: "DeleteFileW", dynlib: "kernel32", stdcall.}
else: else:
proc CreateFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD, proc createFileA*(lpFileName: cstring, dwDesiredAccess, dwShareMode: DWORD,
lpSecurityAttributes: pointer, lpSecurityAttributes: pointer,
dwCreationDisposition, dwFlagsAndAttributes: DWORD, dwCreationDisposition, dwFlagsAndAttributes: DWORD,
hTemplateFile: THANDLE): THANDLE {. hTemplateFile: THANDLE): THANDLE {.
stdcall, dynlib: "kernel32", importc: "CreateFileA".} stdcall, dynlib: "kernel32", importc: "CreateFileA".}
proc DeleteFileA*(pathName: cstring): int32 {. proc deleteFileA*(pathName: cstring): int32 {.
importc: "DeleteFileA", dynlib: "kernel32", stdcall.} importc: "DeleteFileA", dynlib: "kernel32", stdcall.}
proc SetEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32", proc setEndOfFile*(hFile: THANDLE): WINBOOL {.stdcall, dynlib: "kernel32",
importc: "SetEndOfFile".} importc: "SetEndOfFile".}
proc SetFilePointer*(hFile: THANDLE, lDistanceToMove: LONG, proc setFilePointer*(hFile: THANDLE, lDistanceToMove: LONG,
lpDistanceToMoveHigh: ptr LONG, lpDistanceToMoveHigh: ptr LONG,
dwMoveMethod: DWORD): DWORD {. dwMoveMethod: DWORD): DWORD {.
stdcall, dynlib: "kernel32", importc: "SetFilePointer".} stdcall, dynlib: "kernel32", importc: "SetFilePointer".}
proc GetFileSize*(hFile: THANDLE, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall, proc getFileSize*(hFile: THANDLE, lpFileSizeHigh: ptr DWORD): DWORD{.stdcall,
dynlib: "kernel32", importc: "GetFileSize".} dynlib: "kernel32", importc: "GetFileSize".}
proc MapViewOfFileEx*(hFileMappingObject: THANDLE, dwDesiredAccess: DWORD, proc mapViewOfFileEx*(hFileMappingObject: THANDLE, dwDesiredAccess: DWORD,
dwFileOffsetHigh, dwFileOffsetLow: DWORD, dwFileOffsetHigh, dwFileOffsetLow: DWORD,
dwNumberOfBytesToMap: DWORD, dwNumberOfBytesToMap: DWORD,
lpBaseAddress: pointer): pointer{. lpBaseAddress: pointer): pointer{.
stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".} stdcall, dynlib: "kernel32", importc: "MapViewOfFileEx".}
proc CreateFileMappingW*(hFile: THANDLE, proc createFileMappingW*(hFile: THANDLE,
lpFileMappingAttributes: pointer, lpFileMappingAttributes: pointer,
flProtect, dwMaximumSizeHigh: DWORD, flProtect, dwMaximumSizeHigh: DWORD,
dwMaximumSizeLow: DWORD, dwMaximumSizeLow: DWORD,
@ -599,12 +607,12 @@ proc CreateFileMappingW*(hFile: THANDLE,
stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".} stdcall, dynlib: "kernel32", importc: "CreateFileMappingW".}
when not useWinUnicode: when not useWinUnicode:
proc CreateFileMappingA*(hFile: THANDLE, proc createFileMappingA*(hFile: THANDLE,
lpFileMappingAttributes: pointer, lpFileMappingAttributes: pointer,
flProtect, dwMaximumSizeHigh: DWORD, flProtect, dwMaximumSizeHigh: DWORD,
dwMaximumSizeLow: DWORD, lpName: cstring): THANDLE {. dwMaximumSizeLow: DWORD, lpName: cstring): THANDLE {.
stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".} stdcall, dynlib: "kernel32", importc: "CreateFileMappingA".}
proc UnmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall, proc unmapViewOfFile*(lpBaseAddress: pointer): WINBOOL {.stdcall,
dynlib: "kernel32", importc: "UnmapViewOfFile".} dynlib: "kernel32", importc: "UnmapViewOfFile".}

View file

@ -4,6 +4,8 @@ version 0.9.4
- document new templating symbol binding rules - document new templating symbol binding rules
- convert all with "nimrod pretty" - convert all with "nimrod pretty"
- make '--implicitStatic:on' the default - make '--implicitStatic:on' the default
- test&finish first class iterators:
* nested iterators
- special rule for ``[]=`` - special rule for ``[]=``
- ``=`` should be overloadable; requires specialization for ``=``; general - ``=`` should be overloadable; requires specialization for ``=``; general
@ -11,6 +13,7 @@ version 0.9.4
- built-in 'getImpl' - built-in 'getImpl'
- optimize 'genericReset'; 'newException' leads to code bloat - optimize 'genericReset'; 'newException' leads to code bloat
- stack-less GC - stack-less GC
- fix eval in macros.nim
Bugs Bugs
@ -50,8 +53,6 @@ version 0.9.x
version 0.9.X version 0.9.X
============= =============
- test&finish first class iterators:
* nested iterators
- implement the missing features wrt inheritance - implement the missing features wrt inheritance
- better support for macros that rewrite procs - better support for macros that rewrite procs
- macros need access to types and symbols (partially implemented) - macros need access to types and symbols (partially implemented)