summary refs log tree commit diff stats
path: root/compiler
diff options
context:
space:
mode:
authorZahary Karadjov <zahary@gmail.com>2018-05-04 17:47:37 +0300
committerAndreas Rumpf <rumpf_a@web.de>2018-05-07 09:37:49 +0200
commitcf13c5fba48e757531b3f9cb0e3aeae7710c849c (patch)
tree37c2ab529a4dfe808f6fd0118a5f7a51d51ad4ee /compiler
parent72976139009b9ae74669dc2443474f091c99f2e4 (diff)
downloadNim-cf13c5fba48e757531b3f9cb0e3aeae7710c849c.tar.gz
implement the export/except statement
Diffstat (limited to 'compiler')
-rw-r--r--compiler/importer.nim13
-rw-r--r--compiler/semexprs.nim23
2 files changed, 29 insertions, 7 deletions
diff --git a/compiler/importer.nim b/compiler/importer.nim
index f4903e6c4..a5c361864 100644
--- a/compiler/importer.nim
+++ b/compiler/importer.nim
@@ -16,6 +16,13 @@ import
 proc evalImport*(c: PContext, n: PNode): PNode
 proc evalFrom*(c: PContext, n: PNode): PNode
 
+proc readExceptSet*(n: PNode): IntSet =
+  assert n.kind in {nkImportExceptStmt, nkExportExceptStmt}
+  result = initIntSet()
+  for i in 1 ..< n.len:
+    let ident = lookups.considerQuotedIdent(n[i])
+    result.incl(ident.id)
+
 proc importPureEnumField*(c: PContext; s: PSym) =
   var check = strTableGet(c.importTable.symbols, s.name)
   if check == nil:
@@ -198,9 +205,5 @@ proc evalImportExcept*(c: PContext, n: PNode): PNode =
   if m != nil:
     n.sons[0] = newSymNode(m)
     addDecl(c, m, n.info)               # add symbol to symbol table of module
-    var exceptSet = initIntSet()
-    for i in countup(1, sonsLen(n) - 1):
-      let ident = lookups.considerQuotedIdent(n.sons[i])
-      exceptSet.incl(ident.id)
-    importAllSymbolsExcept(c, m, exceptSet)
+    importAllSymbolsExcept(c, m, readExceptSet(n))
     #importForwarded(c, m.ast, exceptSet)
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 5ef9916ad..1ef284a77 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -2160,9 +2160,25 @@ proc semBlock(c: PContext, n: PNode): PNode =
   closeScope(c)
   dec(c.p.nestedBlockCounter)
 
+proc semExportExcept(c: PContext, n: PNode): PNode =
+  let moduleName = semExpr(c, n[0])
+  if moduleName.kind != nkSym or moduleName.sym.kind != skModule:
+    localError(n.info, "The export/except syntax expects a module name")
+    return
+  let exceptSet = readExceptSet(n)
+  let exported = moduleName.sym
+  strTableAdd(c.module.tab, exported)
+  var i: TTabIter
+  var s = initTabIter(i, exported.tab)
+  while s != nil:
+    if s.kind in ExportableSymKinds+{skModule} and
+       s.name.id notin exceptSet:
+      strTableAdd(c.module.tab, s)
+    s = nextIter(i, exported.tab)
+  result = n
+
 proc semExport(c: PContext, n: PNode): PNode =
   var x = newNodeI(n.kind, n.info)
-  #let L = if n.kind == nkExportExceptStmt: L = 1 else: n.len
   for i in 0..<n.len:
     let a = n.sons[i]
     var o: TOverloadIter
@@ -2448,9 +2464,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
   of nkIncludeStmt:
     #if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "include")
     result = evalInclude(c, n)
-  of nkExportStmt, nkExportExceptStmt:
+  of nkExportStmt:
     if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export")
     result = semExport(c, n)
+  of nkExportExceptStmt:
+    if not isTopLevel(c): localError(n.info, errXOnlyAtModuleScope, "export")
+    result = semExportExcept(c, n)
   of nkPragmaBlock:
     result = semPragmaBlock(c, n)
   of nkStaticStmt: