diff --git a/compiler/ast.nim b/compiler/ast.nim index 027f4d003..77f8723e2 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -173,7 +173,9 @@ type nkStmtList, # a list of statements nkImportStmt, # an import statement nkFromStmt, # a from * import statement + nkImportExceptStmt, # an import x except a statement nkIncludeStmt, # an include statement + nkExportStmt, # an export statement nkBindStmt, # a bind statement nkMixinStmt, # a mixin statement nkCommentStmt, # a comment statement diff --git a/compiler/parser.nim b/compiler/parser.nim index d5457fcd8..7ab87804e 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -901,27 +901,30 @@ proc parseExprStmt(p: var TParser): PNode = addSon(result, b) if b.kind == nkElse: break -proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = +proc parseModuleName(p: var TParser): PNode {.inline.} = + result = parseExpr(p) + +proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = var a: PNode result = newNodeP(kind, p) getTok(p) # skip `import` or `include` optInd(p, result) - while true: + while true: case p.tok.tokType - of tkEof, tkSad, tkDed: - break - of tkSymbol, tkAccent: + of tkEof, tkSad, tkDed: + break + of tkSymbol, tkAccent: a = parseSymbol(p) - of tkRStrLit: + of tkRStrLit: a = newStrNodeP(nkRStrLit, p.tok.literal, p) getTok(p) - of tkStrLit: + of tkStrLit: a = newStrNodeP(nkStrLit, p.tok.literal, p) getTok(p) - of tkTripleStrLit: + of tkTripleStrLit: a = newStrNodeP(nkTripleStrLit, p.tok.literal, p) getTok(p) - else: + else: parMessage(p, errIdentifierExpected, p.tok) break addSon(result, a) @@ -931,25 +934,10 @@ proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = expectNl(p) proc parseFromStmt(p: var TParser): PNode = - var a: PNode result = newNodeP(nkFromStmt, p) getTok(p) # skip `from` optInd(p, result) - case p.tok.tokType - of tkSymbol, tkAccent: - a = parseSymbol(p) - of tkRStrLit: - a = newStrNodeP(nkRStrLit, p.tok.literal, p) - getTok(p) - of tkStrLit: - a = newStrNodeP(nkStrLit, p.tok.literal, p) - getTok(p) - of tkTripleStrLit: - a = newStrNodeP(nkTripleStrLit, p.tok.literal, p) - getTok(p) - else: - parMessage(p, errIdentifierExpected, p.tok) - return + var a = parseModuleName(p) addSon(result, a) #optInd(p, a); eat(p, tkImport) optInd(p, result) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index b9d522694..4444f2ab0 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1148,6 +1148,14 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = putWithSpace(g, tkImport, "import") gcomma(g, n, emptyContext, 1) putNL(g) + of nkImportExceptStmt: + putWithSpace(g, tkImport, "import") + gsub(g, n.sons[0]) + put(g, tkSpaces, Space) + putWithSpace(g, tkExcept, "except") + gcommaAux(g, n, g.indent, 1) + gcoms(g) + putNL(g) of nkIncludeStmt: putWithSpace(g, tkInclude, "include") gcoms(g) @@ -1155,6 +1163,13 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = gcommaAux(g, n, g.indent) dedent(g) putNL(g) + of nkExportStmt: + putWithSpace(g, tkExport, "export") + gcoms(g) + indentNL(g) + gcommaAux(g, n, g.indent) + dedent(g) + putNL(g) of nkCommentStmt: gcoms(g) optNL(g) diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 966a21a1b..d2d842025 100755 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -45,8 +45,14 @@ type nnkConstDef, nnkTypeDef, nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt, - nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt, - nnkIncludeStmt, nnkBindStmt, nnkMixinStmt, + nnkDiscardStmt, nnkStmtList, + + nnkImportStmt, nnkFromStmt, + nkImportExceptStmt, + nnkIncludeStmt, + nnkExportStmt, + + nnkBindStmt, nnkMixinStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, diff --git a/todo.txt b/todo.txt index 7e940c3e4..10b044a6d 100755 --- a/todo.txt +++ b/todo.txt @@ -1,9 +1,10 @@ version 0.9.2 ============= - + +- 'export' feature; from buggymodule import * except optBroken, optBroken2 - test&finish first class iterators: * nested iterators - * arglist as a type? + * test generic iterators - fix closure bug finally - overloading based on ASTs: 'constraint' should not be in PType but for the @@ -14,130 +15,31 @@ version 0.9.2 - ``hoist`` pragma for loop hoisting: can be easily done with AST overloading + global +- implement ``system.unsafeNew``. + + +version 0.9.X +============= + +- implement the missing features wrt inheritance +- implement generic methods - improve the compiler as a service - ``=`` should be overloadable; requires specialization for ``=`` -- implement constructors +- implement constructors + full 'not nil' checking - make 'bind' default for templates and introduce 'mixin'; special rule for ``[]=`` - implicit deref for parameter matching; overloading based on 'var T' - optimize genericAssign in the code generator - - -Bugs ----- - -- sneaking with qualifiedLookup() is really broken! -- bug: aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' -- - use a qualifier -- bug: the parser is not strict enough with newlines: 'echo "a" echo "b"' - compiles -- bug: blocks can "export" an identifier but the CCG generates {} for them ... - - -version 0.9.XX -============== - -- improve not-nil types -- make: - p(a, b): - echo a - echo b - - the same as: - - p(a, b, proc() = - echo a - echo b) - -- implement read/write tracking in the effect system -- implement the "snoopResult" pragma; no, make a strutils with string append - semantics instead ... -- implement "closure tuple consists of a single 'ref'" optimization -- JS gen: - - fix exception handling -- object branch transitions can't work with the current 'reset'; add a 'reset' - with an additional parameter --> re-evaluate this issue after constructors - have been added -- fix remaining closure bugs: - - test evals.nim with closures - - what about macros with closures? - -- allow implicit forward declarations of procs via a pragma (so that the - wrappers can deactivate it) -- rethink the syntax: distinction between expr and stmt is unfortunate; - indentation handling is quite complex too; problem with exception handling - is that often the scope of ``try`` is wrong and apart from that ``try`` is - a full blown statement; a ``try`` expression might be a good idea to make - error handling more light-weight -- fix destructors; don't work yet when used as expression -- make use of ``tyIter`` to fix the implicit items/pairs issue - better support for macros that rewrite procs - macros need access to types and symbols (partially implemented) -- document nimdoc properly finally -- make 'clamp' a magic for the range stuff -- we need to support iteration of 2 different data structures in parallel -- 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 -- make pegs support a compile-time option and make c2nim use regexes instead - per default? -- 'const' objects including case objects -- 'export' feature -- from buggymodule import * except optBroken, optBroken2 -- think about ``{:}.toTable[int, string]()`` -- mocking support with ``tyProxy`` that does: - o.p(x) --> p(o, x) --> myMacro(p, o, x) - - This is really the opposite of ``tyExpr``: - * For parameter ``tyExpr`` any argument matches. - * Argument ``tyProxy`` matches any parameter. - -Library -------- - -- suffix trees -- locale support; i18n module -- bignums +- rethink the syntax/grammar: + * parser is not strict enough with newlines + * change comment handling in the AST -Low priority ------------- - -- change how comments are part of the AST -- ``with proc `+`(x, y: T): T`` for generic code -- new feature: ``distinct T with operations`` -- implement the "easy" constructors idea -- resizing of strings/sequences could take into account the memory that - is allocated -- timeout for locks -- compilation cache: - - adapt thread var emulation to care about the new merge operation - - check for interface changes; if only the implementation changes, no - need to recompile clients; er ... what about templates, macros or anything - that has inlining semantics? -- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC -- GC: precise stack marking; - escape analysis for string/seq seems to be easy to do too; - even further write barrier specialization -- GC: marker procs Boehm GC -- implement marker procs for message passing -- optimize method dispatchers -- activate more thread tests -- implement ``--script:sh|bat`` command line option; think about script - generation -- implement closures that support nesting of *procs* > 1 - - -Further optimization ideas -========================== - -- To optimize further copies away, you want to gather the additional - information inlining would provide, but don't inline for code size reasons. - - -Version 2 and beyond -==================== +Concurrency +----------- - shared memory heap: ``shared ref`` etc. The only hard part in the GC is to "stop the world". However, it may be worthwhile to generate explicit @@ -147,40 +49,66 @@ Version 2 and beyond calls syncGC() so that's pointless.) Hm instead of an heuristic simply provide a ``syncgc`` pragma to trigger compiler injection --> more general: an ``injectLoop`` pragma +- 'writes: []' effect; track reads/writes for shared types +- use the effect system to for static deadlock prevention -- const ptr/ref --> pointless because of aliasing; - much better: 'writes: []' effect -- language change: inheritance should only work with reference types, so that - the ``type`` field is not needed for objects! --> zero overhead aggregation - BETTER: ``of`` and safe object conversions only work with ref objects. Same - for multi methods. - -- explicit nil types? - * nil seq[int] - * nil string - * nil ref int - * nil ptr THallo - * nil proc +GC +== -- better for backwards compatibility: default nilable, but ``not nil`` - notation: - - type - PWindow = ref TWindow not nil - - The problem with ``nil`` is that the language currently relies on it for - implicit initialization. Initialization is different from assignment. The - issues can "easily" dealt with by ensuring: - - var x = myProc() # checks myProc() initializes every pointer explicitely +- precise stack marking; embrace C++ code generation for that +- marker procs for Boehm GC +- implement 'mixed' GC mode -- guards for the 'case' statement; generalized case statement; - a guard looks like: - - case x - of nkStmtList if x.value == 0: - - a generalized case statement looks like: - - case x with `=~` + +version 0.9.XX +============== + +- implement the "snoopResult" pragma; no, make a strutils with string append + semantics instead ... +- implement "closure tuple consists of a single 'ref'" optimization +- object branch transitions can't work with the current 'reset'; add a 'reset' + with an additional parameter --> re-evaluate this issue after constructors + have been added +- allow implicit forward declarations of procs via a pragma (so that the + wrappers can deactivate it) +- fix destructors; don't work yet when used as expression +- document nimdoc properly finally +- make 'clamp' a magic for the range stuff +- 'const' objects including case objects +- mocking support with ``tyProxy`` that does: fallback for ``.`` operator + + +Not essential for 1.0.0 +======================= + +- investigate the implicit items/pairs issue +- optimize method dispatchers +- ``with proc `+`(x, y: T): T`` for generic code +- new feature: ``distinct T with operations`` +- arglist as a type (iterator chaining); variable length type lists for generics +- resizing of strings/sequences could take into account the memory that + is allocated +- codegen should use "NIM_CAST" macro and respect aliasing rules for GCC +- implement marker procs for message passing +- activate more thread tests +- implement closures that support nesting of *procs* > 1 + + +Optimizations +============= + +- escape analysis for string/seq seems to be easy to do too; + even further write barrier specialization +- inlining of first class functions +- proc specialization in the code gen for write barrier specialization + + +Bugs +==== + +- sneaking with qualifiedLookup() is really broken! +- aporia.nim(968, 5) Error: ambiguous identifier: 'DELETE' -- + use a qualifier +- blocks can "export" an identifier but the CCG generates {} for them ... +- JS gen: fix exception handling