first steps for the 'export' feature

This commit is contained in:
Araq 2012-11-28 02:02:46 +01:00
commit 0d19de18cc
5 changed files with 114 additions and 175 deletions

View file

@ -173,7 +173,9 @@ type
nkStmtList, # a list of statements nkStmtList, # a list of statements
nkImportStmt, # an import statement nkImportStmt, # an import statement
nkFromStmt, # a from * import statement nkFromStmt, # a from * import statement
nkImportExceptStmt, # an import x except a statement
nkIncludeStmt, # an include statement nkIncludeStmt, # an include statement
nkExportStmt, # an export statement
nkBindStmt, # a bind statement nkBindStmt, # a bind statement
nkMixinStmt, # a mixin statement nkMixinStmt, # a mixin statement
nkCommentStmt, # a comment statement nkCommentStmt, # a comment statement

View file

@ -901,27 +901,30 @@ proc parseExprStmt(p: var TParser): PNode =
addSon(result, b) addSon(result, b)
if b.kind == nkElse: break 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 var a: PNode
result = newNodeP(kind, p) result = newNodeP(kind, p)
getTok(p) # skip `import` or `include` getTok(p) # skip `import` or `include`
optInd(p, result) optInd(p, result)
while true: while true:
case p.tok.tokType case p.tok.tokType
of tkEof, tkSad, tkDed: of tkEof, tkSad, tkDed:
break break
of tkSymbol, tkAccent: of tkSymbol, tkAccent:
a = parseSymbol(p) a = parseSymbol(p)
of tkRStrLit: of tkRStrLit:
a = newStrNodeP(nkRStrLit, p.tok.literal, p) a = newStrNodeP(nkRStrLit, p.tok.literal, p)
getTok(p) getTok(p)
of tkStrLit: of tkStrLit:
a = newStrNodeP(nkStrLit, p.tok.literal, p) a = newStrNodeP(nkStrLit, p.tok.literal, p)
getTok(p) getTok(p)
of tkTripleStrLit: of tkTripleStrLit:
a = newStrNodeP(nkTripleStrLit, p.tok.literal, p) a = newStrNodeP(nkTripleStrLit, p.tok.literal, p)
getTok(p) getTok(p)
else: else:
parMessage(p, errIdentifierExpected, p.tok) parMessage(p, errIdentifierExpected, p.tok)
break break
addSon(result, a) addSon(result, a)
@ -931,25 +934,10 @@ proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode =
expectNl(p) expectNl(p)
proc parseFromStmt(p: var TParser): PNode = proc parseFromStmt(p: var TParser): PNode =
var a: PNode
result = newNodeP(nkFromStmt, p) result = newNodeP(nkFromStmt, p)
getTok(p) # skip `from` getTok(p) # skip `from`
optInd(p, result) optInd(p, result)
case p.tok.tokType var a = parseModuleName(p)
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
addSon(result, a) #optInd(p, a); addSon(result, a) #optInd(p, a);
eat(p, tkImport) eat(p, tkImport)
optInd(p, result) optInd(p, result)

View file

@ -1148,6 +1148,14 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
putWithSpace(g, tkImport, "import") putWithSpace(g, tkImport, "import")
gcomma(g, n, emptyContext, 1) gcomma(g, n, emptyContext, 1)
putNL(g) 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: of nkIncludeStmt:
putWithSpace(g, tkInclude, "include") putWithSpace(g, tkInclude, "include")
gcoms(g) gcoms(g)
@ -1155,6 +1163,13 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
gcommaAux(g, n, g.indent) gcommaAux(g, n, g.indent)
dedent(g) dedent(g)
putNL(g) putNL(g)
of nkExportStmt:
putWithSpace(g, tkExport, "export")
gcoms(g)
indentNL(g)
gcommaAux(g, n, g.indent)
dedent(g)
putNL(g)
of nkCommentStmt: of nkCommentStmt:
gcoms(g) gcoms(g)
optNL(g) optNL(g)

View file

@ -45,8 +45,14 @@ type
nnkConstDef, nnkTypeDef, nnkConstDef, nnkTypeDef,
nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt, nnkYieldStmt, nnkTryStmt, nnkFinally, nnkRaiseStmt,
nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt, nnkReturnStmt, nnkBreakStmt, nnkContinueStmt, nnkBlockStmt, nnkStaticStmt,
nnkDiscardStmt, nnkStmtList, nnkImportStmt, nnkFromStmt, nnkDiscardStmt, nnkStmtList,
nnkIncludeStmt, nnkBindStmt, nnkMixinStmt,
nnkImportStmt, nnkFromStmt,
nkImportExceptStmt,
nnkIncludeStmt,
nnkExportStmt,
nnkBindStmt, nnkMixinStmt,
nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr,
nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy,
nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen, nnkTupleTy, nnkRecList, nnkRecCase, nnkRecWhen,

224
todo.txt
View file

@ -1,9 +1,10 @@
version 0.9.2 version 0.9.2
============= =============
- 'export' feature; from buggymodule import * except optBroken, optBroken2
- test&finish first class iterators: - test&finish first class iterators:
* nested iterators * nested iterators
* arglist as a type? * test generic iterators
- fix closure bug finally - fix closure bug finally
- overloading based on ASTs: 'constraint' should not be in PType but for the - 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 - ``hoist`` pragma for loop hoisting: can be easily done with
AST overloading + global 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 - improve the compiler as a service
- ``=`` should be overloadable; requires specialization for ``=`` - ``=`` should be overloadable; requires specialization for ``=``
- implement constructors - implement constructors + full 'not nil' checking
- make 'bind' default for templates and introduce 'mixin'; - make 'bind' default for templates and introduce 'mixin';
special rule for ``[]=`` special rule for ``[]=``
- implicit deref for parameter matching; overloading based on 'var T' - implicit deref for parameter matching; overloading based on 'var T'
- optimize genericAssign in the code generator - 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 - better support for macros that rewrite procs
- macros need access to types and symbols (partially implemented) - 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 - rethink the syntax/grammar:
------- * parser is not strict enough with newlines
* change comment handling in the AST
- suffix trees
- locale support; i18n module
- bignums
Low priority Concurrency
------------ -----------
- 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
====================
- shared memory heap: ``shared ref`` etc. The only hard part in the GC is to - 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 "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 calls syncGC() so that's pointless.) Hm instead of an heuristic simply
provide a ``syncgc`` pragma to trigger compiler injection --> more general: provide a ``syncgc`` pragma to trigger compiler injection --> more general:
an ``injectLoop`` pragma 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 GC
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
- better for backwards compatibility: default nilable, but ``not nil`` - precise stack marking; embrace C++ code generation for that
notation: - marker procs for Boehm GC
- implement 'mixed' GC mode
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
- guards for the 'case' statement; generalized case statement;
a guard looks like: version 0.9.XX
==============
case x
of nkStmtList if x.value == 0: - implement the "snoopResult" pragma; no, make a strutils with string append
semantics instead ...
a generalized case statement looks like: - implement "closure tuple consists of a single 'ref'" optimization
- object branch transitions can't work with the current 'reset'; add a 'reset'
case x with `=~` 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