Merge branch 'devel' of github.com:Araq/Nim into patch2
This commit is contained in:
commit
770914bc16
3 changed files with 277 additions and 249 deletions
|
|
@ -11,7 +11,7 @@
|
||||||
# and sets of nodes are supported. Efficiency is important as
|
# and sets of nodes are supported. Efficiency is important as
|
||||||
# the data structures here are used in various places of the compiler.
|
# the data structures here are used in various places of the compiler.
|
||||||
|
|
||||||
import
|
import
|
||||||
ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils
|
ast, hashes, intsets, strutils, options, msgs, ropes, idents, rodutils
|
||||||
|
|
||||||
proc hashNode*(p: RootRef): THash
|
proc hashNode*(p: RootRef): THash
|
||||||
|
|
@ -22,7 +22,7 @@ proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope
|
||||||
proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope
|
proc typeToYaml*(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope
|
||||||
proc symToYaml*(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope
|
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: RootRef): bool
|
proc objectSetContains*(t: TObjectSet, obj: RootRef): bool
|
||||||
# returns true whether n is in t
|
# returns true whether n is in t
|
||||||
|
|
@ -34,10 +34,10 @@ proc objectSetContainsOrIncl*(t: var TObjectSet, obj: RootRef): bool
|
||||||
# ----------------------- (key, val)-Hashtables ----------------------------
|
# ----------------------- (key, val)-Hashtables ----------------------------
|
||||||
proc tablePut*(t: var TTable, key, val: RootRef)
|
proc tablePut*(t: var TTable, key, val: RootRef)
|
||||||
proc tableGet*(t: TTable, key: RootRef): RootRef
|
proc tableGet*(t: TTable, key: RootRef): RootRef
|
||||||
type
|
type
|
||||||
TCmpProc* = proc (key, closure: RootRef): bool {.nimcall.} # true if found
|
TCmpProc* = proc (key, closure: RootRef): bool {.nimcall.} # true if found
|
||||||
|
|
||||||
proc tableSearch*(t: TTable, key, closure: RootRef,
|
proc tableSearch*(t: TTable, key, closure: RootRef,
|
||||||
comparator: TCmpProc): RootRef
|
comparator: TCmpProc): RootRef
|
||||||
# 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
|
||||||
|
|
@ -45,16 +45,16 @@ proc tableSearch*(t: TTable, key, closure: RootRef,
|
||||||
# ----------------------- 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
|
||||||
# s: PSym
|
# s: PSym
|
||||||
# s = InitTabIter(i, table)
|
# s = InitTabIter(i, table)
|
||||||
|
|
@ -63,7 +63,7 @@ proc nextIter*(ti: var TTabIter, tab: TStrTable): PSym
|
||||||
# s = NextIter(i, table)
|
# s = NextIter(i, table)
|
||||||
#
|
#
|
||||||
|
|
||||||
type
|
type
|
||||||
TIdentIter*{.final.} = object # iterator over all syms with same identifier
|
TIdentIter*{.final.} = object # iterator over all syms with same identifier
|
||||||
h*: THash # current hash
|
h*: THash # current hash
|
||||||
name*: PIdent
|
name*: PIdent
|
||||||
|
|
@ -97,11 +97,11 @@ proc mustRehash*(length, counter: int): bool
|
||||||
proc nextTry*(h, maxHash: THash): THash {.inline.}
|
proc nextTry*(h, maxHash: THash): THash {.inline.}
|
||||||
|
|
||||||
# ------------- table[int, int] ---------------------------------------------
|
# ------------- table[int, int] ---------------------------------------------
|
||||||
const
|
const
|
||||||
InvalidKey* = low(int)
|
InvalidKey* = low(int)
|
||||||
|
|
||||||
type
|
type
|
||||||
TIIPair*{.final.} = object
|
TIIPair*{.final.} = object
|
||||||
key*, val*: int
|
key*, val*: int
|
||||||
|
|
||||||
TIIPairSeq* = seq[TIIPair]
|
TIIPairSeq* = seq[TIIPair]
|
||||||
|
|
@ -127,21 +127,21 @@ proc skipConvAndClosure*(n: PNode): PNode =
|
||||||
result = result.sons[1]
|
result = result.sons[1]
|
||||||
else: break
|
else: break
|
||||||
|
|
||||||
proc sameValue*(a, b: PNode): bool =
|
proc sameValue*(a, b: PNode): bool =
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
|
if b.kind in {nkCharLit..nkUInt64Lit}: result = a.intVal == b.intVal
|
||||||
of nkFloatLit..nkFloat64Lit:
|
of nkFloatLit..nkFloat64Lit:
|
||||||
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
if b.kind in {nkFloatLit..nkFloat64Lit}: result = a.floatVal == b.floatVal
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal == b.strVal
|
if b.kind in {nkStrLit..nkTripleStrLit}: result = a.strVal == b.strVal
|
||||||
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")
|
||||||
discard
|
discard
|
||||||
|
|
||||||
proc leValue*(a, b: PNode): bool =
|
proc leValue*(a, b: PNode): bool =
|
||||||
# a <= b?
|
# a <= b?
|
||||||
result = false
|
result = false
|
||||||
case a.kind
|
case a.kind
|
||||||
|
|
@ -162,66 +162,66 @@ proc weakLeValue*(a, b: PNode): TImplication =
|
||||||
else:
|
else:
|
||||||
result = if leValue(a, b): impYes else: impNo
|
result = if leValue(a, b): impYes else: impNo
|
||||||
|
|
||||||
proc lookupInRecord(n: PNode, field: PIdent): PSym =
|
proc lookupInRecord(n: PNode, field: PIdent): PSym =
|
||||||
result = nil
|
result = nil
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkRecList:
|
of nkRecList:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result = lookupInRecord(n.sons[i], field)
|
result = lookupInRecord(n.sons[i], field)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
of nkRecCase:
|
of nkRecCase:
|
||||||
if (n.sons[0].kind != nkSym): internalError(n.info, "lookupInRecord")
|
if (n.sons[0].kind != nkSym): internalError(n.info, "lookupInRecord")
|
||||||
result = lookupInRecord(n.sons[0], field)
|
result = lookupInRecord(n.sons[0], field)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
case n.sons[i].kind
|
case n.sons[i].kind
|
||||||
of nkOfBranch, nkElse:
|
of nkOfBranch, nkElse:
|
||||||
result = lookupInRecord(lastSon(n.sons[i]), field)
|
result = lookupInRecord(lastSon(n.sons[i]), field)
|
||||||
if result != nil: return
|
if result != nil: return
|
||||||
else: internalError(n.info, "lookupInRecord(record case branch)")
|
else: internalError(n.info, "lookupInRecord(record case branch)")
|
||||||
of nkSym:
|
of nkSym:
|
||||||
if n.sym.name.id == field.id: result = n.sym
|
if n.sym.name.id == field.id: result = n.sym
|
||||||
else: internalError(n.info, "lookupInRecord()")
|
else: internalError(n.info, "lookupInRecord()")
|
||||||
|
|
||||||
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: RootRef): THash =
|
proc hashNode(p: RootRef): THash =
|
||||||
result = hash(cast[pointer](p))
|
result = hash(cast[pointer](p))
|
||||||
|
|
||||||
proc mustRehash(length, counter: int): bool =
|
proc mustRehash(length, counter: int): bool =
|
||||||
assert(length > counter)
|
assert(length > counter)
|
||||||
result = (length * 2 < counter * 3) or (length - counter < 4)
|
result = (length * 2 < counter * 3) or (length - counter < 4)
|
||||||
|
|
||||||
proc rspaces(x: int): PRope =
|
proc rspaces(x: int): PRope =
|
||||||
# returns x spaces
|
# returns x spaces
|
||||||
result = toRope(spaces(x))
|
result = toRope(spaces(x))
|
||||||
|
|
||||||
proc toYamlChar(c: char): string =
|
proc toYamlChar(c: char): string =
|
||||||
case c
|
case c
|
||||||
of '\0'..'\x1F', '\x80'..'\xFF': result = "\\u" & strutils.toHex(ord(c), 4)
|
of '\0'..'\x1F', '\x80'..'\xFF': result = "\\u" & strutils.toHex(ord(c), 4)
|
||||||
of '\'', '\"', '\\': result = '\\' & c
|
of '\'', '\"', '\\': result = '\\' & c
|
||||||
else: result = $c
|
else: result = $c
|
||||||
|
|
||||||
proc makeYamlString*(s: string): PRope =
|
proc makeYamlString*(s: string): PRope =
|
||||||
# We have to split long strings into many ropes. Otherwise
|
# We have to split long strings into many ropes. Otherwise
|
||||||
# this could trigger InternalError(111). See the ropes module for
|
# this could trigger InternalError(111). See the ropes module for
|
||||||
# further information.
|
# further information.
|
||||||
const MaxLineLength = 64
|
const MaxLineLength = 64
|
||||||
result = nil
|
result = nil
|
||||||
var res = "\""
|
var res = "\""
|
||||||
for i in countup(0, if s.isNil: -1 else: (len(s)-1)):
|
for i in countup(0, if s.isNil: -1 else: (len(s)-1)):
|
||||||
if (i + 1) mod MaxLineLength == 0:
|
if (i + 1) mod MaxLineLength == 0:
|
||||||
add(res, '\"')
|
add(res, '\"')
|
||||||
add(res, "\n")
|
add(res, "\n")
|
||||||
app(result, toRope(res))
|
app(result, toRope(res))
|
||||||
|
|
@ -230,161 +230,161 @@ proc makeYamlString*(s: string): PRope =
|
||||||
add(res, '\"')
|
add(res, '\"')
|
||||||
app(result, toRope(res))
|
app(result, toRope(res))
|
||||||
|
|
||||||
proc flagsToStr[T](flags: set[T]): PRope =
|
proc flagsToStr[T](flags: set[T]): PRope =
|
||||||
if flags == {}:
|
if flags == {}:
|
||||||
result = toRope("[]")
|
result = toRope("[]")
|
||||||
else:
|
else:
|
||||||
result = nil
|
result = nil
|
||||||
for x in items(flags):
|
for x in items(flags):
|
||||||
if result != nil: app(result, ", ")
|
if result != nil: app(result, ", ")
|
||||||
app(result, makeYamlString($x))
|
app(result, makeYamlString($x))
|
||||||
result = con("[", con(result, "]"))
|
result = con("[", con(result, "]"))
|
||||||
|
|
||||||
proc lineInfoToStr(info: TLineInfo): PRope =
|
proc lineInfoToStr(info: TLineInfo): PRope =
|
||||||
result = ropef("[$1, $2, $3]", [makeYamlString(toFilename(info)),
|
result = ropef("[$1, $2, $3]", [makeYamlString(toFilename(info)),
|
||||||
toRope(toLinenumber(info)),
|
toRope(toLinenumber(info)),
|
||||||
toRope(toColumn(info))])
|
toRope(toColumn(info))])
|
||||||
|
|
||||||
proc treeToYamlAux(n: PNode, marker: var IntSet,
|
proc treeToYamlAux(n: PNode, marker: var IntSet,
|
||||||
indent, maxRecDepth: int): PRope
|
indent, maxRecDepth: int): PRope
|
||||||
proc symToYamlAux(n: PSym, marker: var IntSet,
|
proc symToYamlAux(n: PSym, marker: var IntSet,
|
||||||
indent, maxRecDepth: int): PRope
|
indent, maxRecDepth: int): PRope
|
||||||
proc typeToYamlAux(n: PType, marker: var IntSet,
|
proc typeToYamlAux(n: PType, marker: var IntSet,
|
||||||
indent, maxRecDepth: int): PRope
|
indent, maxRecDepth: int): PRope
|
||||||
proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int,
|
proc strTableToYaml(n: TStrTable, marker: var IntSet, indent: int,
|
||||||
maxRecDepth: int): PRope =
|
maxRecDepth: int): PRope =
|
||||||
var istr = rspaces(indent + 2)
|
var istr = rspaces(indent + 2)
|
||||||
result = toRope("[")
|
result = toRope("[")
|
||||||
var mycount = 0
|
var mycount = 0
|
||||||
for i in countup(0, high(n.data)):
|
for i in countup(0, high(n.data)):
|
||||||
if n.data[i] != nil:
|
if n.data[i] != nil:
|
||||||
if mycount > 0: app(result, ",")
|
if mycount > 0: app(result, ",")
|
||||||
appf(result, "$N$1$2",
|
appf(result, "$N$1$2",
|
||||||
[istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
|
[istr, symToYamlAux(n.data[i], marker, indent + 2, maxRecDepth - 1)])
|
||||||
inc(mycount)
|
inc(mycount)
|
||||||
if mycount > 0: appf(result, "$N$1", [rspaces(indent)])
|
if mycount > 0: appf(result, "$N$1", [rspaces(indent)])
|
||||||
app(result, "]")
|
app(result, "]")
|
||||||
assert(mycount == n.counter)
|
assert(mycount == n.counter)
|
||||||
|
|
||||||
proc ropeConstr(indent: int, c: openArray[PRope]): PRope =
|
proc ropeConstr(indent: int, c: openArray[PRope]): PRope =
|
||||||
# array of (name, value) pairs
|
# array of (name, value) pairs
|
||||||
var istr = rspaces(indent + 2)
|
var istr = rspaces(indent + 2)
|
||||||
result = toRope("{")
|
result = toRope("{")
|
||||||
var i = 0
|
var i = 0
|
||||||
while i <= high(c):
|
while i <= high(c):
|
||||||
if i > 0: app(result, ",")
|
if i > 0: app(result, ",")
|
||||||
appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
|
appf(result, "$N$1\"$2\": $3", [istr, c[i], c[i + 1]])
|
||||||
inc(i, 2)
|
inc(i, 2)
|
||||||
appf(result, "$N$1}", [rspaces(indent)])
|
appf(result, "$N$1}", [rspaces(indent)])
|
||||||
|
|
||||||
proc symToYamlAux(n: PSym, marker: var IntSet, indent: int,
|
proc symToYamlAux(n: PSym, marker: var IntSet, indent: int,
|
||||||
maxRecDepth: int): PRope =
|
maxRecDepth: int): PRope =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
elif containsOrIncl(marker, n.id):
|
elif containsOrIncl(marker, n.id):
|
||||||
result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope(
|
result = ropef("\"$1 @$2\"", [toRope(n.name.s), toRope(
|
||||||
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
|
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
|
||||||
else:
|
else:
|
||||||
var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
|
var ast = treeToYamlAux(n.ast, marker, indent + 2, maxRecDepth - 1)
|
||||||
result = ropeConstr(indent, [toRope("kind"),
|
result = ropeConstr(indent, [toRope("kind"),
|
||||||
makeYamlString($n.kind),
|
makeYamlString($n.kind),
|
||||||
toRope("name"), makeYamlString(n.name.s),
|
toRope("name"), makeYamlString(n.name.s),
|
||||||
toRope("typ"), typeToYamlAux(n.typ, marker,
|
toRope("typ"), typeToYamlAux(n.typ, marker,
|
||||||
indent + 2, maxRecDepth - 1),
|
indent + 2, maxRecDepth - 1),
|
||||||
toRope("info"), lineInfoToStr(n.info),
|
toRope("info"), lineInfoToStr(n.info),
|
||||||
toRope("flags"), flagsToStr(n.flags),
|
toRope("flags"), flagsToStr(n.flags),
|
||||||
toRope("magic"), makeYamlString($n.magic),
|
toRope("magic"), makeYamlString($n.magic),
|
||||||
toRope("ast"), ast, toRope("options"),
|
toRope("ast"), ast, toRope("options"),
|
||||||
flagsToStr(n.options), toRope("position"),
|
flagsToStr(n.options), toRope("position"),
|
||||||
toRope(n.position)])
|
toRope(n.position)])
|
||||||
|
|
||||||
proc typeToYamlAux(n: PType, marker: var IntSet, indent: int,
|
proc typeToYamlAux(n: PType, marker: var IntSet, indent: int,
|
||||||
maxRecDepth: int): PRope =
|
maxRecDepth: int): PRope =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
elif containsOrIncl(marker, n.id):
|
elif containsOrIncl(marker, n.id):
|
||||||
result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope(
|
result = ropef("\"$1 @$2\"", [toRope($n.kind), toRope(
|
||||||
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
|
strutils.toHex(cast[ByteAddress](n), sizeof(n) * 2))])
|
||||||
else:
|
else:
|
||||||
if sonsLen(n) > 0:
|
if sonsLen(n) > 0:
|
||||||
result = toRope("[")
|
result = toRope("[")
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if i > 0: app(result, ",")
|
if i > 0: app(result, ",")
|
||||||
appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i],
|
appf(result, "$N$1$2", [rspaces(indent + 4), typeToYamlAux(n.sons[i],
|
||||||
marker, indent + 4, maxRecDepth - 1)])
|
marker, indent + 4, maxRecDepth - 1)])
|
||||||
appf(result, "$N$1]", [rspaces(indent + 2)])
|
appf(result, "$N$1]", [rspaces(indent + 2)])
|
||||||
else:
|
else:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
result = ropeConstr(indent, [toRope("kind"),
|
result = ropeConstr(indent, [toRope("kind"),
|
||||||
makeYamlString($n.kind),
|
makeYamlString($n.kind),
|
||||||
toRope("sym"), symToYamlAux(n.sym, marker,
|
toRope("sym"), symToYamlAux(n.sym, marker,
|
||||||
indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker,
|
indent + 2, maxRecDepth - 1), toRope("n"), treeToYamlAux(n.n, marker,
|
||||||
indent + 2, maxRecDepth - 1), toRope("flags"), flagsToStr(n.flags),
|
indent + 2, maxRecDepth - 1), toRope("flags"), flagsToStr(n.flags),
|
||||||
toRope("callconv"),
|
toRope("callconv"),
|
||||||
makeYamlString(CallingConvToStr[n.callConv]),
|
makeYamlString(CallingConvToStr[n.callConv]),
|
||||||
toRope("size"), toRope(n.size),
|
toRope("size"), toRope(n.size),
|
||||||
toRope("align"), toRope(n.align),
|
toRope("align"), toRope(n.align),
|
||||||
toRope("sons"), result])
|
toRope("sons"), result])
|
||||||
|
|
||||||
proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
|
proc treeToYamlAux(n: PNode, marker: var IntSet, indent: int,
|
||||||
maxRecDepth: int): PRope =
|
maxRecDepth: int): PRope =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
else:
|
else:
|
||||||
var istr = rspaces(indent + 2)
|
var istr = rspaces(indent + 2)
|
||||||
result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
|
result = ropef("{$N$1\"kind\": $2", [istr, makeYamlString($n.kind)])
|
||||||
if maxRecDepth != 0:
|
if maxRecDepth != 0:
|
||||||
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
|
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCharLit..nkInt64Lit:
|
of nkCharLit..nkInt64Lit:
|
||||||
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
|
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
|
||||||
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
appf(result, ",$N$1\"floatVal\": $2",
|
appf(result, ",$N$1\"floatVal\": $2",
|
||||||
[istr, toRope(n.floatVal.toStrMaxPrecision)])
|
[istr, toRope(n.floatVal.toStrMaxPrecision)])
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if n.strVal.isNil:
|
if n.strVal.isNil:
|
||||||
appf(result, ",$N$1\"strVal\": null", [istr])
|
appf(result, ",$N$1\"strVal\": null", [istr])
|
||||||
else:
|
else:
|
||||||
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
||||||
of nkSym:
|
of nkSym:
|
||||||
appf(result, ",$N$1\"sym\": $2",
|
appf(result, ",$N$1\"sym\": $2",
|
||||||
[istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)])
|
[istr, symToYamlAux(n.sym, marker, indent + 2, maxRecDepth)])
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if n.ident != nil:
|
if n.ident != nil:
|
||||||
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
||||||
else:
|
else:
|
||||||
appf(result, ",$N$1\"ident\": null", [istr])
|
appf(result, ",$N$1\"ident\": null", [istr])
|
||||||
else:
|
else:
|
||||||
if sonsLen(n) > 0:
|
if sonsLen(n) > 0:
|
||||||
appf(result, ",$N$1\"sons\": [", [istr])
|
appf(result, ",$N$1\"sons\": [", [istr])
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if i > 0: app(result, ",")
|
if i > 0: app(result, ",")
|
||||||
appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i],
|
appf(result, "$N$1$2", [rspaces(indent + 4), treeToYamlAux(n.sons[i],
|
||||||
marker, indent + 4, maxRecDepth - 1)])
|
marker, indent + 4, maxRecDepth - 1)])
|
||||||
appf(result, "$N$1]", [istr])
|
appf(result, "$N$1]", [istr])
|
||||||
appf(result, ",$N$1\"typ\": $2",
|
appf(result, ",$N$1\"typ\": $2",
|
||||||
[istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
|
[istr, typeToYamlAux(n.typ, marker, indent + 2, maxRecDepth)])
|
||||||
appf(result, "$N$1}", [rspaces(indent)])
|
appf(result, "$N$1}", [rspaces(indent)])
|
||||||
|
|
||||||
proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
proc treeToYaml(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
||||||
var marker = initIntSet()
|
var marker = initIntSet()
|
||||||
result = treeToYamlAux(n, marker, indent, maxRecDepth)
|
result = treeToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
|
|
||||||
proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
proc typeToYaml(n: PType, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
||||||
var marker = initIntSet()
|
var marker = initIntSet()
|
||||||
result = typeToYamlAux(n, marker, indent, maxRecDepth)
|
result = typeToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
|
|
||||||
proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
proc symToYaml(n: PSym, indent: int = 0, maxRecDepth: int = - 1): PRope =
|
||||||
var marker = initIntSet()
|
var marker = initIntSet()
|
||||||
result = symToYamlAux(n, marker, indent, maxRecDepth)
|
result = symToYamlAux(n, marker, indent, maxRecDepth)
|
||||||
|
|
||||||
proc debugTree(n: PNode, indent: int, maxRecDepth: int; renderType=false): PRope
|
proc debugTree*(n: PNode, indent: int, maxRecDepth: int; renderType=false): PRope
|
||||||
proc debugType(n: PType, maxRecDepth=100): PRope =
|
proc debugType(n: PType, maxRecDepth=100): PRope =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
else:
|
else:
|
||||||
result = toRope($n.kind)
|
result = toRope($n.kind)
|
||||||
if n.sym != nil:
|
if n.sym != nil:
|
||||||
app(result, " ")
|
app(result, " ")
|
||||||
app(result, n.sym.name.s)
|
app(result, n.sym.name.s)
|
||||||
if n.kind in IntegralTypes and n.n != nil:
|
if n.kind in IntegralTypes and n.n != nil:
|
||||||
|
|
@ -404,43 +404,43 @@ proc debugType(n: PType, maxRecDepth=100): PRope =
|
||||||
app(result, ")")
|
app(result, ")")
|
||||||
|
|
||||||
proc debugTree(n: PNode, indent: int, maxRecDepth: int;
|
proc debugTree(n: PNode, indent: int, maxRecDepth: int;
|
||||||
renderType=false): PRope =
|
renderType=false): PRope =
|
||||||
if n == nil:
|
if n == nil:
|
||||||
result = toRope("null")
|
result = toRope("null")
|
||||||
else:
|
else:
|
||||||
var istr = rspaces(indent + 2)
|
var istr = rspaces(indent + 2)
|
||||||
result = ropef("{$N$1\"kind\": $2",
|
result = ropef("{$N$1\"kind\": $2",
|
||||||
[istr, makeYamlString($n.kind)])
|
[istr, makeYamlString($n.kind)])
|
||||||
if maxRecDepth != 0:
|
if maxRecDepth != 0:
|
||||||
case n.kind
|
case n.kind
|
||||||
of nkCharLit..nkUInt64Lit:
|
of nkCharLit..nkUInt64Lit:
|
||||||
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
|
appf(result, ",$N$1\"intVal\": $2", [istr, toRope(n.intVal)])
|
||||||
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
of nkFloatLit, nkFloat32Lit, nkFloat64Lit:
|
||||||
appf(result, ",$N$1\"floatVal\": $2",
|
appf(result, ",$N$1\"floatVal\": $2",
|
||||||
[istr, toRope(n.floatVal.toStrMaxPrecision)])
|
[istr, toRope(n.floatVal.toStrMaxPrecision)])
|
||||||
of nkStrLit..nkTripleStrLit:
|
of nkStrLit..nkTripleStrLit:
|
||||||
if n.strVal.isNil:
|
if n.strVal.isNil:
|
||||||
appf(result, ",$N$1\"strVal\": null", [istr])
|
appf(result, ",$N$1\"strVal\": null", [istr])
|
||||||
else:
|
else:
|
||||||
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
appf(result, ",$N$1\"strVal\": $2", [istr, makeYamlString(n.strVal)])
|
||||||
of nkSym:
|
of nkSym:
|
||||||
appf(result, ",$N$1\"sym\": $2_$3",
|
appf(result, ",$N$1\"sym\": $2_$3",
|
||||||
[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
|
[istr, toRope(n.sym.name.s), toRope(n.sym.id)])
|
||||||
# [istr, symToYaml(n.sym, indent, maxRecDepth),
|
# [istr, symToYaml(n.sym, indent, maxRecDepth),
|
||||||
# toRope(n.sym.id)])
|
# toRope(n.sym.id)])
|
||||||
if renderType and n.sym.typ != nil:
|
if renderType and n.sym.typ != nil:
|
||||||
appf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
|
appf(result, ",$N$1\"typ\": $2", [istr, debugType(n.sym.typ, 2)])
|
||||||
of nkIdent:
|
of nkIdent:
|
||||||
if n.ident != nil:
|
if n.ident != nil:
|
||||||
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
appf(result, ",$N$1\"ident\": $2", [istr, makeYamlString(n.ident.s)])
|
||||||
else:
|
else:
|
||||||
appf(result, ",$N$1\"ident\": null", [istr])
|
appf(result, ",$N$1\"ident\": null", [istr])
|
||||||
else:
|
else:
|
||||||
if sonsLen(n) > 0:
|
if sonsLen(n) > 0:
|
||||||
appf(result, ",$N$1\"sons\": [", [istr])
|
appf(result, ",$N$1\"sons\": [", [istr])
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
if i > 0: app(result, ",")
|
if i > 0: app(result, ",")
|
||||||
appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i],
|
appf(result, "$N$1$2", [rspaces(indent + 4), debugTree(n.sons[i],
|
||||||
indent + 4, maxRecDepth - 1, renderType)])
|
indent + 4, maxRecDepth - 1, renderType)])
|
||||||
appf(result, "$N$1]", [istr])
|
appf(result, "$N$1]", [istr])
|
||||||
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
|
appf(result, ",$N$1\"info\": $2", [istr, lineInfoToStr(n.info)])
|
||||||
|
|
@ -454,25 +454,25 @@ proc debug(n: PSym) =
|
||||||
else:
|
else:
|
||||||
#writeln(stdout, ropeToStr(symToYaml(n, 0, 1)))
|
#writeln(stdout, ropeToStr(symToYaml(n, 0, 1)))
|
||||||
msgWriteln("$1_$2: $3, $4, $5, $6" % [
|
msgWriteln("$1_$2: $3, $4, $5, $6" % [
|
||||||
n.name.s, $n.id, flagsToStr(n.flags).ropeToStr,
|
n.name.s, $n.id, flagsToStr(n.flags).ropeToStr,
|
||||||
flagsToStr(n.loc.flags).ropeToStr, lineInfoToStr(n.info).ropeToStr,
|
flagsToStr(n.loc.flags).ropeToStr, lineInfoToStr(n.info).ropeToStr,
|
||||||
$n.kind])
|
$n.kind])
|
||||||
|
|
||||||
proc debug(n: PType) =
|
proc debug(n: PType) =
|
||||||
msgWriteln(ropeToStr(debugType(n)))
|
msgWriteln(ropeToStr(debugType(n)))
|
||||||
|
|
||||||
proc debug(n: PNode) =
|
proc debug(n: PNode) =
|
||||||
msgWriteln(ropeToStr(debugTree(n, 0, 100)))
|
msgWriteln(ropeToStr(debugTree(n, 0, 100)))
|
||||||
|
|
||||||
const
|
const
|
||||||
EmptySeq = @[]
|
EmptySeq = @[]
|
||||||
|
|
||||||
proc nextTry(h, maxHash: THash): THash =
|
proc nextTry(h, maxHash: THash): THash =
|
||||||
result = ((5 * h) + 1) and maxHash
|
result = ((5 * h) + 1) and maxHash
|
||||||
# For any initial h in range(maxHash), repeating that maxHash times
|
# For any initial h in range(maxHash), repeating that maxHash times
|
||||||
# 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 objectSetContains(t: TObjectSet, obj: RootRef): bool =
|
proc objectSetContains(t: TObjectSet, obj: RootRef): bool =
|
||||||
# returns true whether n is in t
|
# returns true whether n is in t
|
||||||
var h: THash = hashNode(obj) and high(t.data) # start with real hash value
|
var h: THash = hashNode(obj) and high(t.data) # start with real hash value
|
||||||
|
|
@ -490,94 +490,94 @@ proc objectSetRawInsert(data: var TObjectSeq, obj: RootRef) =
|
||||||
assert(data[h] == nil)
|
assert(data[h] == nil)
|
||||||
data[h] = obj
|
data[h] = obj
|
||||||
|
|
||||||
proc objectSetEnlarge(t: var TObjectSet) =
|
proc objectSetEnlarge(t: var TObjectSet) =
|
||||||
var n: TObjectSeq
|
var n: TObjectSeq
|
||||||
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: objectSetRawInsert(n, t.data[i])
|
if t.data[i] != nil: objectSetRawInsert(n, t.data[i])
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
||||||
proc objectSetIncl(t: var TObjectSet, obj: RootRef) =
|
proc objectSetIncl(t: var TObjectSet, obj: RootRef) =
|
||||||
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
|
if mustRehash(len(t.data), t.counter): objectSetEnlarge(t)
|
||||||
objectSetRawInsert(t.data, obj)
|
objectSetRawInsert(t.data, obj)
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
|
|
||||||
proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
|
proc objectSetContainsOrIncl(t: var TObjectSet, obj: RootRef): bool =
|
||||||
# returns true if obj is already in the string table:
|
# returns true if obj is already in the string table:
|
||||||
var h: THash = hashNode(obj) and high(t.data)
|
var h: THash = hashNode(obj) and high(t.data)
|
||||||
while true:
|
while true:
|
||||||
var it = t.data[h]
|
var it = t.data[h]
|
||||||
if it == nil: break
|
if it == nil: break
|
||||||
if it == obj:
|
if it == obj:
|
||||||
return true # found it
|
return true # found it
|
||||||
h = nextTry(h, high(t.data))
|
h = nextTry(h, high(t.data))
|
||||||
if mustRehash(len(t.data), t.counter):
|
if mustRehash(len(t.data), t.counter):
|
||||||
objectSetEnlarge(t)
|
objectSetEnlarge(t)
|
||||||
objectSetRawInsert(t.data, obj)
|
objectSetRawInsert(t.data, obj)
|
||||||
else:
|
else:
|
||||||
assert(t.data[h] == nil)
|
assert(t.data[h] == nil)
|
||||||
t.data[h] = obj
|
t.data[h] = obj
|
||||||
inc(t.counter)
|
inc(t.counter)
|
||||||
result = false
|
result = false
|
||||||
|
|
||||||
proc tableRawGet(t: TTable, key: RootRef): int =
|
proc tableRawGet(t: TTable, key: RootRef): 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:
|
||||||
return h
|
return h
|
||||||
h = nextTry(h, high(t.data))
|
h = nextTry(h, high(t.data))
|
||||||
result = -1
|
result = -1
|
||||||
|
|
||||||
proc tableSearch(t: TTable, key, closure: RootRef,
|
proc tableSearch(t: TTable, key, closure: RootRef,
|
||||||
comparator: TCmpProc): RootRef =
|
comparator: TCmpProc): RootRef =
|
||||||
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:
|
||||||
if comparator(t.data[h].val, closure):
|
if comparator(t.data[h].val, closure):
|
||||||
# BUGFIX 1
|
# BUGFIX 1
|
||||||
return t.data[h].val
|
return t.data[h].val
|
||||||
h = nextTry(h, high(t.data))
|
h = nextTry(h, high(t.data))
|
||||||
result = nil
|
result = nil
|
||||||
|
|
||||||
proc tableGet(t: TTable, key: RootRef): RootRef =
|
proc tableGet(t: TTable, key: RootRef): RootRef =
|
||||||
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: RootRef) =
|
proc tableRawInsert(data: var TPairSeq, key, val: RootRef) =
|
||||||
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))
|
||||||
assert(data[h].key == nil)
|
assert(data[h].key == nil)
|
||||||
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: RootRef) =
|
proc tablePut(t: var TTable, key, val: RootRef) =
|
||||||
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):
|
||||||
return true
|
return true
|
||||||
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)
|
||||||
if sfImmediate notin n.flags:
|
if sfImmediate notin n.flags:
|
||||||
# fast path:
|
# fast path:
|
||||||
|
|
@ -614,18 +614,18 @@ proc symTabReplaceRaw(data: var TSymSeq, prevSym: PSym, newSym: PSym) =
|
||||||
return
|
return
|
||||||
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)
|
||||||
|
|
@ -666,103 +666,103 @@ 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]
|
||||||
if result == nil: break
|
if result == nil: break
|
||||||
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 = ti.h and high(tab.data)
|
var h = ti.h and high(tab.data)
|
||||||
var start = h
|
var start = h
|
||||||
result = tab.data[h]
|
result = tab.data[h]
|
||||||
while result != nil:
|
while result != nil:
|
||||||
if result.name.id == ti.name.id: break
|
if result.name.id == ti.name.id: break
|
||||||
h = nextTry(h, high(tab.data))
|
h = nextTry(h, high(tab.data))
|
||||||
if h == start:
|
if h == start:
|
||||||
result = nil
|
result = nil
|
||||||
break
|
break
|
||||||
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: IntSet): PSym =
|
excluding: IntSet): 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
|
||||||
result = tab.data[h]
|
result = tab.data[h]
|
||||||
while result != nil:
|
while result != nil:
|
||||||
if result.name.id == ti.name.id and not contains(excluding, result.id):
|
if result.name.id == ti.name.id and not contains(excluding, result.id):
|
||||||
break
|
break
|
||||||
h = nextTry(h, high(tab.data))
|
h = nextTry(h, high(tab.data))
|
||||||
if h == start:
|
if h == start:
|
||||||
result = nil
|
result = nil
|
||||||
break
|
break
|
||||||
result = tab.data[h]
|
result = tab.data[h]
|
||||||
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: IntSet): PSym =
|
excluding: IntSet): 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)):
|
||||||
if data[h].key == nil:
|
if data[h].key == nil:
|
||||||
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:
|
||||||
if t.data[h].key.id == key:
|
if t.data[h].key.id == key:
|
||||||
return h
|
return h
|
||||||
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): RootRef =
|
proc idTableGet(t: TIdTable, key: PIdObj): RootRef =
|
||||||
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): RootRef =
|
proc idTableGet(t: TIdTable, key: int): RootRef =
|
||||||
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
|
||||||
|
|
@ -771,30 +771,30 @@ iterator pairs*(t: TIdTable): tuple[key: int, value: RootRef] =
|
||||||
for i in 0..high(t.data):
|
for i in 0..high(t.data):
|
||||||
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: RootRef) =
|
proc idTableRawInsert(data: var TIdPairSeq, key: PIdObj, val: RootRef) =
|
||||||
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:
|
||||||
assert(data[h].key.id != key.id)
|
assert(data[h].key.id != key.id)
|
||||||
h = nextTry(h, high(data))
|
h = nextTry(h, high(data))
|
||||||
assert(data[h].key == nil)
|
assert(data[h].key == nil)
|
||||||
data[h].key = key
|
data[h].key = key
|
||||||
data[h].val = val
|
data[h].val = val
|
||||||
|
|
||||||
proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
|
proc idTablePut(t: var TIdTable, key: PIdObj, val: RootRef) =
|
||||||
var
|
var
|
||||||
index: int
|
index: int
|
||||||
n: TIdPairSeq
|
n: TIdPairSeq
|
||||||
index = idTableRawGet(t, key.id)
|
index = idTableRawGet(t, key.id)
|
||||||
if index >= 0:
|
if index >= 0:
|
||||||
assert(t.data[index].key != nil)
|
assert(t.data[index].key != nil)
|
||||||
t.data[index].val = val
|
t.data[index].val = val
|
||||||
else:
|
else:
|
||||||
if mustRehash(len(t.data), t.counter):
|
if mustRehash(len(t.data), t.counter):
|
||||||
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:
|
||||||
idTableRawInsert(n, t.data[i].key, t.data[i].val)
|
idTableRawInsert(n, t.data[i].key, t.data[i].val)
|
||||||
assert(hasEmptySlot(n))
|
assert(hasEmptySlot(n))
|
||||||
swap(t.data, n)
|
swap(t.data, n)
|
||||||
|
|
@ -805,7 +805,7 @@ iterator idTablePairs*(t: TIdTable): tuple[key: PIdObj, val: RootRef] =
|
||||||
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 idNodeTableRawGet(t: TIdNodeTable, key: PIdObj): int =
|
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:
|
||||||
|
|
@ -814,7 +814,7 @@ 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
|
||||||
|
|
@ -823,28 +823,28 @@ proc idNodeTableGet(t: TIdNodeTable, key: PIdObj): PNode =
|
||||||
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:
|
||||||
assert(data[h].key.id != key.id)
|
assert(data[h].key.id != key.id)
|
||||||
h = nextTry(h, high(data))
|
h = nextTry(h, high(data))
|
||||||
assert(data[h].key == nil)
|
assert(data[h].key == nil)
|
||||||
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)
|
||||||
t.data[index].val = val
|
t.data[index].val = val
|
||||||
else:
|
else:
|
||||||
if mustRehash(len(t.data), t.counter):
|
if mustRehash(len(t.data), t.counter):
|
||||||
var n: TIdNodePairSeq
|
var n: TIdNodePairSeq
|
||||||
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)
|
||||||
|
|
@ -858,46 +858,46 @@ iterator pairs*(t: TIdNodeTable): tuple[key: PIdObj, val: PNode] =
|
||||||
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 initIITable(x: var TIITable) =
|
proc initIITable(x: var TIITable) =
|
||||||
x.counter = 0
|
x.counter = 0
|
||||||
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: return h
|
if t.data[h].key == key: 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:
|
||||||
assert(data[h].key != key)
|
assert(data[h].key != key)
|
||||||
h = nextTry(h, high(data))
|
h = nextTry(h, high(data))
|
||||||
assert(data[h].key == InvalidKey)
|
assert(data[h].key == InvalidKey)
|
||||||
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)
|
||||||
t.data[index].val = val
|
t.data[index].val = val
|
||||||
else:
|
else:
|
||||||
if mustRehash(len(t.data), t.counter):
|
if mustRehash(len(t.data), t.counter):
|
||||||
var n: TIIPairSeq
|
var n: TIIPairSeq
|
||||||
newSeq(n, len(t.data) * GrowthFactor)
|
newSeq(n, len(t.data) * GrowthFactor)
|
||||||
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)
|
||||||
|
|
|
||||||
|
|
@ -291,6 +291,24 @@ y.v() --> y.v() is correct
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
proc skipAddrDeref(node: PNode): PNode =
|
||||||
|
var n = node
|
||||||
|
var isAddr = false
|
||||||
|
case n.kind
|
||||||
|
of nkAddr, nkHiddenAddr:
|
||||||
|
n = n.sons[0]
|
||||||
|
isAddr = true
|
||||||
|
of nkDerefExpr, nkHiddenDeref:
|
||||||
|
n = n.sons[0]
|
||||||
|
else: return n
|
||||||
|
if n.kind == nkObjDownConv: n = n.sons[0]
|
||||||
|
if isAddr and n.kind in {nkDerefExpr, nkHiddenDeref}:
|
||||||
|
result = n.sons[0]
|
||||||
|
elif n.kind in {nkAddr, nkHiddenAddr}:
|
||||||
|
result = n.sons[0]
|
||||||
|
else:
|
||||||
|
result = node
|
||||||
|
|
||||||
proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||||
# for better or worse c2nim translates the 'this' argument to a 'var T'.
|
# for better or worse c2nim translates the 'this' argument to a 'var T'.
|
||||||
# However manual wrappers may also use 'ptr T'. In any case we support both
|
# However manual wrappers may also use 'ptr T'. In any case we support both
|
||||||
|
|
@ -301,7 +319,8 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||||
# skip the deref:
|
# skip the deref:
|
||||||
var ri = ri[i]
|
var ri = ri[i]
|
||||||
while ri.kind == nkObjDownConv: ri = ri[0]
|
while ri.kind == nkObjDownConv: ri = ri[0]
|
||||||
if typ.sons[i].kind == tyVar:
|
let t = typ.sons[i].skipTypes({tyGenericInst})
|
||||||
|
if t.kind == tyVar:
|
||||||
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
|
let x = if ri.kind == nkHiddenAddr: ri[0] else: ri
|
||||||
if x.typ.kind == tyPtr:
|
if x.typ.kind == tyPtr:
|
||||||
result = genArgNoParam(p, x)
|
result = genArgNoParam(p, x)
|
||||||
|
|
@ -312,7 +331,7 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||||
else:
|
else:
|
||||||
result = genArgNoParam(p, x)
|
result = genArgNoParam(p, x)
|
||||||
result.app(".")
|
result.app(".")
|
||||||
elif typ.sons[i].kind == tyPtr:
|
elif t.kind == tyPtr:
|
||||||
if ri.kind in {nkAddr, nkHiddenAddr}:
|
if ri.kind in {nkAddr, nkHiddenAddr}:
|
||||||
result = genArgNoParam(p, ri[0])
|
result = genArgNoParam(p, ri[0])
|
||||||
result.app(".")
|
result.app(".")
|
||||||
|
|
@ -320,6 +339,8 @@ proc genThisArg(p: BProc; ri: PNode; i: int; typ: PType): PRope =
|
||||||
result = genArgNoParam(p, ri)
|
result = genArgNoParam(p, ri)
|
||||||
result.app("->")
|
result.app("->")
|
||||||
else:
|
else:
|
||||||
|
ri = skipAddrDeref(ri)
|
||||||
|
if ri.kind in {nkAddr, nkHiddenAddr}: ri = ri[0]
|
||||||
result = genArgNoParam(p, ri) #, typ.n.sons[i].sym)
|
result = genArgNoParam(p, ri) #, typ.n.sons[i].sym)
|
||||||
result.app(".")
|
result.app(".")
|
||||||
|
|
||||||
|
|
@ -354,6 +375,11 @@ proc genPatternCall(p: BProc; ri: PNode; pat: string; typ: PType): PRope =
|
||||||
elif pat[i+1] == '.':
|
elif pat[i+1] == '.':
|
||||||
result.app genThisArg(p, ri, j, typ)
|
result.app genThisArg(p, ri, j, typ)
|
||||||
inc i
|
inc i
|
||||||
|
elif pat[i+1] == '[':
|
||||||
|
var arg = ri.sons[j].skipAddrDeref
|
||||||
|
while arg.kind in {nkAddr, nkHiddenAddr, nkObjDownConv}: arg = arg[0]
|
||||||
|
result.app genArgNoParam(p, arg)
|
||||||
|
#result.app debugTree(arg, 0, 10)
|
||||||
else:
|
else:
|
||||||
result.app genOtherArg(p, ri, j, typ)
|
result.app genOtherArg(p, ri, j, typ)
|
||||||
inc j
|
inc j
|
||||||
|
|
|
||||||
|
|
@ -541,6 +541,8 @@ elif defined(JS):
|
||||||
|
|
||||||
proc getTimezone(): int = result = newDate().getTimezoneOffset()
|
proc getTimezone(): int = result = newDate().getTimezoneOffset()
|
||||||
|
|
||||||
|
proc epochTime*(): float {.tags: [TimeEffect].} = newDate().toSeconds()
|
||||||
|
|
||||||
proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} =
|
proc getDateStr*(): string {.rtl, extern: "nt$1", tags: [TimeEffect].} =
|
||||||
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
## gets the current date as a string of the format ``YYYY-MM-DD``.
|
||||||
var ti = getLocalTime(getTime())
|
var ti = getLocalTime(getTime())
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue