case consistency part 1
This commit is contained in:
parent
9e92455a53
commit
2df9b442c6
88 changed files with 1266 additions and 1144 deletions
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
|
||||||
|
|
@ -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",
|
||||||
|
|
|
||||||
|
|
@ -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"))
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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"
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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})
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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")
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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':
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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_"
|
||||||
|
|
|
||||||
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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()
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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))
|
||||||
|
|
|
||||||
|
|
@ -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.} =
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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) =
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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:
|
||||||
|
|
|
||||||
|
|
@ -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`.
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
190
lib/pure/os.nim
190
lib/pure/os.nim
|
|
@ -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 =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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 '\\':
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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])
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)]
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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.} =
|
||||||
|
|
|
||||||
|
|
@ -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):
|
||||||
#
|
#
|
||||||
|
|
|
||||||
|
|
@ -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.}
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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>".}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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".}
|
||||||
|
|
||||||
|
|
|
||||||
5
todo.txt
5
todo.txt
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue