diff options
-rwxr-xr-x | config/nimdoc.cfg | 6 | ||||
-rwxr-xr-x | config/nimdoc.tex.cfg | 8 | ||||
-rw-r--r-- | doc/lib.txt | 4 | ||||
-rwxr-xr-x | lib/impure/graphics.nim | 2 | ||||
-rwxr-xr-x | lib/pure/hashtabs.nim | 163 | ||||
-rwxr-xr-x | lib/pure/httpclient.nim | 12 | ||||
-rwxr-xr-x | lib/pure/json.nim | 2 | ||||
-rwxr-xr-x | lib/pure/logging.nim | 2 | ||||
-rwxr-xr-x | lib/pure/parsesql.nim | 2 | ||||
-rwxr-xr-x | lib/pure/pegs.nim | 3 | ||||
-rw-r--r-- | lib/pure/smtp.nim | 2 | ||||
-rwxr-xr-x | lib/pure/variants.nim | 181 | ||||
-rwxr-xr-x | lib/pure/xmldom.nim | 2 | ||||
-rwxr-xr-x | lib/pure/xmldomparser.nim | 4 | ||||
-rwxr-xr-x | lib/pure/xmlparser.nim | 5 | ||||
-rwxr-xr-x | lib/system/sysstr.nim | 2 | ||||
-rwxr-xr-x | rod/docgen.nim | 30 |
17 files changed, 60 insertions, 370 deletions
diff --git a/config/nimdoc.cfg b/config/nimdoc.cfg index 1db1ad6cf..541eacced 100755 --- a/config/nimdoc.cfg +++ b/config/nimdoc.cfg @@ -1,5 +1,5 @@ # This is the config file for the documentation generator. -# (c) 2010 Andreas Rumpf +# (c) 2011 Andreas Rumpf # Feel free to edit the templates as you need. split.item.toc = "20" @@ -45,12 +45,16 @@ doc.body_toc = """ $tableofcontents <div class="content" id="content"> $moduledesc +<h1>Dependencies</h1> + $deps $content </div> """ doc.body_no_toc = """ $moduledesc +<h1>Dependencies</h1> + $deps $content """ diff --git a/config/nimdoc.tex.cfg b/config/nimdoc.tex.cfg index 54a57e0fb..2ec5f98cb 100755 --- a/config/nimdoc.tex.cfg +++ b/config/nimdoc.tex.cfg @@ -1,6 +1,6 @@ # This is the config file for the documentation generator that produces TeX # output. -# (c) 2009 Andreas Rumpf +# (c) 2011 Andreas Rumpf # Feel free to edit the templates as you need. split.item.toc = "20" @@ -30,11 +30,17 @@ doc.toc = r"\tableofcontents \newpage" doc.body_toc = """ $tableofcontents $moduledesc + +Dependencies: $deps + $content """ doc.body_no_toc = """ $moduledesc + +Dependencies: $deps + $content """ diff --git a/doc/lib.txt b/doc/lib.txt index 2bdcc2272..47cd08cab 100644 --- a/doc/lib.txt +++ b/doc/lib.txt @@ -34,6 +34,10 @@ Core * `macros <macros.html>`_ Contains the AST API and documentation of Nimrod for writing macros. +* `marshal <marshal.html>`_ + Contains procs for serialization and deseralization of arbitrary Nimrod + data structures. + String handling --------------- diff --git a/lib/impure/graphics.nim b/lib/impure/graphics.nim index b6e2c0677..e8b10d56b 100755 --- a/lib/impure/graphics.nim +++ b/lib/impure/graphics.nim @@ -24,7 +24,7 @@ type w, h: int s: sdl.PSurface - EGraphics* = object of EBase + EGraphics* = object of EIO TFont {.pure, final.} = object f: sdl_ttf.PFont diff --git a/lib/pure/hashtabs.nim b/lib/pure/hashtabs.nim deleted file mode 100755 index 68d19d63b..000000000 --- a/lib/pure/hashtabs.nim +++ /dev/null @@ -1,163 +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. -# - -## The ``hashtabs`` module implements an efficient generic hash -## table/dictionary data type. - -import - hashes - -const - growthFactor = 2 - startSize = 8 - sham = sizeof(THash)*8-2 # shift amount - mask = 0b11 shl sham - usedSlot = 0b10 shl sham - delSlot = 0b01 shl sham - emptySlot = 0 - -type - TTable*[TKey, TValue] = object - counter: int - data: seq[tuple[key: TKey, val: TValue, h: THash]] - -proc init*(t: var TTable, size = startSize) = - t.counter = 0 - newSeq(t.data, size) - -proc markUsed(h: THash): THash {.inline.} = - return h and not mask or usedSlot - -proc len*(t: TTable): int {.inline.} = - ## returns the number of keys in `t`. - result = t.counter - -proc mustRehash(length, counter: int): bool = - assert(length > counter) - result = (length * 2 < counter * 3) or (length - counter < 4) - -proc nextTry(h, maxHash: THash): THash {.inline.} = - result = ((5 * h) + 1) and maxHash - -template eq(a, b: expr): expr = a == b - -proc rawGet(t: TTable, key: TKey, fullhash: THash): int = - var h = fullhash and high(t.data) - while (t.data[h].h and mask) != 0: - # If it is a deleted entry, the comparison with ``markUsed(fullhash)`` - # fails, so there is no need to check for this explicitely. - if t.data[h].h == markUsed(fullhash) and eq(t.data[h].key, key): return h - h = nextTry(h, high(t.data)) - result = - 1 - -proc `[]`*(t: TTable, key: TKey): TValue = - ## retrieves the value at ``t[key]``. If `key` is not in `t`, - ## `EInvalidValue` is raised. - var index = rawGet(t, key, hash(key)) - if index >= 0: result = t.data[index].val - else: - var e: ref EInvalidValue - new(e) - e.msg = "invalid key: " & $key - raise e - -proc hasKey*(t: TTable, key: TKey): bool = - ## returns true iff `key` is in the table `t`. - result = rawGet(t, key) >= 0 - -proc rawInsert[TKey, TValue]( - data: var seq[tuple[key: TKey, val: TValue, h: THash]], - tup: tuple[key: TKey, val: TValue, h: THash]) = - var h = tup.h and high(data) - while (data[h].h and mask) == usedSlot: h = nextTry(h, high(data)) - data[h] = tup - -proc enlarge(t: var TTable) = - var n: seq[tuple[key: TKey, val: TValue, h: THash]] - newSeq(n, len(t.data) * growthFactor) - for i in 0..high(t.data): - if (t.data[i].h and mask) == usedSlot: rawInsert(n, t.data[i]) - swap(t.data, n) - -proc `[]=`*(t: var TTable, key: TKey, val: TValue) = - ## puts a (key, value)-pair into `t`. - var fullhash = hash(key) - var index = rawGet(t, key, fullhash) - if index >= 0: - t.data[index].val = val - else: - if mustRehash(len(t.data), t.counter): enlarge(t) - rawInsert(t.data, (key, val, markUsed(fullhash))) - inc(t.counter) - -proc add*(t: var TTable, key: TKey, val: TValue) = - ## puts a (key, value)-pair into `t`, but does not check if key already - ## exists. - if mustRehash(len(t.data), t.counter): enlarge(t) - rawInsert(t.data, (key, val, markUsed(hash(key)))) - inc(t.counter) - -proc del*(t: var TTable, key: TKey) = - ## deletes a (key, val)-pair in `t`. - var index = rawGet(t, key) - if index >= 0: - t.data[index].h = delSlot - -proc delAll*(t: var TTable, key: TKey) = - ## deletes all (key, val)-pairs in `t`. - while true: - var index = rawGet(t, key) - if index < 0: break - t.data[index].h = delSlot - -iterator pairs*(t: TTable): tuple[key: TKey, value: TValue] = - ## iterates over any (key, value) pair in the table `t`. - for h in 0..high(t.data): - if (t.data[h].h and mask) == usedSlot: - yield (t.data[h].key, t.data[h].val) - -iterator keys*(t: TTable): TKey = - ## iterate over any key in the table `t`. If key occurs multiple times, it - ## is yielded multiple times. - for h in 0..high(t.data): - if (t.data[h].h and mask) == usedSlot: - yield t.data[h].key - -iterator values*(t: TTable): TValue = - ## iterate over any value in the table `t`. - for h in 0..high(t.data): - if (t.data[h].h and mask) == usedSlot: - yield t.data[h].val - -iterator values*(t: TTable, key: TKey): TValue = - ## iterate over any value associated with `key` in `t`. - var fullhash = hash(key) - var h = fullhash and high(t.data) - while (t.data[h].h and mask) != 0: - # If it is a deleted entry, the comparison with ``markUsed(fullhash)`` - # fails, so there is no need to check for this explicitely. - if t.data[h].h == markUsed(fullhash) and eq(t.data[h].key, key): - yield t.data[h].val - h = nextTry(h, high(t.data)) - -proc `$`*[KeyToStr=`$`, ValueToStr=`$`](t: TTable): string = - ## turns the table into its string representation. `$` must be available - ## for TKey and TValue for this to work. - if t.len == 0: - result = "{:}" - else: - result = "{" - var i = 0 - for k, v in pairs(t): - if i > 0: add(result, ", ") - add(result, KeyToStr(k)) - add(result, ": ") - add(result, ValueToStr(v)) - inc(i) - add(result, "}") diff --git a/lib/pure/httpclient.nim b/lib/pure/httpclient.nim index 9948e6c9b..092d8e5c6 100755 --- a/lib/pure/httpclient.nim +++ b/lib/pure/httpclient.nim @@ -52,13 +52,13 @@ type headers: PStringTable, body: string] - EInvalidProtocol* = object of EBase ## exception that is raised when server - ## does not conform to the implemented - ## protocol + EInvalidProtocol* = object of ESynch ## exception that is raised when server + ## does not conform to the implemented + ## protocol - EHttpRequestErr* = object of EBase ## Thrown in the ``getContent`` proc - ## and ``postContent`` proc, - ## when the server returns an error + EHttpRequestErr* = object of ESynch ## Thrown in the ``getContent`` proc + ## and ``postContent`` proc, + ## when the server returns an error proc httpError(msg: string) = var e: ref EInvalidProtocol diff --git a/lib/pure/json.nim b/lib/pure/json.nim index c32a82397..134c4926f 100755 --- a/lib/pure/json.nim +++ b/lib/pure/json.nim @@ -498,7 +498,7 @@ type of JArray: elems*: seq[PJsonNode] - EJsonParsingError* = object of EBase + EJsonParsingError* = object of EInvalidValue proc raiseParseErr(p: TJsonParser, msg: string) = raise newException(EJsonParsingError, errorMsgExpected(p, msg)) diff --git a/lib/pure/logging.nim b/lib/pure/logging.nim index 6df39f50b..81c6a53c5 100755 --- a/lib/pure/logging.nim +++ b/lib/pure/logging.nim @@ -8,7 +8,7 @@ # ## This module implements a simple logger. It is based on the following design: -## * Runtime log formating is a bug: Sooner or later ever log file is parsed. +## * Runtime log formating is a bug: Sooner or later every log file is parsed. ## * Keep it simple: If this library does not fullfill your needs, write your ## own. Trying to support every logging feature just leads to bloat. ## diff --git a/lib/pure/parsesql.nim b/lib/pure/parsesql.nim index 2109c273a..31951e966 100755 --- a/lib/pure/parsesql.nim +++ b/lib/pure/parsesql.nim @@ -536,7 +536,7 @@ type nkEnumDef type - EInvalidSql* = object of EBase ## Invalid SQL encountered + EInvalidSql* = object of EInvalidValue ## Invalid SQL encountered PSqlNode* = ref TSqlNode ## an SQL abstract syntax tree node TSqlNode* = object ## an SQL abstract syntax tree node case kind*: TSqlNodeKind ## kind of syntax tree diff --git a/lib/pure/pegs.nim b/lib/pure/pegs.nim index f09e8f3b9..4628a3ff9 100755 --- a/lib/pure/pegs.nim +++ b/lib/pure/pegs.nim @@ -1344,7 +1344,8 @@ proc arrowIsNextTok(c: TPegLexer): bool = # ----------------------------- parser ---------------------------------------- type - EInvalidPeg* = object of EBase ## raised if an invalid PEG has been detected + EInvalidPeg* = object of EInvalidValue ## raised if an invalid + ## PEG has been detected TPegParser = object of TPegLexer ## the PEG parser object tok: TToken nonterms: seq[PNonTerminal] diff --git a/lib/pure/smtp.nim b/lib/pure/smtp.nim index 3490822b9..21afdf953 100644 --- a/lib/pure/smtp.nim +++ b/lib/pure/smtp.nim @@ -48,7 +48,7 @@ type msgOtherHeaders: PStringTable msgBody: string - EInvalidReply* = object of EBase + EInvalidReply* = object of EIO proc debugSend(smtp: TSMTP, cmd: string) = if smtp.debug: diff --git a/lib/pure/variants.nim b/lib/pure/variants.nim deleted file mode 100755 index 620cd7b99..000000000 --- a/lib/pure/variants.nim +++ /dev/null @@ -1,181 +0,0 @@ -# -# -# Nimrod's Runtime Library -# (c) Copyright 2010 Andreas Rumpf -# -# See the file "copying.txt", included in this -# distribution, for details about the copyright. -# - -## This module implements Nimrod's support for the ``variant`` datatype. -## `TVariant` shows how the flexibility of dynamic typing is achieved -## within a static type system. - -type - TVarType* = enum - vtNone, - vtBool, - vtChar, - vtEnum, - vtInt, - vtFloat, - vtString, - vtSet, - vtSeq, - vtDict - TVariant* {.final.} = object of TObject - case vtype: TVarType - of vtNone: nil - of vtBool, vtChar, vtEnum, vtInt: vint: int64 - of vtFloat: vfloat: float64 - of vtString: vstring: string - of vtSet, vtSeq: q: seq[TVariant] - of vtDict: d: seq[tuple[key, val: TVariant]] - -iterator objectFields*[T](x: T, skipInherited: bool): tuple[ - key: string, val: TVariant] {.magic: "ObjectFields"} - -proc `?`*(x: ordinal): TVariant = - result.kind = vtEnum - result.vint = x - -proc `?`*(x: biggestInt): TVariant = - result.kind = vtInt - result.vint = x - -proc `?`*(x: char): TVariant = - result.kind = vtChar - result.vint = ord(x) - -proc `?`*(x: bool): TVariant = - result.kind = vtBool - result.vint = ord(x) - -proc `?`*(x: biggestFloat): TVariant = - result.kind = vtFloat - result.vfloat = x - -proc `?`*(x: string): TVariant = - result.kind = vtString - result.vstring = x - -proc `?`*[T](x: openArray[T]): TVariant = - result.kind = vtSeq - newSeq(result.q, x.len) - for i in 0..x.len-1: result.q[i] = <>x[i] - -proc `?`*[T](x: set[T]): TVariant = - result.kind = vtSet - result.q = @[] - for a in items(x): result.q.add(<>a) - -proc `?`* [T: object](x: T): TVariant {.magic: "ToVariant".} - ## this converts a value to a variant ("boxing") - -proc `><`*[T](v: TVariant, typ: T): T {.magic: "FromVariant".} - -?[?5, ?67, ?"hello"] -myVar?int - - -proc `==`* (x, y: TVariant): bool = - if x.vtype == y.vtype: - case x.vtype - of vtNone: result = true - of vtBool, vtChar, vtEnum, vtInt: result = x.vint == y.vint - of vtFloat: result = x.vfloat == y.vfloat - of vtString: result = x.vstring == y.vstring - of vtSet: - # complicated! We check that each a in x also occurs in y and that the - # counts are identical: - if x.q.len == y.q.len: - for a in items(x.q): - block inner: - for b in items(y.q): - if a == b: break inner - return false - result = true - of vtSeq: - if x.q.len == y.q.len: - for i in 0..x.q.len-1: - if x.q[i] != y.q[i]: return false - result = true - of vtDict: - # it is an ordered dict: - if x.d.len == y.d.len: - for i in 0..x.d.len-1: - if x.d[i].key != y.d[i].key: return false - if x.d[i].val != y.d[i].val: return false - result = true - -proc `[]`* (a, b: TVariant): TVariant = - case a.vtype - of vtSeq: - if b.vtype in {vtBool, vtChar, vtEnum, vtInt}: - result = a.q[b.vint] - else: - variantError() - of vtDict: - for i in 0..a.d.len-1: - if a.d[i].key == b: return a.d[i].val - if b.vtype in {vtBool, vtChar, vtEnum, vtInt}: - result = a.d[b.vint].val - variantError() - else: variantError() - -proc `[]=`* (a, b, c: TVariant) = - case a.vtype - of vtSeq: - if b.vtype in {vtBool, vtChar, vtEnum, vtInt}: - a.q[b.vint] = b - else: - variantError() - of vtDict: - for i in 0..a.d.len-1: - if a.d[i].key == b: - a.d[i].val = c - return - if b.vtype in {vtBool, vtChar, vtEnum, vtInt}: - a.d[b.vint].val = c - variantError() - else: variantError() - -proc `[]`* (a: TVariant, b: int): TVariant {.inline} = return a[?b] -proc `[]`* (a: TVariant, b: string): TVariant {.inline} = return a[?b] -proc `[]=`* (a: TVariant, b: int, c: TVariant) {.inline} = a[?b] = c -proc `[]=`* (a: TVariant, b: string, c: TVariant) {.inline} = a[?b] = c - -proc `+`* (x, y: TVariant): TVariant = - case x.vtype - of vtBool, vtChar, vtEnum, vtInt: - if y.vtype == x.vtype: - result.vtype = x.vtype - result.vint = x.vint + y.vint - else: - case y.vtype - of vtBool, vtChar, vtEnum, vtInt: - - - - vint: int64 - of vtFloat: vfloat: float64 - of vtString: vstring: string - of vtSet, vtSeq: q: seq[TVariant] - of vtDict: d: seq[tuple[key, val: TVariant]] - -proc `-`* (x, y: TVariant): TVariant -proc `*`* (x, y: TVariant): TVariant -proc `/`* (x, y: TVariant): TVariant -proc `div`* (x, y: TVariant): TVariant -proc `mod`* (x, y: TVariant): TVariant -proc `&`* (x, y: TVariant): TVariant -proc `$`* (x: TVariant): string = - # uses JS notation - -proc parseVariant*(s: string): TVariant -proc `<`* (x, y: TVariant): bool -proc `<=`* (x, y: TVariant): bool - -proc hash*(x: TVariant): int = - - diff --git a/lib/pure/xmldom.nim b/lib/pure/xmldom.nim index b7ee165f5..552bd54cf 100755 --- a/lib/pure/xmldom.nim +++ b/lib/pure/xmldom.nim @@ -16,7 +16,7 @@ import strutils #Exceptions type - EDOMException* = object of E_Base ## Base exception object for all DOM Exceptions + EDOMException* = object of EInvalidValue ## Base exception object for all DOM Exceptions EDOMStringSizeErr* = object of EDOMException ## If the specified range of text does not fit into a DOMString ## Currently not used(Since DOMString is just string) EHierarchyRequestErr* = object of EDOMException ## If any node is inserted somewhere it doesn't belong diff --git a/lib/pure/xmldomparser.nim b/lib/pure/xmldomparser.nim index d9eb210c3..fda46bac0 100755 --- a/lib/pure/xmldomparser.nim +++ b/lib/pure/xmldomparser.nim @@ -15,8 +15,8 @@ import xmldom, os, streams, parsexml, strutils type # Parsing errors - EMismatchedTag* = object of E_Base ## Raised when a tag is not properly closed - EParserError* = object of E_Base ## Raised when an unexpected XML Parser event occurs + EMismatchedTag* = object of EInvalidValue ## Raised when a tag is not properly closed + EParserError* = object of EInvalidValue ## Raised when an unexpected XML Parser event occurs # For namespaces xmlnsAttr = tuple[name, value: string, ownerElement: PElement] diff --git a/lib/pure/xmlparser.nim b/lib/pure/xmlparser.nim index 635497fa8..ad28bf618 100755 --- a/lib/pure/xmlparser.nim +++ b/lib/pure/xmlparser.nim @@ -12,8 +12,9 @@ import streams, parsexml, strtabs, xmltree type - EInvalidXml* = object of E_Base ## exception that is raised for invalid XML - errors*: seq[string] ## all detected parsing errors + EInvalidXml* = object of EInvalidValue ## exception that is raised + ## for invalid XML + errors*: seq[string] ## all detected parsing errors proc raiseInvalidXml(errors: seq[string]) = var e: ref EInvalidXml diff --git a/lib/system/sysstr.nim b/lib/system/sysstr.nim index 41efdf431..6c5435724 100755 --- a/lib/system/sysstr.nim +++ b/lib/system/sysstr.nim @@ -244,7 +244,7 @@ proc nimIntToStr(x: int): string {.compilerRtl.} = proc nimFloatToStr(x: float): string {.compilerproc.} = var buf: array [0..59, char] - c_sprintf(buf, "%#g", x) + c_sprintf(buf, "%#.16e", x) return $buf proc nimInt64ToStr(x: int64): string {.compilerRtl.} = diff --git a/rod/docgen.nim b/rod/docgen.nim index 7e141d633..ade2aa93f 100755 --- a/rod/docgen.nim +++ b/rod/docgen.nim @@ -32,7 +32,7 @@ type filename*: string # filename of the source file; without extension basedir*: string # base directory (where to put the documentation) modDesc*: PRope # module description - dependsOn*: PRope # dependencies + deps*: PRope # dependencies id*: int # for generating IDs splitAfter*: int # split too long entries in the TOC tocPart*: seq[TTocEntry] @@ -755,6 +755,19 @@ proc renderRstToOut(d: PDoc, n: PRstNode): PRope = proc checkForFalse(n: PNode): bool = result = n.kind == nkIdent and IdentEq(n.ident, "false") +proc getModuleFile(n: PNode): string = + case n.kind + of nkStrLit, nkRStrLit, nkTripleStrLit: result = n.strVal + of nkIdent: result = n.ident.s + of nkSym: result = n.sym.name.s + else: + internalError(n.info, "getModuleFile()") + result = "" + +proc traceDeps(d: PDoc, n: PNode) = + if d.deps != nil: app(d.deps, ", ") + app(d.deps, getModuleFile(n)) + proc generateDoc(d: PDoc, n: PNode) = if n == nil: return case n.kind @@ -783,6 +796,9 @@ proc generateDoc(d: PDoc, n: PNode) = # generate documentation for the first branch only: if not checkForFalse(n.sons[0].sons[0]): generateDoc(d, lastSon(n.sons[0])) + of nkImportStmt: + for i in 0 .. sonsLen(n)-1: traceDeps(d, n.sons[i]) + of nkFromStmt: traceDeps(d, n.sons[0]) else: nil proc genSection(d: PDoc, kind: TSymKind) = @@ -817,12 +833,14 @@ proc genOutFile(d: PDoc): PRope = if d.hasToc: bodyname = "doc.body_toc" else: bodyname = "doc.body_no_toc" content = ropeFormatNamedVars(getConfigVar(bodyname), ["title", - "tableofcontents", "moduledesc", "date", "time", "content"], [title, toc, - d.modDesc, toRope(getDateStr()), toRope(getClockStr()), code]) - if not (optCompileOnly in gGlobalOptions): + "tableofcontents", "moduledesc", "deps", "date", "time", "content"], + [title, toc, d.modDesc, d.deps, toRope(getDateStr()), + toRope(getClockStr()), code]) + if optCompileOnly notin gGlobalOptions: code = ropeFormatNamedVars(getConfigVar("doc.file"), ["title", - "tableofcontents", "moduledesc", "date", "time", "content", "author", - "version"], [title, toc, d.modDesc, toRope(getDateStr()), + "tableofcontents", "moduledesc", "deps", "date", "time", + "content", "author", "version"], + [title, toc, d.modDesc, d.deps, toRope(getDateStr()), toRope(getClockStr()), content, d.meta[metaAuthor], d.meta[metaVersion]]) else: |