From 02ff5f596c330b68927f843814ecb9b86c2eee67 Mon Sep 17 00:00:00 2001 From: Andreas Rumpf Date: Sun, 1 Oct 2017 23:34:19 +0200 Subject: implemented new experimental scriptable import mechanism --- compiler/importer.nim | 50 ++++++++++++++++++++++++++++++++++++++++---------- 1 file changed, 40 insertions(+), 10 deletions(-) (limited to 'compiler/importer.nim') diff --git a/compiler/importer.nim b/compiler/importer.nim index dfc9e84ba..07f42a147 100644 --- a/compiler/importer.nim +++ b/compiler/importer.nim @@ -11,11 +11,22 @@ import intsets, strutils, os, ast, astalgo, msgs, options, idents, rodread, lookups, - semdata, passes, renderer + semdata, passes, renderer, gorgeimpl proc evalImport*(c: PContext, n: PNode): PNode proc evalFrom*(c: PContext, n: PNode): PNode +proc lookupPackage(pkg, subdir: PNode): string = + let sub = if subdir != nil: renderTree(subdir, {renderNoComments}).replace(" ") else: "" + case pkg.kind + of nkStrLit, nkRStrLit, nkTripleStrLit: + result = scriptableImport(pkg.strVal, sub, pkg.info) + of nkIdent: + result = scriptableImport(pkg.ident.s, sub, pkg.info) + else: + localError(pkg.info, "package name must be an identifier or string literal") + result = "" + proc getModuleName*(n: PNode): string = # This returns a short relative module name without the nim extension # e.g. like "system", "importer" or "somepath/module" @@ -31,16 +42,33 @@ proc getModuleName*(n: PNode): string = result = n.ident.s of nkSym: result = n.sym.name.s - of nkInfix, nkPrefix: - if n.sons[0].kind == nkIdent and n.sons[0].ident.id == getIdent("as").id: + of nkInfix: + let n0 = n[0] + let n1 = n[1] + if n0.kind == nkIdent and n0.ident.id == getIdent("as").id: # XXX hack ahead: n.kind = nkImportAs n.sons[0] = n.sons[1] n.sons[1] = n.sons[2] n.sons.setLen(2) return getModuleName(n.sons[0]) - # hacky way to implement 'x / y /../ z': - result = renderTree(n, {renderNoComments}).replace(" ") + if n1.kind == nkPrefix and n1[0].kind == nkIdent and n1[0].ident.s == "$": + if n0.kind == nkIdent and n0.ident.s == "/": + result = lookupPackage(n1[1], n[2]) + else: + localError(n.info, "only '/' supported with $package notation") + result = "" + else: + # hacky way to implement 'x / y /../ z': + result = getModuleName(n1) + result.add renderTree(n0, {renderNoComments}) + result.add getModuleName(n[2]) + of nkPrefix: + if n.sons[0].kind == nkIdent and n.sons[0].ident.s == "$": + result = lookupPackage(n[1], nil) + else: + # hacky way to implement 'x / y /../ z': + result = renderTree(n, {renderNoComments}).replace(" ") of nkDotExpr: result = renderTree(n, {renderNoComments}).replace(".", "/") of nkImportAs: @@ -209,12 +237,14 @@ proc evalImport(c: PContext, n: PNode): PNode = for i in countup(0, sonsLen(n) - 1): let it = n.sons[i] if it.kind == nkInfix and it.len == 3 and it[2].kind == nkBracket: - let sep = renderTree(it.sons[0], {renderNoComments}) - let dir = renderTree(it.sons[1], {renderNoComments}) + let sep = it[0] + let dir = it[1] + let a = newNodeI(nkInfix, it.info) + a.add sep + a.add dir + a.add sep # dummy entry, replaced in the loop for x in it[2]: - let f = renderTree(x, {renderNoComments}) - let a = newStrNode(nkStrLit, (dir & sep & f).replace(" ")) - a.info = it.info + a.sons[2] = x impMod(c, a) else: impMod(c, it) -- cgit 1.4.1-2-gfad0