implemented the using statement

This commit is contained in:
Zahary Karadjov 2013-08-31 19:40:36 +03:00
commit b5d833b329
9 changed files with 53 additions and 11 deletions

View file

@ -178,6 +178,7 @@ type
nkIncludeStmt, # an include statement nkIncludeStmt, # an include statement
nkBindStmt, # a bind statement nkBindStmt, # a bind statement
nkMixinStmt, # a mixin statement nkMixinStmt, # a mixin statement
nkUsingStmt, # an using statement
nkCommentStmt, # a comment statement nkCommentStmt, # a comment statement
nkStmtListExpr, # a statement list followed by an expr; this is used nkStmtListExpr, # a statement list followed by an expr; this is used
# to allow powerful multi-line templates # to allow powerful multi-line templates
@ -619,6 +620,7 @@ type
TScope* = object TScope* = object
depthLevel*: int depthLevel*: int
symbols*: TStrTable symbols*: TStrTable
usingSyms*: seq[PNode]
parent*: PScope parent*: PScope
PScope* = ref TScope PScope* = ref TScope

View file

@ -41,7 +41,7 @@ type
tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface, tkGeneric, tkIf, tkImport, tkIn, tkInclude, tkInterface,
tkIs, tkIsnot, tkIterator, tkIs, tkIsnot, tkIterator,
tkLambda, tkLet, tkLambda, tkLet,
tkMacro, tkMethod, tkMixin, tkMod, tkNil, tkNot, tkNotin, tkMacro, tkMethod, tkMixin, tkUsing, tkMod, tkNil, tkNot, tkNotin,
tkObject, tkOf, tkOr, tkOut, tkObject, tkOf, tkOr, tkOut,
tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShared, tkShl, tkShr, tkStatic, tkProc, tkPtr, tkRaise, tkRef, tkReturn, tkShared, tkShl, tkShr, tkStatic,
tkTemplate, tkTemplate,
@ -75,7 +75,7 @@ const
"finally", "for", "from", "generic", "if", "finally", "for", "from", "generic", "if",
"import", "in", "include", "interface", "is", "isnot", "iterator", "import", "in", "include", "interface", "is", "isnot", "iterator",
"lambda", "let", "lambda", "let",
"macro", "method", "mixin", "mod", "macro", "method", "mixin", "using", "mod",
"nil", "not", "notin", "object", "of", "or", "nil", "not", "notin", "object", "of", "or",
"out", "proc", "ptr", "raise", "ref", "return", "out", "proc", "ptr", "raise", "ref", "return",
"shared", "shl", "shr", "static", "shared", "shl", "shr", "static",

View file

@ -89,7 +89,7 @@ type
errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError, errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError,
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile, errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely, errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely,
errOnlyACallOpCanBeDelegator, errOnlyACallOpCanBeDelegator, errUsingNoSymbol,
errXExpectsTwoArguments, errXExpectsTwoArguments,
errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations, errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations,
@ -318,6 +318,7 @@ const
errVarVarTypeNotAllowed: "type \'var var\' is not allowed", errVarVarTypeNotAllowed: "type \'var var\' is not allowed",
errInstantiateXExplicitely: "instantiate '$1' explicitely", errInstantiateXExplicitely: "instantiate '$1' explicitely",
errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator", errOnlyACallOpCanBeDelegator: "only a call operator can be a delegator",
errUsingNoSymbol: "'$1' is not a variable, constant or a proc name",
errXExpectsTwoArguments: "\'$1\' expects two arguments", errXExpectsTwoArguments: "\'$1\' expects two arguments",
errXExpectsObjectTypes: "\'$1\' expects object types", errXExpectsObjectTypes: "\'$1\' expects object types",
errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype", errXcanNeverBeOfThisSubtype: "\'$1\' can never be of this subtype",

View file

@ -1775,6 +1775,7 @@ proc complexOrSimpleStmt(p: var TParser): PNode =
of tkVar: result = parseSection(p, nkVarSection, parseVariable) of tkVar: result = parseSection(p, nkVarSection, parseVariable)
of tkBind: result = parseBind(p, nkBindStmt) of tkBind: result = parseBind(p, nkBindStmt)
of tkMixin: result = parseBind(p, nkMixinStmt) of tkMixin: result = parseBind(p, nkMixinStmt)
of tkUsing: result = parseBind(p, nkUsingStmt)
else: result = simpleStmt(p) else: result = simpleStmt(p)
proc parseStmt(p: var TParser): PNode = proc parseStmt(p: var TParser): PNode =

