implemented 'import a as b'
This commit is contained in:
parent
367abca382
commit
83584bf889
4 changed files with 84 additions and 25 deletions
|
|
@ -131,7 +131,7 @@ type
|
||||||
nkFormalParams, # formal parameters
|
nkFormalParams, # formal parameters
|
||||||
nkOfInherit, # inherited from symbol
|
nkOfInherit, # inherited from symbol
|
||||||
|
|
||||||
nkModule, # the syntax tree of a module
|
nkImportAs, # a 'as' b in an import statement
|
||||||
nkProcDef, # a proc
|
nkProcDef, # a proc
|
||||||
nkMethodDef, # a method
|
nkMethodDef, # a method
|
||||||
nkConverterDef, # a converter
|
nkConverterDef, # a converter
|
||||||
|
|
@ -641,6 +641,11 @@ type
|
||||||
# this is because in incremental compilation, when a module is about to
|
# this is because in incremental compilation, when a module is about to
|
||||||
# be replaced with a newer version, we must decrement the usage count
|
# be replaced with a newer version, we must decrement the usage count
|
||||||
# of all previously used generics.
|
# of all previously used generics.
|
||||||
|
# For 'import as' we copy the module symbol but shallowCopy the 'tab'
|
||||||
|
# and set the 'usedGenerics' to ... XXX gah! Better set module.name
|
||||||
|
# instead? But this doesn't work either. --> We need an skModuleAlias?
|
||||||
|
# No need, just leave it as skModule but set the owner accordingly and
|
||||||
|
# check for the owner when touching 'usedGenerics'.
|
||||||
usedGenerics*: seq[PInstantiation]
|
usedGenerics*: seq[PInstantiation]
|
||||||
tab*: TStrTable # interface table for modules
|
tab*: TStrTable # interface table for modules
|
||||||
else: nil
|
else: nil
|
||||||
|
|
@ -1106,7 +1111,7 @@ proc copyType(t: PType, owner: PSym, keepId: bool): PType =
|
||||||
|
|
||||||
proc copySym(s: PSym, keepId: bool = false): PSym =
|
proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||||
result = newSym(s.kind, s.name, s.owner, s.info)
|
result = newSym(s.kind, s.name, s.owner, s.info)
|
||||||
result.ast = nil # BUGFIX; was: s.ast which made problems
|
#result.ast = nil # BUGFIX; was: s.ast which made problems
|
||||||
result.typ = s.typ
|
result.typ = s.typ
|
||||||
if keepId:
|
if keepId:
|
||||||
result.id = s.id
|
result.id = s.id
|
||||||
|
|
@ -1121,6 +1126,20 @@ proc copySym(s: PSym, keepId: bool = false): PSym =
|
||||||
result.position = s.position
|
result.position = s.position
|
||||||
result.loc = s.loc
|
result.loc = s.loc
|
||||||
result.annex = s.annex # BUGFIX
|
result.annex = s.annex # BUGFIX
|
||||||
|
|
||||||
|
proc createModuleAlias*(s: PSym, newIdent: PIdent, info: TLineInfo): PSym =
|
||||||
|
result = newSym(s.kind, newIdent, s.owner, info)
|
||||||
|
# keep ID!
|
||||||
|
result.ast = s.ast
|
||||||
|
result.id = s.id
|
||||||
|
result.flags = s.flags
|
||||||
|
system.shallowCopy(result.tab, s.tab)
|
||||||
|
result.options = s.options
|
||||||
|
result.position = s.position
|
||||||
|
result.loc = s.loc
|
||||||
|
result.annex = s.annex
|
||||||
|
# XXX once usedGenerics is used, ensure module aliases keep working!
|
||||||
|
assert s.usedGenerics == nil
|
||||||
|
|
||||||
proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym,
|
proc newSym(symKind: TSymKind, Name: PIdent, owner: PSym,
|
||||||
info: TLineInfo): PSym =
|
info: TLineInfo): PSym =
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,7 @@
|
||||||
#
|
#
|
||||||
#
|
#
|
||||||
# The Nimrod Compiler
|
# The Nimrod Compiler
|
||||||
# (c) Copyright 2012 Andreas Rumpf
|
# (c) Copyright 2013 Andreas Rumpf
|
||||||
#
|
#
|
||||||
# See the file "copying.txt", included in this
|
# See the file "copying.txt", included in this
|
||||||
# distribution, for details about the copyright.
|
# distribution, for details about the copyright.
|
||||||
|
|
@ -27,12 +27,24 @@ proc getModuleName*(n: PNode): string =
|
||||||
result = n.ident.s
|
result = n.ident.s
|
||||||
of nkSym:
|
of nkSym:
|
||||||
result = n.sym.name.s
|
result = n.sym.name.s
|
||||||
else:
|
of nkInfix:
|
||||||
|
if n.sons[0].kind == nkIdent and n.sons[0].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':
|
# hacky way to implement 'x / y /../ z':
|
||||||
result = renderTree(n, {renderNoComments}).replace(" ")
|
result = renderTree(n, {renderNoComments}).replace(" ")
|
||||||
#localError(n.info, errGenerated,
|
of nkDotExpr:
|
||||||
# "invalide module name: '$1'" % renderTree(n))
|
result = renderTree(n, {renderNoComments}).replace(".")
|
||||||
#result = ""
|
of nkImportAs:
|
||||||
|
result = getModuleName(n.sons[0])
|
||||||
|
else:
|
||||||
|
localError(n.info, errGenerated,
|
||||||
|
"invalid module name: '$1'" % renderTree(n))
|
||||||
|
result = ""
|
||||||
|
|
||||||
proc checkModuleName*(n: PNode): int32 =
|
proc checkModuleName*(n: PNode): int32 =
|
||||||
# This returns the full canonical path for a given module import
|
# This returns the full canonical path for a given module import
|
||||||
|
|
@ -135,15 +147,28 @@ proc importForwarded(c: PContext, n: PNode, exceptSet: TIntSet) =
|
||||||
for i in 0 ..safeLen(n)-1:
|
for i in 0 ..safeLen(n)-1:
|
||||||
importForwarded(c, n.sons[i], exceptSet)
|
importForwarded(c, n.sons[i], exceptSet)
|
||||||
|
|
||||||
|
proc importModuleAs(n: PNode, realModule: PSym): PSym =
|
||||||
|
result = realModule
|
||||||
|
if n.kind != nkImportAs: discard
|
||||||
|
elif n.len != 2 or n.sons[1].kind != nkIdent:
|
||||||
|
localError(n.info, errGenerated, "module alias must be an identifier")
|
||||||
|
elif n.sons[1].ident.id != realModule.name.id:
|
||||||
|
# some misguided guy will write 'import abc.foo as foo' ...
|
||||||
|
result = createModuleAlias(realModule, n.sons[1].ident, n.sons[1].info)
|
||||||
|
|
||||||
|
proc myImportModule(c: PContext, n: PNode): PSym =
|
||||||
|
var f = checkModuleName(n)
|
||||||
|
if f != InvalidFileIDX:
|
||||||
|
result = importModuleAs(n, gImportModule(c.module, f))
|
||||||
|
if sfDeprecated in result.flags:
|
||||||
|
Message(n.info, warnDeprecated, result.name.s)
|
||||||
|
|
||||||
proc evalImport(c: PContext, n: PNode): PNode =
|
proc evalImport(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
var emptySet: TIntSet
|
var emptySet: TIntSet
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
var f = checkModuleName(n.sons[i])
|
var m = myImportModule(c, n.sons[i])
|
||||||
if f != InvalidFileIDX:
|
if m != nil:
|
||||||
var m = gImportModule(c.module, f)
|
|
||||||
if sfDeprecated in m.flags:
|
|
||||||
Message(n.sons[i].info, warnDeprecated, m.name.s)
|
|
||||||
# ``addDecl`` needs to be done before ``importAllSymbols``!
|
# ``addDecl`` needs to be done before ``importAllSymbols``!
|
||||||
addDecl(c, m) # add symbol to symbol table of module
|
addDecl(c, m) # add symbol to symbol table of module
|
||||||
importAllSymbolsExcept(c, m, emptySet)
|
importAllSymbolsExcept(c, m, emptySet)
|
||||||
|
|
@ -152,21 +177,19 @@ proc evalImport(c: PContext, n: PNode): PNode =
|
||||||
proc evalFrom(c: PContext, n: PNode): PNode =
|
proc evalFrom(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
var f = checkModuleName(n.sons[0])
|
var m = myImportModule(c, n.sons[0])
|
||||||
if f != InvalidFileIDX:
|
if m != nil:
|
||||||
var m = gImportModule(c.module, f)
|
|
||||||
n.sons[0] = newSymNode(m)
|
n.sons[0] = newSymNode(m)
|
||||||
addDecl(c, m) # add symbol to symbol table of module
|
addDecl(c, m) # add symbol to symbol table of module
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
if n.sons[i].kind != nkNilLit:
|
if n.sons[i].kind != nkNilLit:
|
||||||
importSymbol(c, n.sons[i], m)
|
importSymbol(c, n.sons[i], m)
|
||||||
|
|
||||||
proc evalImportExcept*(c: PContext, n: PNode): PNode =
|
proc evalImportExcept*(c: PContext, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
checkMinSonsLen(n, 2)
|
checkMinSonsLen(n, 2)
|
||||||
var f = checkModuleName(n.sons[0])
|
var m = myImportModule(c, n.sons[0])
|
||||||
if f != InvalidFileIDX:
|
if m != nil:
|
||||||
var m = gImportModule(c.module, f)
|
|
||||||
n.sons[0] = newSymNode(m)
|
n.sons[0] = newSymNode(m)
|
||||||
addDecl(c, m) # add symbol to symbol table of module
|
addDecl(c, m) # add symbol to symbol table of module
|
||||||
var exceptSet = initIntSet()
|
var exceptSet = initIntSet()
|
||||||
|
|
|
||||||
|
|
@ -1088,6 +1088,17 @@ proc parseExprStmt(p: var TParser): PNode =
|
||||||
addSon(result, b)
|
addSon(result, b)
|
||||||
if b.kind == nkElse: break
|
if b.kind == nkElse: break
|
||||||
|
|
||||||
|
proc parseModuleName(p: var TParser, kind: TNodeKind): PNode =
|
||||||
|
result = parseExpr(p)
|
||||||
|
when false:
|
||||||
|
# parseExpr already handles 'as' syntax ...
|
||||||
|
if p.tok.tokType == tkAs and kind == nkImportStmt:
|
||||||
|
let a = result
|
||||||
|
result = newNodeP(nkImportAs, p)
|
||||||
|
getTok(p)
|
||||||
|
result.add(a)
|
||||||
|
result.add(parseExpr(p))
|
||||||
|
|
||||||
proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||||
#| importStmt = 'import' optInd expr
|
#| importStmt = 'import' optInd expr
|
||||||
#| ((comma expr)*
|
#| ((comma expr)*
|
||||||
|
|
@ -1095,7 +1106,7 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||||
result = newNodeP(kind, p)
|
result = newNodeP(kind, p)
|
||||||
getTok(p) # skip `import` or `export`
|
getTok(p) # skip `import` or `export`
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
var a = parseExpr(p)
|
var a = parseModuleName(p, kind)
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
if p.tok.tokType in {tkComma, tkExcept}:
|
if p.tok.tokType in {tkComma, tkExcept}:
|
||||||
if p.tok.tokType == tkExcept:
|
if p.tok.tokType == tkExcept:
|
||||||
|
|
@ -1104,10 +1115,10 @@ proc parseImport(p: var TParser, kind: TNodeKind): PNode =
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
while true:
|
while true:
|
||||||
# was: while p.tok.tokType notin {tkEof, tkSad, tkDed}:
|
# was: while p.tok.tokType notin {tkEof, tkSad, tkDed}:
|
||||||
a = parseExpr(p)
|
a = parseModuleName(p, kind)
|
||||||
if a.kind == nkEmpty: break
|
if a.kind == nkEmpty: break
|
||||||
addSon(result, a)
|
addSon(result, a)
|
||||||
if p.tok.tokType != tkComma: break
|
if p.tok.tokType != tkComma: break
|
||||||
getTok(p)
|
getTok(p)
|
||||||
optInd(p, a)
|
optInd(p, a)
|
||||||
#expectNl(p)
|
#expectNl(p)
|
||||||
|
|
@ -1128,11 +1139,11 @@ proc parseIncludeStmt(p: var TParser): PNode =
|
||||||
#expectNl(p)
|
#expectNl(p)
|
||||||
|
|
||||||
proc parseFromStmt(p: var TParser): PNode =
|
proc parseFromStmt(p: var TParser): PNode =
|
||||||
#| fromStmt = 'from' expr 'import' optInd expr (comma expr)*
|
#| fromStmt = 'from' moduleName 'import' optInd expr (comma expr)*
|
||||||
result = newNodeP(nkFromStmt, p)
|
result = newNodeP(nkFromStmt, p)
|
||||||
getTok(p) # skip `from`
|
getTok(p) # skip `from`
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
var a = parseExpr(p)
|
var a = parseModuleName(p, nkImportStmt)
|
||||||
addSon(result, a) #optInd(p, a);
|
addSon(result, a) #optInd(p, a);
|
||||||
eat(p, tkImport)
|
eat(p, tkImport)
|
||||||
optInd(p, result)
|
optInd(p, result)
|
||||||
|
|
|
||||||
|
|
@ -448,6 +448,7 @@ proc lsub(n: PNode): int =
|
||||||
of nkPragma: result = lcomma(n) + 4
|
of nkPragma: result = lcomma(n) + 4
|
||||||
of nkCommentStmt: result = len(n.comment)
|
of nkCommentStmt: result = len(n.comment)
|
||||||
of nkOfBranch: result = lcomma(n, 0, - 2) + lsub(lastSon(n)) + len("of_:_")
|
of nkOfBranch: result = lcomma(n, 0, - 2) + lsub(lastSon(n)) + len("of_:_")
|
||||||
|
of nkImportAs: result = lsub(n.sons[0]) + len("_as_") + lsub(n.sons[1])
|
||||||
of nkElifBranch: result = lsons(n) + len("elif_:_")
|
of nkElifBranch: result = lsons(n) + len("elif_:_")
|
||||||
of nkElse: result = lsub(n.sons[0]) + len("else:_")
|
of nkElse: result = lsub(n.sons[0]) + len("else:_")
|
||||||
of nkFinally: result = lsub(n.sons[0]) + len("finally:_")
|
of nkFinally: result = lsub(n.sons[0]) + len("finally:_")
|
||||||
|
|
@ -1191,6 +1192,11 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
|
||||||
putWithSpace(g, tkColon, ":")
|
putWithSpace(g, tkColon, ":")
|
||||||
gcoms(g)
|
gcoms(g)
|
||||||
gstmts(g, lastSon(n), c)
|
gstmts(g, lastSon(n), c)
|
||||||
|
of nkImportAs:
|
||||||
|
gsub(g, n.sons[0])
|
||||||
|
put(g, tkSpaces, Space)
|
||||||
|
putWithSpace(g, tkAs, "as")
|
||||||
|
gsub(g, n.sons[1])
|
||||||
of nkBindStmt:
|
of nkBindStmt:
|
||||||
putWithSpace(g, tkBind, "bind")
|
putWithSpace(g, tkBind, "bind")
|
||||||
gcomma(g, n, c)
|
gcomma(g, n, c)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue