got rid of some arcane module names

This commit is contained in:
Araq 2011-04-21 00:54:44 +02:00
commit 36c67455d4
34 changed files with 327 additions and 1258 deletions

View file

@ -8,7 +8,7 @@
# #
import import
strutils, os, times, parseopt, llstream, ast, rnimsyn, options, msgs, strutils, os, times, parseopt, llstream, ast, renderer, options, msgs,
clex, cparse clex, cparse
const const

View file

@ -14,7 +14,7 @@
# XXX cleanup of declaration handling. # XXX cleanup of declaration handling.
import import
os, llstream, rnimsyn, clex, idents, strutils, pegs, ast, astalgo, msgs, os, llstream, renderer, clex, idents, strutils, pegs, ast, astalgo, msgs,
options, strtabs options, strtabs
type type

View file

@ -14,7 +14,7 @@ import
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
options, options,
nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, ccgutils, os,
times, ropes, math, passes, rodread, wordrecg, rnimsyn, treetab, cgmeth, times, ropes, math, passes, rodread, wordrecg, treetab, cgmeth,
rodutils rodutils
when options.hasTinyCBackend: when options.hasTinyCBackend:

View file

@ -10,7 +10,7 @@
## This module implements code generation for multi methods. ## This module implements code generation for multi methods.
import import
options, ast, astalgo, msgs, idents, rnimsyn, types, magicsys options, ast, astalgo, msgs, idents, renderer, types, magicsys
proc genConv(n: PNode, d: PType, downcast: bool): PNode = proc genConv(n: PNode, d: PType, downcast: bool): PNode =
var var

View file

@ -13,7 +13,7 @@
import import
ast, astalgo, strutils, nhashes, options, nversion, msgs, os, ropes, idents, ast, astalgo, strutils, nhashes, options, nversion, msgs, os, ropes, idents,
wordrecg, math, syntaxes, rnimsyn, scanner, rst, times, highlite wordrecg, math, syntaxes, renderer, lexer, rst, times, highlite
proc CommandDoc*(filename: string) proc CommandDoc*(filename: string)
proc CommandRst2Html*(filename: string) proc CommandRst2Html*(filename: string)

View file

@ -14,7 +14,7 @@
import import
ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp, ast, astalgo, strutils, nhashes, trees, platform, magicsys, extccomp,
options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os, options, nversion, nimsets, msgs, crc, bitsets, idents, lists, types, os,
times, ropes, math, passes, ccgutils, wordrecg, rnimsyn, rodread, rodutils times, ropes, math, passes, ccgutils, wordrecg, renderer, rodread, rodutils
proc ecmasgenPass*(): TPass proc ecmasgenPass*(): TPass
# implementation # implementation

View file

@ -15,7 +15,7 @@
import import
strutils, magicsys, lists, options, ast, astalgo, trees, treetab, nimsets, strutils, magicsys, lists, options, ast, astalgo, trees, treetab, nimsets,
msgs, os, condsyms, idents, rnimsyn, types, passes, semfold msgs, os, condsyms, idents, renderer, types, passes, semfold
type type
PStackFrame* = ref TStackFrame PStackFrame* = ref TStackFrame

View file

@ -11,7 +11,7 @@
import import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
rnimsyn, filters renderer, filters
proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream proc filterTmpl*(stdin: PLLStream, filename: string, call: PNode): PLLStream
# #! template(subsChar='$', metaChar='#') | standard(version="0.7.2") # #! template(subsChar='$', metaChar='#') | standard(version="0.7.2")

View file

@ -10,7 +10,8 @@
# This module implements Nimrod's simple filters and helpers for filters. # This module implements Nimrod's simple filters and helpers for filters.
import import
llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options, rnimsyn llstream, os, wordrecg, idents, strutils, ast, astalgo, msgs, options,
renderer
proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream proc filterReplace*(stdin: PLLStream, filename: string, call: PNode): PLLStream
proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream proc filterStrip*(stdin: PLLStream, filename: string, call: PNode): PLLStream

View file

@ -12,7 +12,7 @@
# The interface supports one language nested in another. # The interface supports one language nested in another.
import import
nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, scanner nhashes, options, msgs, strutils, platform, idents, lexbase, wordrecg, lexer
type type
TTokenClass* = enum TTokenClass* = enum
@ -154,7 +154,7 @@ proc nimNextToken(g: var TGeneralTokenizer) =
while not (g.buf[pos] in {'\0', '\x0A', '\x0D'}): inc(pos) while not (g.buf[pos] in {'\0', '\x0A', '\x0D'}): inc(pos)
of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF': of 'a'..'z', 'A'..'Z', '_', '\x80'..'\xFF':
var id = "" var id = ""
while g.buf[pos] in scanner.SymChars + {'_'}: while g.buf[pos] in lexer.SymChars + {'_'}:
add(id, g.buf[pos]) add(id, g.buf[pos])
inc(pos) inc(pos)
if (g.buf[pos] == '\"'): if (g.buf[pos] == '\"'):
@ -247,9 +247,9 @@ proc nimNextToken(g: var TGeneralTokenizer) =
of '\0': of '\0':
g.kind = gtEof g.kind = gtEof
else: else:
if g.buf[pos] in scanner.OpChars: if g.buf[pos] in lexer.OpChars:
g.kind = gtOperator g.kind = gtOperator
while g.buf[pos] in scanner.OpChars: inc(pos) while g.buf[pos] in lexer.OpChars: inc(pos)
else: else:
inc(pos) inc(pos)
g.kind = gtNone g.kind = gtNone
@ -462,9 +462,9 @@ proc clikeNextToken(g: var TGeneralTokenizer, keywords: openarray[string],
of '\0': of '\0':
g.kind = gtEof g.kind = gtEof
else: else:
if g.buf[pos] in scanner.OpChars: if g.buf[pos] in lexer.OpChars:
g.kind = gtOperator g.kind = gtOperator
while g.buf[pos] in scanner.OpChars: inc(pos) while g.buf[pos] in lexer.OpChars: inc(pos)
else: else:
inc(pos) inc(pos)
g.kind = gtNone g.kind = gtNone

View file

@ -10,7 +10,7 @@
# This module implements lookup helpers. # This module implements lookup helpers.
import import
ast, astalgo, idents, semdata, types, msgs, options, rodread, rnimsyn ast, astalgo, idents, semdata, types, msgs, options, rodread, renderer
type type
TOverloadIterMode* = enum TOverloadIterMode* = enum

View file

@ -11,7 +11,7 @@
# module handling # module handling
import import
llstream, strutils, ast, astalgo, scanner, syntaxes, rnimsyn, options, msgs, llstream, strutils, ast, astalgo, lexer, syntaxes, renderer, options, msgs,
os, lists, condsyms, rodread, rodwrite, ropes, trees, os, lists, condsyms, rodread, rodwrite, ropes, trees,
wordrecg, sem, semdata, idents, passes, docgen, extccomp, wordrecg, sem, semdata, idents, passes, docgen, extccomp,
cgen, ecmasgen, cgen, ecmasgen,

View file

@ -10,7 +10,7 @@
# This module handles the reading of the config file. # This module handles the reading of the config file.
import import
llstream, nversion, commands, os, strutils, msgs, platform, condsyms, scanner, llstream, nversion, commands, os, strutils, msgs, platform, condsyms, lexer,
options, idents, wordrecg options, idents, wordrecg
# ---------------- configuration file parser ----------------------------- # ---------------- configuration file parser -----------------------------

View file

@ -11,7 +11,7 @@ when defined(gcc) and defined(windows):
{.link: "icons/nimrod.res".} {.link: "icons/nimrod.res".}
import import
times, commands, scanner, condsyms, options, msgs, nversion, nimconf, ropes, times, commands, lexer, condsyms, options, msgs, nversion, nimconf, ropes,
extccomp, strutils, os, platform, main, parseopt extccomp, strutils, os, platform, main, parseopt
when hasTinyCBackend: when hasTinyCBackend:

View file

@ -10,7 +10,7 @@
# this unit handles Nimrod sets; it implements symbolic sets # this unit handles Nimrod sets; it implements symbolic sets
import import
ast, astalgo, trees, nversion, msgs, platform, bitsets, types, rnimsyn ast, astalgo, trees, nversion, msgs, platform, bitsets, types, renderer
proc toBitSet*(s: PNode, b: var TBitSet) proc toBitSet*(s: PNode, b: var TBitSet)
# this function is used for case statement checking: # this function is used for case statement checking:

View file

@ -15,7 +15,7 @@
# from the grammar and how comments belong to the AST. # from the grammar and how comments belong to the AST.
import import
llstream, scanner, idents, strutils, ast, msgs llstream, lexer, idents, strutils, ast, msgs
type type
TParser*{.final.} = object # a TParser object represents a module that TParser*{.final.} = object # a TParser object represents a module that

View file

@ -8,7 +8,7 @@
# #
import import
strutils, os, parseopt, llstream, ast, rnimsyn, options, msgs, strutils, os, parseopt, llstream, ast, renderer, options, msgs,
paslex, pasparse paslex, pasparse
const const

View file

@ -12,8 +12,8 @@
import import
strutils, lists, options, ast, astalgo, llstream, msgs, platform, os, strutils, lists, options, ast, astalgo, llstream, msgs, platform, os,
condsyms, idents, rnimsyn, types, extccomp, math, magicsys, nversion, nimsets, condsyms, idents, renderer, types, extccomp, math, magicsys, nversion,
syntaxes, times, rodread nimsets, syntaxes, times, rodread
type type
TPassContext* = object of TObject # the pass's context TPassContext* = object of TObject # the pass's context

File diff suppressed because it is too large Load diff

View file

@ -8,16 +8,11 @@
# #
import import
llstream, scanner, idents, strutils, ast, msgs, pnimsyn llstream, lexer, parser, idents, strutils, ast, msgs
proc ParseAll*(p: var TParser): PNode proc ParseAll*(p: var TParser): PNode =
proc parseTopLevelStmt*(p: var TParser): PNode
# implements an iterator. Returns the next top-level statement or nil if end
# of stream.
# implementation
proc ParseAll(p: var TParser): PNode =
result = nil result = nil
proc parseTopLevelStmt(p: var TParser): PNode = proc parseTopLevelStmt*(p: var TParser): PNode =
result = nil result = nil

View file

@ -10,7 +10,7 @@
# This module implements semantic checking for pragmas # This module implements semantic checking for pragmas
import import
os, platform, condsyms, ast, astalgo, idents, semdata, msgs, rnimsyn, os, platform, condsyms, ast, astalgo, idents, semdata, msgs, renderer,
wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees, wordrecg, ropes, options, strutils, lists, extccomp, math, magicsys, trees,
rodread rodread

View file

@ -10,7 +10,7 @@
# This module implements the renderer of the standard Nimrod representation. # This module implements the renderer of the standard Nimrod representation.
import import
scanner, options, idents, strutils, ast, msgs, lists lexer, options, idents, strutils, ast, msgs, lists
type type
TRenderFlag* = enum TRenderFlag* = enum
@ -637,7 +637,7 @@ proc gasm(g: var TSrcGen, n: PNode) =
proc gident(g: var TSrcGen, n: PNode) = proc gident(g: var TSrcGen, n: PNode) =
var t: TTokType var t: TTokType
var s = atom(n) var s = atom(n)
if (s[0] in scanner.SymChars): if (s[0] in lexer.SymChars):
if (n.kind == nkIdent): if (n.kind == nkIdent):
if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or if (n.ident.id < ord(tokKeywordLow) - ord(tkSymbol)) or
(n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)): (n.ident.id > ord(tokKeywordHigh) - ord(tkSymbol)):

