got rid of nstrtabs and nhashes modules

This commit is contained in:
Araq
2011-06-10 22:49:06 +02:00
parent 988de05707
commit 922e216b86
20 changed files with 57 additions and 362 deletions

View File

@@ -10,7 +10,7 @@
# abstract syntax tree + symbol table
import
msgs, nhashes, nversion, options, strutils, crc, ropes, idents, lists
msgs, hashes, nversion, options, strutils, crc, ropes, idents, lists
const
ImportTablePos* = 0

View File

@@ -12,7 +12,7 @@
# the data structures here are used in various places of the compiler.
import
ast, nhashes, strutils, options, msgs, ropes, idents, rodutils
ast, hashes, strutils, options, msgs, ropes, idents, rodutils
proc hashNode*(p: PObject): THash
proc treeToYaml*(n: PNode, indent: int = 0, maxRecDepth: int = - 1): PRope
@@ -179,7 +179,7 @@ proc getSymFromList(list: PNode, ident: PIdent, start: int = 0): PSym =
result = nil
proc hashNode(p: PObject): THash =
result = hashPtr(cast[pointer](p))
result = hash(cast[pointer](p))
proc mustRehash(length, counter: int): bool =
assert(length > counter)

View File

@@ -10,7 +10,7 @@
# This module declares some helpers for the C code generator.
import
ast, astalgo, ropes, lists, nhashes, strutils, types, msgs, wordrecg,
ast, astalgo, ropes, lists, hashes, strutils, types, msgs, wordrecg,
platform
proc whichPragma*(n: PNode): TSpecialWord =

View File

@@ -11,7 +11,7 @@
# than the old one. It also generates better code.
import
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
options,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,

View File

@@ -10,7 +10,7 @@
# This module handles the conditional symbols.
import
ast, astalgo, msgs, nhashes, platform, strutils, idents
ast, astalgo, msgs, hashes, platform, strutils, idents
var gSymbols*: TStrTable

View File

@@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2010 Andreas Rumpf
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -12,7 +12,7 @@
# by knowing how the anchors are going to be named.
import
ast, astalgo, strutils, nhashes, options, nversion, msgs, os, ropes, idents,
ast, astalgo, strutils, hashes, options, nversion, msgs, os, ropes, idents,
wordrecg, math, syntaxes, renderer, lexer, rst, times, highlite
proc CommandDoc*(filename: string)

View File

@@ -12,7 +12,7 @@
# code!**
import
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
ast, astalgo, strutils, hashes, trees, platform, magicsys, extccomp,
options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os,
times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils

View File

@@ -12,7 +12,7 @@
# The interface supports one language nested in another.
import
nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, lexer
hashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, lexer
type
TTokenClass* = enum

View File

@@ -12,7 +12,7 @@
# id. This module is essential for the compiler's performance.
import
nhashes, strutils
hashes, strutils
type
TIdObj* = object of TObject
@@ -80,7 +80,7 @@ proc cmpExact(a, b: cstring, blen: int): int =
proc getIdent(identifier: string): PIdent =
result = getIdent(cstring(identifier), len(identifier),
getNormalizedHash(identifier))
hashIgnoreStyle(identifier))
proc getIdent(identifier: string, h: THash): PIdent =
result = getIdent(cstring(identifier), len(identifier), h)

View File