View file

@ -96,6 +96,11 @@ proc NotFoundError*(c: PContext, n: PNode, errors: seq[string]) =
LocalError(n.Info, errGenerated, result) LocalError(n.Info, errGenerated, result)
proc gatherUsedSyms(c: PContext, usedSyms: var seq[PNode]) =
for scope in walkScopes(c.currentScope):
if scope.usingSyms != nil:
for s in scope.usingSyms: usedSyms.safeAdd(s)
proc resolveOverloads(c: PContext, n, orig: PNode, proc resolveOverloads(c: PContext, n, orig: PNode,
filter: TSymKinds): TCandidate = filter: TSymKinds): TCandidate =
var initialBinding: PNode var initialBinding: PNode
@ -109,11 +114,27 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
initialBinding = nil initialBinding = nil
var errors: seq[string] var errors: seq[string]
var usedSyms: seq[PNode]
template pickBest(headSymbol: expr) = template pickBest(headSymbol: expr) =
pickBestCandidate(c, headSymbol, n, orig, initialBinding, pickBestCandidate(c, headSymbol, n, orig, initialBinding,
filter, result, alt, errors) filter, result, alt, errors)
gatherUsedSyms(c, usedSyms)
if usedSyms != nil:
var hiddenArg = if usedSyms.len > 1: newNode(nkClosedSymChoice, n.info, usedSyms)
else: usedSyms[0]
n.sons.insert(hiddenArg, 1)
orig.sons.insert(hiddenArg, 1)
pickBest(f)
if result.state != csMatch:
n.sons.delete(1)
orig.sons.delete(1)
else: return
pickBest(f) pickBest(f)
let overloadsState = result.state let overloadsState = result.state

View file

@ -1329,6 +1329,22 @@ proc newAnonSym(kind: TSymKind, info: TLineInfo,
result = newSym(kind, idAnon, owner, info) result = newSym(kind, idAnon, owner, info)
result.flags = {sfGenSym} result.flags = {sfGenSym}
proc semUsing(c: PContext, n: PNode): PNode =
result = newNodeI(nkEmpty, n.info)
for e in n.sons:
let usedSym = semExpr(c, e)
if usedSym.kind == nkSym:
case usedSym.sym.kind
of skLocalVars + {skConst}:
c.currentScope.usingSyms.safeAdd(usedSym)
continue
of skProcKinds:
addDeclAt(c.currentScope, usedSym.sym)
continue
else: nil
LocalError(e.info, errUsingNoSymbol, e.renderTree)
proc semExpandToAst(c: PContext, n: PNode): PNode = proc semExpandToAst(c: PContext, n: PNode): PNode =
var macroCall = n[1] var macroCall = n[1]
var expandedSym = expectMacroOrTemplateCall(c, macroCall) var expandedSym = expectMacroOrTemplateCall(c, macroCall)
@ -1967,6 +1983,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode =
of nkForStmt, nkParForStmt: result = semFor(c, n) of nkForStmt, nkParForStmt: result = semFor(c, n)
of nkCaseStmt: result = semCase(c, n) of nkCaseStmt: result = semCase(c, n)
of nkReturnStmt: result = semReturn(c, n) of nkReturnStmt: result = semReturn(c, n)
of nkUsingStmt: result = semUsing(c, n)
of nkAsmStmt: result = semAsm(c, n) of nkAsmStmt: result = semAsm(c, n)
of nkYieldStmt: result = semYield(c, n) of nkYieldStmt: result = semYield(c, n)
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas) of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)

View file

@ -28,7 +28,7 @@ type
wElif, wElse, wEnd, wEnum, wExcept, wExport, wElif, wElse, wEnd, wEnum, wExcept, wExport,
wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn, wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
wInclude, wInterface, wIs, wIsnot, wIterator, wLambda, wLet, wInclude, wInterface, wIs, wIsnot, wIterator, wLambda, wLet,
wMacro, wMethod, wMixin, wMod, wNil, wMacro, wMethod, wMixin, wUsing, wMod, wNil,
wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn, wNot, wNotin, wObject, wOf, wOr, wOut, wProc, wPtr, wRaise, wRef, wReturn,
wShared, wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wVar, wShared, wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wVar,
wWhen, wWhile, wWith, wWithout, wXor, wYield, wWhen, wWhile, wWith, wWithout, wXor, wYield,
@ -72,7 +72,7 @@ type
wPrivate, wProtected, wPublic, wRegister, wReinterpret_cast, wPrivate, wProtected, wPublic, wRegister, wReinterpret_cast,
wShort, wSigned, wSizeof, wStatic_cast, wStruct, wSwitch, wShort, wSigned, wSizeof, wStatic_cast, wStruct, wSwitch,
wThis, wThrow, wTrue, wTypedef, wTypeid, wTypename, wThis, wThrow, wTrue, wTypedef, wTypeid, wTypename,
wUnion, wUnsigned, wUsing, wVirtual, wVoid, wVolatile, wWchar_t, wUnion, wUnsigned, wVirtual, wVoid, wVolatile, wWchar_t,
wAlignas, wAlignof, wConstexpr, wDecltype, wNullptr, wNoexcept, wAlignas, wAlignof, wConstexpr, wDecltype, wNullptr, wNoexcept,
wThread_local, wStatic_assert, wChar16_t, wChar32_t, wThread_local, wStatic_assert, wChar16_t, wChar32_t,
@ -95,7 +95,7 @@ const
cppNimSharedKeywords* = { cppNimSharedKeywords* = {
wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport, wAsm, wBreak, wCase, wConst, wContinue, wDo, wElse, wEnum, wExport,
wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile} wFor, wIf, wReturn, wStatic, wTemplate, wTry, wWhile, wUsing }
specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["", specialWords*: array[low(TSpecialWord)..high(TSpecialWord), string] = ["",
@ -107,7 +107,7 @@ const
"finally", "for", "from", "generic", "if", "finally", "for", "from", "generic", "if",
"import", "in", "include", "interface", "is", "isnot", "iterator", "import", "in", "include", "interface", "is", "isnot", "iterator",
"lambda", "let", "lambda", "let",
"macro", "method", "mixin", "mod", "nil", "not", "notin", "macro", "method", "mixin", "using", "mod", "nil", "not", "notin",
"object", "of", "or", "object", "of", "or",
"out", "proc", "ptr", "raise", "ref", "return", "out", "proc", "ptr", "raise", "ref", "return",
"shared", "shl", "shr", "static", "shared", "shl", "shr", "static",
@ -154,7 +154,7 @@ const
"private", "protected", "public", "register", "reinterpret_cast", "private", "protected", "public", "register", "reinterpret_cast",
"short", "signed", "sizeof", "static_cast", "struct", "switch", "short", "signed", "sizeof", "static_cast", "struct", "switch",
"this", "throw", "true", "typedef", "typeid", "this", "throw", "true", "typedef", "typeid",
"typename", "union", "unsigned", "using", "virtual", "void", "volatile", "typename", "union", "unsigned", "virtual", "void", "volatile",
"wchar_t", "wchar_t",
"alignas", "alignof", "constexpr", "decltype", "nullptr", "noexcept", "alignas", "alignof", "constexpr", "decltype", "nullptr", "noexcept",

View file

@ -7,7 +7,7 @@ finally for from
generic generic
if import in include interface is isnot iterator if import in include interface is isnot iterator
lambda let lambda let
macro method mixin mod macro method mixin using mod
nil not notin nil not notin
object of or out object of or out
proc ptr proc ptr

View file

@ -56,7 +56,7 @@ type
nnkFromStmt, nnkFromStmt,
nnkIncludeStmt, nnkIncludeStmt,
nnkBindStmt, nnkMixinStmt, nnkBindStmt, nnkMixinStmt, nnkUsingStmt,
nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr,
nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy,
nnkTupleTy, nnkTypeClassTy, nnkRecList, nnkRecCase, nnkRecWhen, nnkTupleTy, nnkTypeClassTy, nnkRecList, nnkRecCase, nnkRecWhen,