added getOrDefault; bootstrapping works again

This commit is contained in:
Araq 2015-10-13 03:03:05 +02:00
commit 2fda95a4d6
9 changed files with 52 additions and 40 deletions

View file

@ -121,7 +121,7 @@ proc importAllSymbolsExcept(c: PContext, fromMod: PSym, exceptSet: IntSet) =
if s.kind != skEnumField: if s.kind != skEnumField:
if s.kind notin ExportableSymKinds: if s.kind notin ExportableSymKinds:
internalError(s.info, "importAllSymbols: " & $s.kind) internalError(s.info, "importAllSymbols: " & $s.kind)
if s.name.id notin exceptSet: if exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s) rawImportSymbol(c, s)
s = nextIter(i, fromMod.tab) s = nextIter(i, fromMod.tab)
@ -138,7 +138,7 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: IntSet) =
let s = a.sym let s = a.sym
if s.kind == skModule: if s.kind == skModule:
importAllSymbolsExcept(c, s, exceptSet) importAllSymbolsExcept(c, s, exceptSet)
elif s.name.id notin exceptSet: elif exceptSet.isNil or s.name.id notin exceptSet:
rawImportSymbol(c, s) rawImportSymbol(c, s)
of nkExportExceptStmt: of nkExportExceptStmt:
localError(n.info, errGenerated, "'export except' not implemented") localError(n.info, errGenerated, "'export except' not implemented")

View file

@ -15,7 +15,7 @@ import
wordrecg, sem, semdata, idents, passes, docgen, extccomp, wordrecg, sem, semdata, idents, passes, docgen, extccomp,
cgen, jsgen, json, nversion, cgen, jsgen, json, nversion,
platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen, platform, nimconf, importer, passaux, depends, vm, vmdef, types, idgen,
tables, docgen2, service, parser, modules, ccgutils, sigmatch, ropes, lists docgen2, service, parser, modules, ccgutils, sigmatch, ropes, lists
from magicsys import systemModule, resetSysTypes from magicsys import systemModule, resetSysTypes

View file

@ -48,7 +48,7 @@ proc addPackage(packages: StringTableRef, p: string) =
let name = p.substr(0, x-1) let name = p.substr(0, x-1)
if x < p.len: if x < p.len:
let version = p.substr(x+1) let version = p.substr(x+1)
if packages[name] <. version: if packages.getOrDefault(name) <. version:
packages[name] = version packages[name] = version
else: else:
packages[name] = latest packages[name] = latest

View file

@ -173,7 +173,7 @@ proc existsConfigVar*(key: string): bool =
result = hasKey(gConfigVars, key) result = hasKey(gConfigVars, key)
proc getConfigVar*(key: string): string = proc getConfigVar*(key: string): string =
result = gConfigVars[key] result = gConfigVars.getOrDefault key
proc setConfigVar*(key, val: string) = proc setConfigVar*(key, val: string) =
gConfigVars[key] = val gConfigVars[key] = val

View file