@@ -16,7 +16,7 @@
# DOS or Macintosh text files, even when it is not the native format.
import
nhashes, options, msgs, strutils, platform, idents, lexbase, llstream,
hashes, options, msgs, strutils, platform, idents, lexbase, llstream,
wordrecg
const
@@ -546,17 +546,17 @@ proc getSymbol(L: var TLexer, tok: var TToken) =
var c = buf[pos]
case c
of 'a'..'z', '0'..'9', '\x80'..'\xFF':
h = concHash(h, ord(c))
h = h !& ord(c)
of 'A'..'Z':
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = concHash(h, ord(c))
of '_':
h = h !& ord(c)
of '_':
if buf[pos+1] notin SymChars:
lexMessage(L, errInvalidToken, "_")
break
else: break
Inc(pos)
h = finishHash(h)
h = !$h
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
L.bufpos = pos
if (tok.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
@@ -567,7 +567,7 @@ proc getSymbol(L: var TLexer, tok: var TToken) =
proc endOperator(L: var TLexer, tok: var TToken, pos: int,
hash: THash) {.inline.} =
var h = finishHash(hash)
var h = !$hash
tok.ident = getIdent(addr(L.buf[L.bufpos]), pos - L.bufpos, h)
if (tok.ident.id < oprLow) or (tok.ident.id > oprHigh): tok.tokType = tkOpr
else: tok.tokType = TTokType(tok.ident.id - oprLow + ord(tkColon))
@@ -580,7 +580,7 @@ proc getOperator(L: var TLexer, tok: var TToken) =
while true:
var c = buf[pos]
if c notin OpChars: break
h = concHash(h, Ord(c))
h = h !& Ord(c)
Inc(pos)
endOperator(L, tok, pos, h)
@@ -678,7 +678,7 @@ proc rawGetTok(L: var TLexer, tok: var TToken) =
# '*:' is unfortunately a special case, because it is two tokens in
# 'var v*: int'.
if L.buf[L.bufpos+1] == ':' and L.buf[L.bufpos+2] notin OpChars:
var h = concHash(0, ord('*'))
var h = 0 !& ord('*')
endOperator(L, tok, L.bufpos+1, h)
else:
getOperator(L, tok)

View File

@@ -1,7 +1,7 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2010 Andreas Rumpf
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
@@ -10,7 +10,7 @@
# Built-in types and compilerprocs are registered here.
import
ast, astalgo, nhashes, msgs, platform, nversion, times, idents, rodread
ast, astalgo, hashes, msgs, platform, nversion, times, idents, rodread
var SystemModule*: PSym
@@ -69,7 +69,7 @@ proc getSysType(kind: TTypeKind): PType =
if result == nil: InternalError("type not found: " & $kind)
proc getCompilerProc(name: string): PSym =
var ident = getIdent(name, getNormalizedHash(name))
var ident = getIdent(name, hashIgnoreStyle(name))
result = StrTableGet(compilerprocs, ident)
if result == nil:
result = StrTableGet(rodCompilerProcs, ident)

View File

@@ -1,138 +0,0 @@
#
#
# The Nimrod Compiler
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
import
strutils
const
SmallestSize* = (1 shl 3) - 1
DefaultSize* = (1 shl 11) - 1
BiggestSize* = (1 shl 28) - 1
type
THash* = int
PHash* = ref THash
THashFunc* = proc (str: cstring): THash
proc concHash*(h: THash, val: int): THash {.inline.} =
result = h +% val
result = result +% result shl 10
result = result xor (result shr 6)
proc finishHash*(h: THash): THash {.inline.} =
result = h +% h shl 3
result = result xor (result shr 11)
result = result +% result shl 15
proc GetDataHash*(Data: Pointer, Size: int): THash =
var
h: THash
p: cstring
i, s: int
h = 0
p = cast[cstring](Data)
i = 0
s = size
while s > 0:
h = h +% ord(p[i])
h = h +% h shl 10
h = h xor (h shr 6)
Inc(i)
Dec(s)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)
proc hashPtr*(p: Pointer): THash =
result = (cast[THash](p)) shr 3 # skip the alignment
proc GetHash*(str: cstring): THash =
var
h: THash
i: int
h = 0
i = 0
while str[i] != '\0':
h = h +% ord(str[i])
h = h +% h shl 10
h = h xor (h shr 6)
Inc(i)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)
proc GetHashStr*(s: string): THash =
var h: THash
h = 0
for i in countup(1, len(s)):
h = h +% ord(s[i])
h = h +% h shl 10
h = h xor (h shr 6)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)
proc getNormalizedHash*(s: string): THash =
var
h: THash
c: Char
h = 0
for i in countup(0, len(s) + 0 - 1):
c = s[i]
if c == '_':
continue # skip _
if c in {'A'..'Z'}:
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = h +% ord(c)
h = h +% h shl 10
h = h xor (h shr 6)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)
proc GetHashStrCI*(s: string): THash =
var
h: THash
c: Char
h = 0
for i in countup(0, len(s) + 0 - 1):
c = s[i]
if c in {'A'..'Z'}:
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = h +% ord(c)
h = h +% h shl 10
h = h xor (h shr 6)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)
proc GetHashCI*(str: cstring): THash =
var
h: THash
c: Char
i: int
h = 0
i = 0
while str[i] != '\0':
c = str[i]
if c in {'A'..'Z'}:
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = h +% ord(c)
h = h +% h shl 10
h = h xor (h shr 6)
Inc(i)
h = h +% h shl 3
h = h xor (h shr 11)
h = h +% h shl 15
result = THash(h)