View file

@ -10,9 +10,9 @@
# This module implements the semantic checking pass. # This module implements the semantic checking pass.
import import
strutils, nhashes, lists, options, scanner, ast, astalgo, trees, treetab, strutils, nhashes, lists, options, lexer, ast, astalgo, trees, treetab,
wordrecg, ropes, msgs, os, condsyms, idents, rnimsyn, types, platform, math, wordrecg, ropes, msgs, os, condsyms, idents, renderer, types, platform, math,
magicsys, pnimsyn, nversion, nimsets, semdata, evals, semfold, importer, magicsys, parser, nversion, nimsets, semdata, evals, semfold, importer,
procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest procfind, lookups, rodread, pragmas, passes, semtypinst, sigmatch, suggest
proc semPass*(): TPass proc semPass*(): TPass

View file

@ -10,9 +10,9 @@
# This module contains the data structures for the semantic checking phase. # This module contains the data structures for the semantic checking phase.
import import
strutils, lists, options, scanner, ast, astalgo, trees, treetab, wordrecg, strutils, lists, options, lexer, ast, astalgo, trees, treetab, wordrecg,
ropes, msgs, platform, os, condsyms, idents, rnimsyn, types, extccomp, math, ropes, msgs, platform, os, condsyms, idents, renderer, types, extccomp, math,
magicsys, nversion, nimsets, pnimsyn, times, passes, rodread magicsys, nversion, nimsets, parser, times, passes, rodread
type type
TOptionEntry* = object of lists.TListEntry # entries to put on a TOptionEntry* = object of lists.TListEntry # entries to put on a

