diff options
-rwxr-xr-x | compiler/commands.nim | 3 | ||||
-rw-r--r-- | compiler/docgen2.nim | 11 | ||||
-rwxr-xr-x | compiler/lexer.nim | 1 | ||||
-rwxr-xr-x | compiler/main.nim | 14 | ||||
-rwxr-xr-x | compiler/options.nim | 2 | ||||
-rw-r--r-- | compiler/sempass2.nim | 65 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 4 | ||||
-rwxr-xr-x | compiler/transf.nim | 8 | ||||
-rwxr-xr-x | doc/advopt.txt | 1 | ||||
-rwxr-xr-x | lib/system.nim | 17 | ||||
-rwxr-xr-x | todo.txt | 9 | ||||
-rwxr-xr-x | web/news.txt | 2 | ||||
-rwxr-xr-x | web/nimrod.ini | 44 | ||||
-rwxr-xr-x | web/question.txt | 2 |
14 files changed, 108 insertions, 75 deletions
diff --git a/compiler/commands.nim b/compiler/commands.nim index b6ef02fe1..50b4a1e6f 100755 --- a/compiler/commands.nim +++ b/compiler/commands.nim @@ -268,6 +268,9 @@ proc processSwitch(switch, arg: string, pass: TCmdlinePass, info: TLineInfo) = of "forcebuild", "f": expectNoArg(switch, arg, pass, info) incl(gGlobalOptions, optForceFullMake) + of "project": + expectNoArg(switch, arg, pass, info) + gWholeProject = true of "gc": expectArg(switch, arg, pass, info) case arg.normalize diff --git a/compiler/docgen2.nim b/compiler/docgen2.nim index ba3f5d4ca..2d175adbf 100644 --- a/compiler/docgen2.nim +++ b/compiler/docgen2.nim @@ -23,11 +23,12 @@ type proc close(p: PPassContext, n: PNode): PNode = var g = PGen(p) let useWarning = sfMainModule notin g.module.flags - writeOutput(g.doc, g.filename, HtmlExt, useWarning) - try: - generateIndex(g.doc) - except EIO: - nil + if gWholeProject or sfMainModule in g.module.flags: + writeOutput(g.doc, g.filename, HtmlExt, useWarning) + try: + generateIndex(g.doc) + except EIO: + nil proc processNode(c: PPassContext, n: PNode): PNode = result = n diff --git a/compiler/lexer.nim b/compiler/lexer.nim index faa9fc672..59e367962 100755 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -679,6 +679,7 @@ proc scanComment(L: var TLexer, tok: var TToken) = inc(indent) if buf[pos] == '#' and (col == indent or lastBackslash > 0): tok.literal.add "\n" + col = indent else: if buf[pos] > ' ': L.indentAhead = indent diff --git a/compiler/main.nim b/compiler/main.nim index 26b3c9c4c..9aefa3eb3 100755 --- a/compiler/main.nim +++ b/compiler/main.nim @@ -83,9 +83,19 @@ proc CompileModule(filename: string, flags: TSymFlags): PSym = result.id = getID() processModule(result, f, nil, rd) +proc `==^`(a, b: string): bool = + try: + result = sameFile(a, b) + except EOS: + result = false + proc CompileProject(projectFile = gProjectFull) = - discard CompileModule(options.libpath / "system", {sfSystemModule}) - discard CompileModule(projectFile, {sfMainModule}) + let systemFile = options.libpath / "system" + if projectFile.addFileExt(nimExt) ==^ systemFile.addFileExt(nimExt): + discard CompileModule(projectFile, {sfMainModule, sfSystemModule}) + else: + discard CompileModule(systemFile, {sfSystemModule}) + discard CompileModule(projectFile, {sfMainModule}) proc semanticPasses = registerPass(verbosePass()) diff --git a/compiler/options.nim b/compiler/options.nim index 2051953ce..42fca1ad1 100755 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -95,6 +95,8 @@ var gVerbosity*: int # how verbose the compiler is gNumberOfProcessors*: int # number of processors + gWholeProject*: bool # for 'doc2': output any dependency + const genSubDir* = "nimcache" NimExt* = "nim" diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index c3e2ce8bc..bd8a3ba02 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -9,7 +9,7 @@ import intsets, ast, astalgo, msgs, renderer, magicsys, types, idents, trees, - wordrecg, strutils + wordrecg, strutils, options # Second semantic checking pass over the AST. Necessary because the old # way had some inherent problems. Performs: @@ -92,30 +92,44 @@ proc excType(n: PNode): PType = let t = if n.kind == nkEmpty: sysTypeFromName"E_Base" else: n.typ result = skipTypes(t, skipPtrs) +proc createRaise(n: PNode): PNode = + result = newNode(nkType) + result.typ = sysTypeFromName"E_Base" + if not n.isNil: result.info = n.info + +proc createTag(n: PNode): PNode = + result = newNode(nkType) + result.typ = sysTypeFromName"TEffect" + if not n.isNil: result.info = n.info + proc addEffect(a: PEffects, e: PNode, useLineInfo=true) = assert e.kind != nkRaiseStmt var aa = a.exc for i in a.bottom .. <aa.len: if sameType(aa[i].excType, e.excType): - if not useLineInfo: return + if not useLineInfo or gCmd == cmdDoc: return elif aa[i].info == e.info: return throws(a.exc, e) -proc mergeEffects(a: PEffects, b: PNode, useLineInfo: bool) = - if not b.isNil: - for effect in items(b): addEffect(a, effect, useLineInfo) - proc addTag(a: PEffects, e: PNode, useLineInfo=true) = var aa = a.tags for i in 0 .. <aa.len: if sameType(aa[i].typ.skipTypes(skipPtrs), e.typ.skipTypes(skipPtrs)): - if not useLineInfo: return + if not useLineInfo or gCmd == cmdDoc: return elif aa[i].info == e.info: return throws(a.tags, e) -proc mergeTags(a: PEffects, b: PNode, useLineInfo: bool) = - if not b.isNil: - for effect in items(b): addTag(a, effect, useLineInfo) +proc mergeEffects(a: PEffects, b, comesFrom: PNode) = + if b.isNil: + addEffect(a, createRaise(comesFrom)) + else: + for effect in items(b): addEffect(a, effect, useLineInfo=comesFrom != nil) + +proc mergeTags(a: PEffects, b, comesFrom: PNode) = + if b.isNil: + addTag(a, createTag(comesFrom)) + else: + for effect in items(b): addTag(a, effect, useLineInfo=comesFrom != nil) proc listEffects(a: PEffects) = for e in items(a.exc): Message(e.info, hintUser, typeToString(e.typ)) @@ -197,6 +211,8 @@ proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int) = var t = typeToString(real[i].typ) if t.startsWith("ref "): t = substr(t, 4) effects.sons[i] = newIdentNode(getIdent(t), n.info) + # set the type so that the following analysis doesn't screw up: + effects.sons[i].typ = real[i].typ var pair = newNode(nkExprColonExpr, n.info, @[ newIdentNode(getIdent(specialWords[effectType]), n.info), effects]) @@ -208,34 +224,20 @@ proc documentEffect(n, x: PNode, effectType: TSpecialWord, idx: int) = proc documentRaises*(n: PNode) = if n.sons[namePos].kind != nkSym: return - - var x = n.sons[pragmasPos] - documentEffect(n, x, wRaises, exceptionEffects) - documentEffect(n, x, wTags, tagEffects) - -proc createRaise(n: PNode): PNode = - result = newNodeIT(nkType, n.info, sysTypeFromName"E_Base") - -proc createTag(n: PNode): PNode = - result = newNodeIT(nkType, n.info, sysTypeFromName"TEffect") + documentEffect(n, n.sons[pragmasPos], wRaises, exceptionEffects) + documentEffect(n, n.sons[pragmasPos], wTags, tagEffects) proc propagateEffects(tracked: PEffects, n: PNode, s: PSym) = let pragma = s.ast.sons[pragmasPos] let spec = effectSpec(pragma, wRaises) - if not isNil(spec): - mergeEffects(tracked, spec, useLineInfo=false) - else: - addEffect(tracked, createRaise(n)) + mergeEffects(tracked, spec, n) let tagSpec = effectSpec(pragma, wTags) - if not isNil(tagSpec): - mergeTags(tracked, tagSpec, useLineInfo=false) - else: - addTag(tracked, createTag(n)) + mergeTags(tracked, tagSpec, n) proc track(tracked: PEffects, n: PNode) = case n.kind - of nkRaiseStmt: + of nkRaiseStmt: n.sons[0].info = n.info throws(tracked.exc, n.sons[0]) of nkCallKinds: @@ -254,8 +256,8 @@ proc track(tracked: PEffects, n: PNode) = addEffect(tracked, createRaise(n)) addTag(tracked, createTag(n)) else: - mergeEffects(tracked, effectList.sons[exceptionEffects], true) - mergeTags(tracked, effectList.sons[tagEffects], true) + mergeEffects(tracked, effectList.sons[exceptionEffects], n) + mergeTags(tracked, effectList.sons[tagEffects], n) of nkTryStmt: trackTryStmt(tracked, n) return @@ -346,3 +348,4 @@ proc trackProc*(s: PSym, body: PNode) = hints=off) # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec + \ No newline at end of file diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index e613f23af..a08c39ce6 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -247,6 +247,9 @@ proc semVarOrLet(c: PContext, n: PNode, symkind: TSymKind): PNode = if a.kind != nkVarTuple: v.typ = typ b = newNodeI(nkIdentDefs, a.info) + if gCmd == cmdDoc: + # keep documentation information: + b.comment = a.comment addSon(b, newSymNode(v)) addSon(b, a.sons[length-2]) # keep type desc for doc generator addSon(b, copyTree(def)) @@ -284,6 +287,7 @@ proc semConst(c: PContext, n: PNode): PNode = v.ast = def # no need to copy if sfGenSym notin v.flags: addInterfaceDecl(c, v) var b = newNodeI(nkConstDef, a.info) + if gCmd == cmdDoc: b.comment = a.comment addSon(b, newSymNode(v)) addSon(b, ast.emptyNode) # no type description addSon(b, copyTree(def)) diff --git a/compiler/transf.nim b/compiler/transf.nim index d28b9b21d..dfa4095b4 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -150,6 +150,9 @@ proc transformVarSection(c: PTransf, v: PNode): PTransNode = newVar.owner = getCurrOwner(c) IdNodeTablePut(c.transCon.mapping, it.sons[0].sym, newSymNode(newVar)) var defs = newTransNode(nkIdentDefs, it.info, 3) + if gCmd == cmdDoc: + # keep documentation information: + pnode(defs).comment = it.comment defs[0] = newSymNode(newVar).PTransNode defs[1] = it.sons[1].PTransNode defs[2] = transform(c, it.sons[2]) @@ -659,6 +662,11 @@ proc transform(c: PTransf, n: PNode): PTransNode = result = transformSons(c, n) of nkBlockStmt, nkBlockExpr: result = transformBlock(c, n) + of nkIdentDefs, nkConstDef: + result = transformSons(c, n) + # XXX comment handling really sucks: + if gCmd == cmdDoc: + pnode(result).comment = n.comment else: result = transformSons(c, n) var cnst = getConstExpr(c.module, PNode(result)) diff --git a/doc/advopt.txt b/doc/advopt.txt index dba0a009a..a6718572e 100755 --- a/doc/advopt.txt +++ b/doc/advopt.txt @@ -49,6 +49,7 @@ Advanced options: (you should omit platform-specific extensions) --genMapping generate a mapping file containing (Nimrod, mangled) identifier pairs + --project document the whole project (doc2) --lineDir:on|off generation of #line directive on|off --threadanalysis:on|off turn thread analysis on|off --tlsEmulation:on|off turn thread local storage emulation on|off diff --git a/lib/system.nim b/lib/system.nim index d4c7aaf5e..9ad99fb79 100755 --- a/lib/system.nim +++ b/lib/system.nim @@ -246,7 +246,7 @@ type EInvalidLibrary* = object of EOS ## raised if a dynamic library ## could not be loaded. EResourceExhausted* = object of ESystem ## raised if a resource request - ## could not be fullfilled. + ## could not be fullfilled. EArithmetic* = object of ESynch ## raised if any kind of arithmetic ## error occured. EDivByZero* {.compilerproc.} = @@ -847,7 +847,12 @@ when taintMode: proc len*(s: TaintedString): int {.borrow.} else: - type TaintedString* = string + type TaintedString* = string ## a distinct string type that + ## is `tainted`:idx:. It is an alias for + ## ``string`` if the taint mode is not + ## turned on. Use the ``-d:taintMode`` + ## command line switch to turn the taint + ## mode on. when defined(profiler): proc nimProfile() {.compilerProc, noinline.} @@ -1817,8 +1822,7 @@ when not defined(EcmaScript) and not defined(NimrodVM): ## Returns true iff `f` is at the end. proc readChar*(f: TFile): char {.importc: "fgetc", nodecl, tags: [FReadIO].} - ## Reads a single character from the stream `f`. If the stream - ## has no more characters, `EEndOfFile` is raised. + ## Reads a single character from the stream `f`. proc FlushFile*(f: TFile) {.importc: "fflush", noDecl, tags: [FWriteIO].} ## Flushes `f`'s buffer. @@ -2317,10 +2321,11 @@ proc raiseAssert*(msg: string) {.noinline.} = raise newException(EAssertionFailed, msg) when true: - proc hiddenRaiseAssert(msg: string) {.raises: [].} = + proc hiddenRaiseAssert(msg: string) {.raises: [], tags: [].} = # trick the compiler to not list ``EAssertionFailed`` when called # by ``assert``. - type THide = proc (msg: string) {.noinline, raises: [], noSideEffect.} + type THide = proc (msg: string) {.noinline, raises: [], noSideEffect, + tags: [].} THide(raiseAssert)(msg) template assert*(cond: bool, msg = "") = diff --git a/todo.txt b/todo.txt index a754bc650..90fc38485 100755 --- a/todo.txt +++ b/todo.txt @@ -1,11 +1,6 @@ version 0.9.2 ============= - -- improve 'doc2': - * respect output directory - * write only 1 file unless requested 'whole project' - * make it work for the 'system' module - * the documentation system should default to 'doc2' + - test&finish first class iterators: * allow return in first class iterators * nested iterators @@ -82,9 +77,7 @@ version 0.9.XX - macros need access to types and symbols (partially implemented) - document nimdoc properly finally - make 'clamp' a magic for the range stuff -- implement a warning message for shadowed 'result' variable - we need to support iteration of 2 different data structures in parallel -- implement proper coroutines - proc specialization in the code gen for write barrier specialization - tlastmod returns wrong results on BSD (Linux, MacOS X: works) - nested tuple unpacking; tuple unpacking in non-var-context diff --git a/web/news.txt b/web/news.txt index 8474db4f9..4150ddf8d 100755 --- a/web/news.txt +++ b/web/news.txt @@ -27,6 +27,8 @@ Changes affecting backwards compatibility Compiler Additions ------------------ +- The ``doc2`` command does not generate output for the whole project anymore. + Use the new ``--project`` switch to enable this behaviour. - The compiler can now warn about shadowed local variables. However, this needs to be turned on explicitly via ``--warning[ShadowIdent]:on``. diff --git a/web/nimrod.ini b/web/nimrod.ini index 047677ae5..4213eda9a 100755 --- a/web/nimrod.ini +++ b/web/nimrod.ini @@ -25,28 +25,28 @@ file: ticker doc: "endb;intern;apis;lib;manual;tut1;tut2;nimrodc;overview;filters;trmacros" doc: "tools;c2nim;niminst;nimgrep;gc;estp" pdf: "manual;lib;tut1;tut2;nimrodc;c2nim;niminst;gc" -srcdoc2: "impure/graphics;wrappers/sdl" -srcdoc: "core/macros;pure/marshal;core/typeinfo;core/unsigned" -srcdoc: "impure/re;pure/sockets" -srcdoc: "system.nim;system/threads.nim;system/channels.nim" -srcdoc: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" -srcdoc: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib" -srcdoc: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase" -srcdoc: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" -srcdoc: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode" -srcdoc: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers" -srcdoc: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;impure/db_mongo" -srcdoc: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor" -srcdoc: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" -srcdoc: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes" -srcdoc: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics" -srcdoc: "impure/rdstdin;wrappers/zmq;wrappers/sphinx" -srcdoc: "pure/collections/tables;pure/collections/sets;pure/collections/lists" -srcdoc: "pure/collections/intsets;pure/collections/queues;pure/encodings" -srcdoc: "pure/events;pure/collections/sequtils;pure/irc;ecmas/dom;pure/cookies" -srcdoc: "pure/ftpclient;pure/memfiles;pure/subexes;pure/collections/critbits" -srcdoc: "pure/asyncio;pure/actors;core/locks;pure/oids;pure/endians;pure/uri" -srcdoc: "pure/nimprof" +srcdoc2: "system.nim;impure/graphics;wrappers/sdl" +srcdoc2: "core/macros;pure/marshal;core/typeinfo;core/unsigned" +srcdoc2: "impure/re;pure/sockets" +srcdoc: "system/threads.nim;system/channels.nim" +srcdoc2: "pure/os;pure/strutils;pure/math;pure/matchers;pure/algorithm" +srcdoc2: "pure/complex;pure/times;pure/osproc;pure/pegs;pure/dynlib" +srcdoc2: "pure/parseopt;pure/hashes;pure/strtabs;pure/lexbase" +srcdoc2: "pure/parsecfg;pure/parsexml;pure/parsecsv;pure/parsesql" +srcdoc2: "pure/streams;pure/terminal;pure/cgi;impure/web;pure/unicode" +srcdoc2: "impure/zipfiles;pure/htmlgen;pure/parseutils;pure/browsers" +srcdoc2: "impure/db_postgres;impure/db_mysql;impure/db_sqlite;impure/db_mongo" +srcdoc2: "pure/httpserver;pure/httpclient;pure/smtp;impure/ssl;pure/fsmonitor" +srcdoc2: "pure/ropes;pure/unidecode/unidecode;pure/xmldom;pure/xmldomparser" +srcdoc2: "pure/xmlparser;pure/htmlparser;pure/xmltree;pure/colors;pure/mimetypes" +srcdoc2: "pure/json;pure/base64;pure/scgi;pure/redis;impure/graphics" +srcdoc2: "impure/rdstdin;wrappers/zmq;wrappers/sphinx" +srcdoc2: "pure/collections/tables;pure/collections/sets;pure/collections/lists" +srcdoc2: "pure/collections/intsets;pure/collections/queues;pure/encodings" +srcdoc2: "pure/events;pure/collections/sequtils;pure/irc;ecmas/dom;pure/cookies" +srcdoc2: "pure/ftpclient;pure/memfiles;pure/subexes;pure/collections/critbits" +srcdoc2: "pure/asyncio;pure/actors;core/locks;pure/oids;pure/endians;pure/uri" +srcdoc2: "pure/nimprof" webdoc: "wrappers/libcurl;pure/md5;wrappers/mysql;wrappers/iup" webdoc: "wrappers/sqlite3;wrappers/postgres;wrappers/tinyc" diff --git a/web/question.txt b/web/question.txt index 8e301b6bd..ebdcc091c 100755 --- a/web/question.txt +++ b/web/question.txt @@ -72,7 +72,7 @@ statements. How fast is Nimrod? ------------------- Benchmarks show it to be comparable to C. Some language features (methods, -closures, RTTI) are not yet as optimized as they could and will be. +closures, message passing) are not yet as optimized as they could and will be. The only overhead Nimrod has over C is the GC which has been tuned for years but still needs some work. |