View File

@@ -1,171 +0,0 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2009 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
# String tables.
import
os, nhashes, strutils
type
TStringTableMode* = enum
modeCaseSensitive, # the table is case sensitive
modeCaseInsensitive, # the table is case insensitive
modeStyleInsensitive # the table is style insensitive
TKeyValuePair* = tuple[key, val: string]
TKeyValuePairSeq* = seq[TKeyValuePair]
TStringTable* = object of TObject
counter*: int
data*: TKeyValuePairSeq
mode*: TStringTableMode
PStringTable* = ref TStringTable
proc newStringTable*(keyValuePairs: openarray[string],
mode: TStringTableMode = modeCaseSensitive): PStringTable
proc put*(t: PStringTable, key, val: string)
proc get*(t: PStringTable, key: string): string
proc hasKey*(t: PStringTable, key: string): bool
proc length*(t: PStringTable): int
type
TFormatFlag* = enum
useEnvironment, # use environment variable if the ``$key``
# is not found in the table
useEmpty, # use the empty string as a default, thus it
# won't throw an exception if ``$key`` is not
# in the table
useKey # do not replace ``$key`` if it is not found
# in the table (or in the environment)
TFormatFlags* = set[TFormatFlag]
proc `%`*(f: string, t: PStringTable, flags: TFormatFlags = {}): string
# implementation
const
growthFactor = 2
startSize = 64
proc newStringTable(keyValuePairs: openarray[string],
mode: TStringTableMode = modeCaseSensitive): PStringTable =
new(result)
result.mode = mode
result.counter = 0
newSeq(result.data, startSize)
var i = 0
while i < high(keyValuePairs):
put(result, keyValuePairs[i], keyValuePairs[i + 1])
inc(i, 2)
proc myhash(t: PStringTable, key: string): THash =
case t.mode
of modeCaseSensitive: result = nhashes.GetHashStr(key)
of modeCaseInsensitive: result = nhashes.GetHashStrCI(key)
of modeStyleInsensitive: result = nhashes.getNormalizedHash(key)
proc myCmp(t: PStringTable, a, b: string): bool =
case t.mode
of modeCaseSensitive: result = cmp(a, b) == 0
of modeCaseInsensitive: result = cmpIgnoreCase(a, b) == 0
of modeStyleInsensitive: result = cmpIgnoreStyle(a, b) == 0
proc mustRehash(length, counter: int): bool =
assert(length > counter)
result = (length * 2 < counter * 3) or (length - counter < 4)
proc length(t: PStringTable): int =
result = t.counter
proc nextTry(h, maxHash: THash): THash =
result = ((5 * h) + 1) and maxHash
# For any initial h in range(maxHash), repeating that maxHash times
# generates each int in range(maxHash) exactly once (see any text on
# random-number generation for proof).
proc RawGet(t: PStringTable, key: string): int =
var h = myhash(t, key) and high(t.data) # start with real hash value
while not isNil(t.data[h].key):
if mycmp(t, t.data[h].key, key):
return h
h = nextTry(h, high(t.data))
result = - 1
proc get(t: PStringTable, key: string): string =
var index = RawGet(t, key)
if index >= 0: result = t.data[index].val
else: result = ""
proc hasKey(t: PStringTable, key: string): bool =
result = rawGet(t, key) >= 0
proc RawInsert(t: PStringTable, data: var TKeyValuePairSeq, key, val: string) =
var h = myhash(t, key) and high(data)
while not isNil(data[h].key):
h = nextTry(h, high(data))
data[h].key = key
data[h].val = val
proc Enlarge(t: PStringTable) =
var n: TKeyValuePairSeq
newSeq(n, len(t.data) * growthFactor)
for i in countup(0, high(t.data)):
if not isNil(t.data[i].key): RawInsert(t, n, t.data[i].key, t.data[i].val)
swap(t.data, n)
proc Put(t: PStringTable, key, val: string) =
var index = RawGet(t, key)
if index >= 0:
t.data[index].val = val
else:
if mustRehash(len(t.data), t.counter): Enlarge(t)
RawInsert(t, t.data, key, val)
inc(t.counter)
proc RaiseFormatException(s: string) =
var e: ref EInvalidValue
new(e)
e.msg = "format string: key not found: " & s
raise e
proc getValue(t: PStringTable, flags: TFormatFlags, key: string): string =
if hasKey(t, key): return get(t, key)
if useEnvironment in flags: result = os.getEnv(key)
else: result = ""
if result.len == 0:
if useKey in flags: result = '$' & key
elif not (useEmpty in flags): raiseFormatException(key)
proc `%`(f: string, t: PStringTable, flags: TFormatFlags = {}): string =
const
PatternChars = {'a'..'z', 'A'..'Z', '0'..'9', '_', '\x80'..'\xFF'}
result = ""
var i = 0
while i <= len(f) + 0 - 1:
if f[i] == '$':
case f[i + 1]
of '$':
add(result, '$')
inc(i, 2)
of '{':
var j = i + 1
while (j <= len(f) + 0 - 1) and (f[j] != '}'): inc(j)
var key = substr(f, i + 2 + 0 - 1, j - 1 + 0 - 1)
add(result, getValue(t, flags, key))
i = j + 1
of 'a'..'z', 'A'..'Z', '\x80'..'\xFF', '_':
var j = i + 1
while (j <= len(f) + 0 - 1) and (f[j] in PatternChars): inc(j)
var key = substr(f, i + 1 + 0 - 1, j - 1 + 0 - 1)
add(result, getValue(t, flags, key))
i = j
else:
add(result, f[i])
inc(i)
else:
add(result, f[i])
inc(i)