View file

@ -12,7 +12,7 @@
import import
strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times, strutils, lists, options, ast, astalgo, trees, treetab, nimsets, times,
nversion, platform, math, msgs, os, condsyms, idents, rnimsyn, types, nversion, platform, math, msgs, os, condsyms, idents, renderer, types,
commands commands
proc getConstExpr*(m: PSym, n: PNode): PNode proc getConstExpr*(m: PSym, n: PNode): PNode

View file

@ -11,7 +11,7 @@
# the call to overloaded procs, generic procs and operators. # the call to overloaded procs, generic procs and operators.
import import
ast, astalgo, semdata, types, msgs, rnimsyn, lookups, semtypinst, ast, astalgo, semdata, types, msgs, renderer, lookups, semtypinst,
magicsys magicsys
type type

View file

@ -9,7 +9,8 @@
## This file implements features required for IDE support. ## This file implements features required for IDE support.
import scanner, idents, ast, astalgo, semdata, msgs, types, sigmatch, options import
lexer, idents, ast, astalgo, semdata, msgs, types, sigmatch, options
const const
sep = '\t' sep = '\t'
@ -38,7 +39,7 @@ proc SymToStr(s: PSym, isLocal: bool, section: string): string =
result.add($ToColumn(s.info)) result.add($ToColumn(s.info))
proc filterSym(s: PSym): bool {.inline.} = proc filterSym(s: PSym): bool {.inline.} =
result = s.name.s[0] in scanner.SymChars result = s.name.s[0] in lexer.SymChars
proc suggestField(s: PSym) = proc suggestField(s: PSym) =
if filterSym(s): if filterSym(s):

View file

@ -10,8 +10,8 @@
## Implements the dispatcher for the different parsers. ## Implements the dispatcher for the different parsers.
import import
strutils, llstream, ast, astalgo, idents, scanner, options, msgs, pnimsyn, strutils, llstream, ast, astalgo, idents, lexer, options, msgs, parser,
pbraces, ptmplsyn, filters, rnimsyn pbraces, filters, filter_tmpl, renderer
type type
TFilterKind* = enum TFilterKind* = enum
@ -54,7 +54,7 @@ proc ParseFile(filename: string): PNode =
proc parseAll(p: var TParsers): PNode = proc parseAll(p: var TParsers): PNode =
case p.skin case p.skin
of skinStandard: of skinStandard:
result = pnimsyn.parseAll(p.parser) result = parser.parseAll(p.parser)
of skinBraces: of skinBraces:
result = pbraces.parseAll(p.parser) result = pbraces.parseAll(p.parser)
of skinEndX: of skinEndX:
@ -65,7 +65,7 @@ proc parseAll(p: var TParsers): PNode =
proc parseTopLevelStmt(p: var TParsers): PNode = proc parseTopLevelStmt(p: var TParsers): PNode =
case p.skin case p.skin
of skinStandard: of skinStandard:
result = pnimsyn.parseTopLevelStmt(p.parser) result = parser.parseTopLevelStmt(p.parser)
of skinBraces: of skinBraces:
result = pbraces.parseTopLevelStmt(p.parser) result = pbraces.parseTopLevelStmt(p.parser)
of skinEndX: of skinEndX:
@ -99,7 +99,7 @@ proc parsePipe(filename: string, inputStream: PLLStream): PNode =
while line[i] in WhiteSpace: inc(i) while line[i] in WhiteSpace: inc(i)
var q: TParser var q: TParser
OpenParser(q, filename, LLStreamOpen(copy(line, i))) OpenParser(q, filename, LLStreamOpen(copy(line, i)))
result = pnimsyn.parseAll(q) result = parser.parseAll(q)
CloseParser(q) CloseParser(q)
LLStreamClose(s) LLStreamClose(s)
@ -167,7 +167,7 @@ proc openParsers(p: var TParsers, filename: string, inputstream: PLLStream) =
else: s = inputStream else: s = inputStream
case p.skin case p.skin
of skinStandard, skinBraces, skinEndX: of skinStandard, skinBraces, skinEndX:
pnimsyn.openParser(p.parser, filename, s) parser.openParser(p.parser, filename, s)
proc closeParsers(p: var TParsers) = proc closeParsers(p: var TParsers) =
pnimsyn.closeParser(p.parser) parser.closeParser(p.parser)