@ -239,7 +239,7 @@ proc loadAny(p: var JsonParser, t: PType,
result = newNode(nkNilLit) result = newNode(nkNilLit)
next(p) next(p)
of jsonInt: of jsonInt:
result = tab[p.getInt] result = tab.getOrDefault(p.getInt)
if result.isNil: if result.isNil:
raiseParseErr(p, "cannot load object with address " & $p.getInt) raiseParseErr(p, "cannot load object with address " & $p.getInt)
next(p) next(p)

View file

@ -138,6 +138,8 @@ proc initIntSet*: IntSet =
result.counter = 0 result.counter = 0
result.head = nil result.head = nil
proc isNil*(x: IntSet): bool {.inline.} = x.head.isNil
proc assign*(dest: var IntSet, src: IntSet) = proc assign*(dest: var IntSet, src: IntSet) =
## copies `src` to `dest`. `dest` does not need to be initialized by ## copies `src` to `dest`. `dest` does not need to be initialized by
## `initIntSet`. ## `initIntSet`.

View file

@ -96,18 +96,10 @@ proc len*[A, B](t: Table[A, B]): int =
## returns the number of keys in `t`. ## returns the number of keys in `t`.
result = t.counter result = t.counter
proc `[]`*[A, B](t: Table[A, B], key: A): B = template get(t, key): untyped {.immediate.} =
## retrieves the value at ``t[key]``. If `key` is not in `t`,
## default empty value for the type `B` is returned
## and no exception is raised. One can check with ``hasKey`` whether the key
## exists.
var hc: Hash
var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val
proc mget*[A, B](t: var Table[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 ``KeyError`` exception is raised. ## If `key` is not in `t`, the ``KeyError`` exception is raised.
mixin rawGet
var hc: Hash var hc: Hash
var index = rawGet(t, key, hc) var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val if index >= 0: result = t.data[index].val
@ -117,6 +109,12 @@ proc mget*[A, B](t: var Table[A, B], key: A): var B =
else: else:
raise newException(KeyError, "key not found") raise newException(KeyError, "key not found")
template getOrDefaultImpl(t, key): untyped {.immediate.} =
mixin rawGet
var hc: Hash
var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val
proc `[]`*[A, B](t: Table[A, B], key: A): B = proc `[]`*[A, B](t: Table[A, B], key: A): B =
## retrieves the value at ``t[key]``. If `key` is not in `t`, the ## retrieves the value at ``t[key]``. If `key` is not in `t`, the
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether ## ``KeyError`` exception is raised. One can check with ``hasKey`` whether
@ -134,6 +132,8 @@ proc mget*[A, B](t: var Table[A, B], key: A): var B {.deprecated.} =
## instead. ## instead.
get(t, key) get(t, key)
proc getOrDefault*[A, B](t: Table[A, B], key: A): B = getOrDefaultImpl(t, key)
iterator allValues*[A, B](t: Table[A, B]; key: A): B = iterator allValues*[A, B](t: Table[A, B]; key: A): B =
## iterates over any value in the table `t` that belongs to the given `key`. ## iterates over any value in the table `t` that belongs to the given `key`.
var h: Hash = hash(key) and high(t.data) var h: Hash = hash(key) and high(t.data)
@ -305,6 +305,8 @@ proc mget*[A, B](t: TableRef[A, B], key: A): var B {.deprecated.} =
## Use ```[]``` instead. ## Use ```[]``` instead.
t[][key] t[][key]
proc getOrDefault*[A, B](t: TableRef[A, B], key: A): B = getOrDefault(t[], key)
proc mgetOrPut*[A, B](t: TableRef[A, B], key: A, val: B): var B = proc mgetOrPut*[A, B](t: TableRef[A, B], key: A, val: B): var B =
## retrieves value at ``t[key]`` or puts ``val`` if not present, either way ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
## returning a value which can be modified. ## returning a value which can be modified.
@ -416,20 +418,6 @@ proc rawGetDeep[A, B](t: OrderedTable[A, B], key: A, hc: var Hash): int {.inline
proc rawGet[A, B](t: OrderedTable[A, B], key: A, hc: var Hash): int = proc rawGet[A, B](t: OrderedTable[A, B], key: A, hc: var Hash): int =
rawGetImpl() rawGetImpl()
proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
## retrieves the value at ``t[key]``. If `key` is not in `t`,
## default empty value for the type `B` is returned
## and no exception is raised. One can check with ``hasKey`` whether the key
## exists.
var hc: Hash
var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val
else:
when compiles($key):
raise newException(KeyError, "key not found: " & $key)
else:
raise newException(KeyError, "key not found")
proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B = proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
## retrieves the value at ``t[key]``. If `key` is not in `t`, the ## retrieves the value at ``t[key]``. If `key` is not in `t`, the
## ``KeyError`` exception is raised. One can check with ``hasKey`` whether ## ``KeyError`` exception is raised. One can check with ``hasKey`` whether
@ -438,11 +426,18 @@ proc `[]`*[A, B](t: OrderedTable[A, B], key: A): B =
proc `[]`*[A, B](t: var OrderedTable[A, B], key: A): var B = proc `[]`*[A, B](t: var OrderedTable[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 ``KeyError`` exception is raised.
var hc: Hash get(t, key)
var index = rawGet(t, key, hc)
if index >= 0: result = t.data[index].val proc mget*[A, B](t: var OrderedTable[A, B], key: A): var B {.deprecated.} =
else: raise newException(KeyError, "key not found: " & $key) ## retrieves the value at ``t[key]``. The value can be modified.
## If `key` is not in `t`, the ``KeyError`` exception is raised.
## Use ```[]``` instead.
get(t, key)
proc getOrDefault*[A, B](t: OrderedTable[A, B], key: A): B =
getOrDefaultImpl(t, key)
proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool = proc hasKey*[A, B](t: OrderedTable[A, B], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
@ -612,6 +607,9 @@ proc mget*[A, B](t: OrderedTableRef[A, B], key: A): var B {.deprecated.} =
## Use ```[]``` instead. ## Use ```[]``` instead.
result = t[][key] result = t[][key]
proc getOrDefault*[A, B](t: OrderedTableRef[A, B], key: A): B =
getOrDefault(t[], key)
proc mgetOrPut*[A, B](t: OrderedTableRef[A, B], key: A, val: B): var B = proc mgetOrPut*[A, B](t: OrderedTableRef[A, B], key: A, val: B): var B =
## retrieves value at ``t[key]`` or puts ``val`` if not present, either way ## retrieves value at ``t[key]`` or puts ``val`` if not present, either way
## returning a value which can be modified. ## returning a value which can be modified.
@ -711,7 +709,7 @@ proc rawGet[A](t: CountTable[A], key: A): int =
h = nextTry(h, high(t.data)) h = nextTry(h, high(t.data))
result = -1 - h # < 0 => MISSING; insert idx = -1 - result result = -1 - h # < 0 => MISSING; insert idx = -1 - result
template get[A](t: CountTable[A], key: A): int {.immediate.} = template ctget(t, key: untyped): untyped {.immediate.} =
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: else:
@ -724,18 +722,22 @@ proc `[]`*[A](t: CountTable[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`,
## the ``KeyError`` exception is raised. One can check with ``hasKey`` ## the ``KeyError`` exception is raised. One can check with ``hasKey``
## whether the key exists. ## whether the key exists.
get(t, key) ctget(t, key)
proc `[]`*[A](t: var CountTable[A], key: A): var int = proc `[]`*[A](t: var CountTable[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 ``KeyError`` exception is raised. ## If `key` is not in `t`, the ``KeyError`` exception is raised.
get(t, key) ctget(t, key)
proc mget*[A](t: var CountTable[A], key: A): var int {.deprecated.} = proc mget*[A](t: var CountTable[A], key: A): var int {.deprecated.} =
## 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 ``KeyError`` exception is raised. ## If `key` is not in `t`, the ``KeyError`` exception is raised.
## Use ```[]``` instead. ## Use ```[]``` instead.
get(t, key) ctget(t, key)
proc getOrDefault*[A](t: CountTable[A], key: A): int =
var index = rawGet(t, key)
if index >= 0: result = t.data[index].val
proc hasKey*[A](t: CountTable[A], key: A): bool = proc hasKey*[A](t: CountTable[A], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
@ -882,6 +884,9 @@ proc mget*[A](t: CountTableRef[A], key: A): var int {.deprecated.} =
## Use ```[]``` instead. ## Use ```[]``` instead.
result = t[][key] result = t[][key]
proc getOrDefault*[A](t: CountTableRef[A], key: A): int =
getOrDefaultImpl(t, key)
proc hasKey*[A](t: CountTableRef[A], key: A): bool = proc hasKey*[A](t: CountTableRef[A], key: A): bool =
## returns true iff `key` is in the table `t`. ## returns true iff `key` is in the table `t`.
result = t[].hasKey(key) result = t[].hasKey(key)

View file

@ -122,6 +122,11 @@ proc mget*(t: StringTableRef, key: string): var string {.deprecated.} =
## ``KeyError`` exception is raised. Use ```[]``` instead. ## ``KeyError`` exception is raised. Use ```[]``` instead.
get(t, key) get(t, key)
proc getOrDefault*(t: StringTableRef; key: string): string =
var index = rawGet(t, key)
if index >= 0: result = t.data[index].val
else: result = ""
proc hasKey*(t: StringTableRef, key: string): bool {.rtl, extern: "nst$1".} = proc hasKey*(t: StringTableRef, 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