View File

@@ -8,7 +8,7 @@
#
import
os, lists, strutils, nstrtabs
os, lists, strutils, strtabs
const
hasTinyCBackend* = defined(tinyc)
@@ -117,10 +117,10 @@ proc existsConfigVar(key: string): bool =
result = hasKey(gConfigVars, key)
proc getConfigVar(key: string): string =
result = nstrtabs.get(gConfigVars, key)
result = gConfigVars[key]
proc setConfigVar(key, val: string) =
nstrtabs.put(gConfigVars, key, val)
gConfigVars[key] = val
proc getOutFile*(filename, ext: string): string =
if options.outFile != "": result = options.outFile
@@ -204,4 +204,4 @@ proc binaryStrSearch(x: openarray[string], y: string): int =
return mid
result = - 1
gConfigVars = newStringTable([], modeStyleInsensitive)
gConfigVars = newStringTable(modeStyleInsensitive)

View File

@@ -59,7 +59,7 @@
#
import
msgs, strutils, platform, nhashes, crc
msgs, strutils, platform, hashes, crc
const
CacheLeafs* = true

View File

@@ -11,7 +11,7 @@
# subset is provided.
import
os, msgs, strutils, platform, nhashes, ropes, options
os, msgs, strutils, platform, hashes, ropes, options
type
TRstNodeKind* = enum

View File

@@ -10,7 +10,7 @@
# This module implements the semantic checking pass.
import
strutils, nhashes, lists, options, lexer, ast, astalgo, trees, treetab,
strutils, hashes, lists, options, lexer, ast, astalgo, trees, treetab,
wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer,
procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest

View File