View file

@ -18,7 +18,7 @@
import import
strutils, lists, options, ast, astalgo, trees, treetab, evals, msgs, os, strutils, lists, options, ast, astalgo, trees, treetab, evals, msgs, os,
idents, rnimsyn, types, passes, semfold, magicsys, cgmeth idents, renderer, types, passes, semfold, magicsys, cgmeth
const const
genPrefix* = ":tmp" # prefix for generated names genPrefix* = ":tmp" # prefix for generated names

View file

@ -10,7 +10,7 @@
# tree helper routines # tree helper routines
import import
ast, astalgo, scanner, msgs, strutils ast, astalgo, lexer, msgs, strutils
proc getMagic*(op: PNode): TMagic proc getMagic*(op: PNode): TMagic

View file

@ -9,16 +9,11 @@ nimrod main module: parses the command line and calls
main implements the top-level command dispatching main implements the top-level command dispatching
nimconf implements the config file reader nimconf implements the config file reader
syntaxes dispatcher for the different parsers and filters syntaxes dispatcher for the different parsers and filters
ptmplsyn standard template filter (``#! stdtempl``) filter_tmpl standard template filter (``#! stdtempl``)
lexbase buffer handling of the lexical analyser lexbase buffer handling of the lexical analyser
scanner lexical analyser lexer lexical analyser
pnimsyn Nimrod's parser parser Nimrod's parser
rnimsyn Nimrod code renderer (AST back to its textual form) renderer Nimrod code renderer (AST back to its textual form)
paslex lexer for Pascal
pasparse parser for Pascal; Pascal's advanced OO features are not
supported
options contains global and local compiler options options contains global and local compiler options
ast type definitions of the abstract syntax tree (AST) and ast type definitions of the abstract syntax tree (AST) and
node constructors node constructors

View file

@ -18,8 +18,8 @@ type
TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B] TKeyValuePair[A, B] = tuple[slot: TSlotEnum, key: A, val: B]
TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]] TKeyValuePairSeq[A, B] = seq[TKeyValuePair[A, B]]
THashTable[A, B] = object of TObject THashTable[A, B] = object of TObject
counter: int
data: TKeyValuePairSeq[A, B] data: TKeyValuePairSeq[A, B]
counter: int
PHashTable*[A, B] = ref THashTable[A, B] ## use this type to declare tables PHashTable*[A, B] = ref THashTable[A, B] ## use this type to declare tables
@ -32,12 +32,12 @@ iterator pairs*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] =
for h in 0..high(t.data): for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val) if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
iterator keys*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] = iterator keys*[A, B](t: PHashTable[A, B]): A =
## iterates over any key in the table `t`. ## iterates over any key in the table `t`.
for h in 0..high(t.data): for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield t.data[h].key if t.data[h].slot == seFilled: yield t.data[h].key
iterator values*[A, B](t: PHashTable[A, B]): tuple[key: A, val: B] = iterator values*[A, B](t: PHashTable[A, B]): B =
## iterates over any value in the table `t`. ## iterates over any value in the table `t`.
for h in 0..high(t.data): for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield t.data[h].val if t.data[h].slot == seFilled: yield t.data[h].val
@ -103,6 +103,7 @@ proc del*[A, B](t: PHashTable[A, B], key: A) =
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)
proc newHashTable*[A, B](initialSize = 64): PHashTable[A, B] = proc newHashTable*[A, B](initialSize = 64): PHashTable[A, B] =
## creates a new string table that is empty. `initialSize` needs to be ## creates a new string table that is empty. `initialSize` needs to be
@ -125,6 +126,110 @@ proc `$`*[A, B](t: PHashTable[A, B]): string =
result.add($val) result.add($val)
result.add("}") result.add("}")
# ------------------------------ count tables -------------------------------
const
deletedCount = -1
type
TCountTable*[A] {.final.} = object
data: seq[tuple[key: A, val: int]]
counter: int
proc len*[A](t: TCountTable[A]): int =
## returns the number of keys in `t`.
result = t.counter
iterator pairs*[A](t: TCountTable[A]): tuple[key: A, val: int] =
## iterates over any (key, value) pair in the table `t`.
for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield (t.data[h].key, t.data[h].val)
iterator keys*[A](t: TCountTable[A]): A =
## iterates over any key in the table `t`.
for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield t.data[h].key
iterator values*[A](t: TCountTable[A]): int =
## iterates over any value in the table `t`.
for h in 0..high(t.data):
if t.data[h].slot == seFilled: yield t.data[h].val
proc RawGet[A](t: TCountTable[A], key: A): int =
var h: THash = hash(key) and high(t.data) # start with real hash value
while t.data[h].slot != seEmpty:
if t.data[h].key == key and t.data[h].slot == seFilled:
return h
h = nextTry(h, high(t.data))
result = -1
proc `[]`*[A](t: TCountTable[A], 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 index = RawGet(t, key)
if index >= 0: result = t.data[index].val
proc hasKey*[A](t: TCountTable[A], key: A): bool =
## returns true iff `key` is in the table `t`.
result = rawGet(t, key) >= 0
proc RawInsert[A](t: TCountTable[A], data: var TKeyValuePairSeq[A, B],
key: A, val: int) =
var h: THash = hash(key) and high(data)
while data[h].slot == seFilled:
h = nextTry(h, high(data))
data[h].key = key
data[h].val = val
data[h].slot = seFilled
proc Enlarge[A](t: TCountTable[A]) =
var n: TKeyValuePairSeq[A, B]
newSeq(n, len(t.data) * growthFactor)
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)
swap(t.data, n)
proc `[]=`*[A](t: TCountTable[A], key: A, val: int) =
## puts a (key, value)-pair into `t`.
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 del*[A](t: TCountTable[A], key: A) =
## deletes `key` from hash table `t`.
var index = RawGet(t, key)
if index >= 0:
t.data[index].slot = seDeleted
proc newHashTable*[A, B](initialSize = 64): PHashTable[A, B] =
## creates a new string table that is empty. `initialSize` needs to be
## a power of two.
assert isPowerOfTwo(initialSize)
new(result)
result.counter = 0
newSeq(result.data, initialSize)
proc `$`*[A](t: TCountTable[A]): string =
## The `$` operator for string tables.
if t.len == 0:
result = "{:}"
else:
result = "{"
for key, val in pairs(t):
if result.len > 1: result.add(", ")
result.add($key)
result.add(": ")
result.add($val)
result.add("}")
when isMainModule: when isMainModule:
var table = newHashTable[string, float]() var table = newHashTable[string, float]()
table["test"] = 1.2345 table["test"] = 1.2345

155
lib/pure/collections/lists.nim Executable file
View file

@ -0,0 +1,155 @@
#
#
# Nimrod's Runtime Library
# (c) Copyright 2011 Andreas Rumpf
#
# See the file "copying.txt", included in this
# distribution, for details about the copyright.
#
## Implementation of singly and doubly linked lists. Because it makes no sense
## to do so, the 'next' and 'prev' pointers are not hidden from you and can
## be manipulated directly for efficiency.
type
TDoublyLinkedNode[T] {.pure, final.} = object
next*, prev*: ref TDoublyLinkedNode[T]
value*: T
PDoublyLinkedNode*[T] = ref TDoublyLinkedNode[T]
TSinglyLinkedNode[T] {.pure, final.} = object
next*: ref TSinglyLinkedNode[T]
value*: T
PSinglyLinkedNode*[T] = ref TSinglyLinkedNode[T]
proc newDoublyLinkedNode*[T](value: T): PDoublyLinkedNode[T] =
## creates a new doubly linked node with the given `value`.
new(result)
result.value = value
proc newSinglyLinkedNode*[T](value: T): PSinglyLinkedNode[T] =
## creates a new singly linked node with the given `value`.
new(result)
result.value = value
iterator items*[T](n: PDoublyLinkedNode[T]): T =
## yields every value of `x`.
var it = n
while it != nil:
yield it.value
it = it.next
iterator items*[T](n: PSinglyLinkedNode[T]): T =
## yields every value of `x`.
var it = n
while it != nil:
yield it.value
it = it.next
iterator nodes*[T](n: PSinglyLinkedNode[T]): PSinglyLinkedNode[T] =
## iterates over every node of `x`. Removing the current node from the
## list during traversal is supported.
var it = n
while it != nil:
var nxt = it.next
yield it
it = nxt
iterator nodes*[T](n: PDoublyLinkedNode[T]): PDoublyLinkedNode[T] =
## iterates over every node of `x`. Removing the current node from the
## list during traversal is supported.
var it = n
while it != nil:
var nxt = it.next
yield it
it = nxt
proc `$`*[list: PSinglyLinkedNode|PDoublyLinkedNode](n: list): string =
## turns a list into its string representation.
result = "["
for x in nodes(n):
if result.len > 1: result.add(", ")
result.add($x.value)
result.add("]")
proc find*[list: PSinglyLinkedNode|PDoublyLinkedNode, T](
n: list, value: T): list =
## searches in the list for a value. Returns nil if the value does not
## exist.
for x in nodes(n):
if x.value == value: return x
proc contains*[list: PSinglyLinkedNode|PDoublyLinkedNode, T](
n: list, value: T): list =
## searches in the list for a value. Returns false if the value does not
## exist, true otherwise.
for x in nodes(n):
if x.value == value: return true
proc prepend*[T](head: var PSinglyLinkedNode[T],
toAdd: PSinglyLinkedNode[T]) {.inline.} =
## prepends a node to `head`. Efficiency: O(1).
toAdd.next = head
head = toAdd
proc prepend*[T](head: var PSinglyLinkedNode[T], x: T) {.inline.} =
## creates a new node with the value `x` and prepends that node to `head`.
## Efficiency: O(1).
preprend(head, newSinglyLinkedNode(x))
proc append*[T](head: var PSinglyLinkedNode[T],
toAdd: PSinglyLinkedNode[T]) =
## appends a node to `head`. Efficiency: O(n).
if head == nil:
head = toAdd
else:
var it = head
while it.next != nil: it = it.next
it.next = toAdd
proc append*[T](head: var PSinglyLinkedNode[T], x: T) {.inline.} =
## creates a new node with the value `x` and appends that node to `head`.
## Efficiency: O(n).
append(head, newSinglyLinkedNode(x))
proc prepend*[T](head: var PDoublyLinkedNode[T],
toAdd: PDoublyLinkedNode[T]) {.inline.} =
## prepends a node to `head`. Efficiency: O(1).
if head == nil:
head = toAdd
# head.prev stores the last node:
head.prev = toAdd
else:
toAdd.next = head
toAdd.prev = head.prev # copy pointer to last element
head.prev = toAdd
head = toAdd
proc prepend*[T](head: var PDoublyLinkedNode[T], x: T) {.inline.} =
## creates a new node with the value `x` and prepends that node to `head`.
## Efficiency: O(1).
preprend(head, newDoublyLinkedNode(x))
proc append*[T](head: var PDoublyLinkedNode[T],
toAdd: PDoublyLinkedNode[T]) {.inline.} =
## appends a node to `head`. Efficiency: O(1).
if head == nil:
head = toAdd
# head.prev stores the last node:
head.prev = toAdd
else:
var last = head.prev
assert last.next == nil
last.next = toAdd
toAdd.prev = last
head.prev = toAdd # new last element
proc append*[T](head: var PDoublyLinkedNode[T], x: T) {.inline.} =
## creates a new node with the value `x` and appends that node to `head`.
## Efficiency: O(1).
append(head, newDoublyLinkedNode(x))