@@ -10,7 +10,7 @@
# Implements a table from trees to trees. Does structural equavilent checking.
import
nhashes, ast, astalgo, types
hashes, ast, astalgo, types
proc hashTree(n: PNode): THash =
if n == nil: return
@@ -19,20 +19,20 @@ proc hashTree(n: PNode): THash =
of nkEmpty, nkNilLit, nkType:
nil
of nkIdent:
result = concHash(result, n.ident.h)
of nkSym:
result = concHash(result, n.sym.name.h)
result = result !& n.ident.h
of nkSym:
result = result !& n.sym.name.h
of nkCharLit..nkInt64Lit:
if (n.intVal >= low(int)) and (n.intVal <= high(int)):
result = concHash(result, int(n.intVal))
of nkFloatLit..nkFloat64Lit:
result = result !& int(n.intVal)
of nkFloatLit..nkFloat64Lit:
if (n.floatVal >= - 1000000.0) and (n.floatVal <= 1000000.0):
result = concHash(result, toInt(n.floatVal))
result = result !& toInt(n.floatVal)
of nkStrLit..nkTripleStrLit:
result = concHash(result, GetHashStr(n.strVal))
result = result !& hash(n.strVal)
else:
for i in countup(0, sonsLen(n) - 1):
result = concHash(result, hashTree(n.sons[i]))
result = result !& hashTree(n.sons[i])
proc TreesEquivalent(a, b: PNode): bool =
if a == b:

View File

@@ -14,7 +14,7 @@
# be slow and unreadable.
import
nhashes, strutils, idents
hashes, strutils, idents
# Keywords must be kept sorted and within a range
@@ -124,6 +124,6 @@ proc whichKeyword*(id: String): TSpecialWord =
proc initSpecials() =
# initialize the keywords:
for s in countup(succ(low(specialWords)), high(specialWords)):
getIdent(specialWords[s], getNormalizedHash(specialWords[s])).id = ord(s)
getIdent(specialWords[s], hashIgnoreStyle(specialWords[s])).id = ord(s)
initSpecials()

View File

@@ -18,12 +18,16 @@ type
## always have a size of a power of two and can use the ``and``
## operator instead of ``mod`` for truncation of the hash value.
proc concHash(h: THash, val: int): THash {.inline.} =
proc `!&`*(h: THash, val: int): THash {.inline.} =
## mixes a hash value `h` with `val` to produce a new hash value. This is
## only needed if you need to implement a hash proc for a new datatype.
result = h +% val
result = result +% result shl 10
result = result xor (result shr 6)
proc finishHash(h: THash): THash {.inline.} =
proc `!$`*(h: THash): THash {.inline.} =
## finishes the computation of the hash value. This is
## only needed if you need to implement a hash proc for a new datatype.
result = h +% h shl 3
result = result xor (result shr 11)
result = result +% result shl 15
@@ -35,10 +39,10 @@ proc hashData*(Data: Pointer, Size: int): THash =
var i = 0
var s = size
while s > 0:
h = concHash(h, ord(p[i]))
h = h !& ord(p[i])
Inc(i)
Dec(s)
result = finishHash(h)
result = !$h
proc hash*(x: Pointer): THash {.inline.} =
## efficient hashing of pointers
@@ -60,8 +64,8 @@ proc hash*(x: string): THash =
## efficient hashing of strings
var h: THash = 0
for i in 0..x.len-1:
h = concHash(h, ord(x[i]))
result = finishHash(h)
h = h !& ord(x[i])
result = !$h
proc hashIgnoreStyle*(x: string): THash =
## efficient hashing of strings; style is ignored
@@ -72,8 +76,8 @@ proc hashIgnoreStyle*(x: string): THash =
continue # skip _
if c in {'A'..'Z'}:
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = concHash(h, ord(c))
result = finishHash(h)
h = h !& ord(c)
result = !$h
proc hashIgnoreCase*(x: string): THash =
## efficient hashing of strings; case is ignored
@@ -82,12 +86,12 @@ proc hashIgnoreCase*(x: string): THash =
var c = x[i]
if c in {'A'..'Z'}:
c = chr(ord(c) + (ord('a') - ord('A'))) # toLower()
h = concHash(h, ord(c))
result = finishHash(h)
h = h !& ord(c)
result = !$h
proc hash*[T: tuple](x: T): THash =
## efficient hashing of tuples.
for f in fields(x):
result = concHash(result, hash(f))
result = finishHash(result)
result = result !& hash(f)
result = !$result