implemented the using statement

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

View File

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

View File

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

View File

@@ -89,7 +89,7 @@ type
errInvalidSectionStart, errGridTableNotImplemented, errGeneralParseError,
errNewSectionExpected, errWhitespaceExpected, errXisNoValidIndexFile,
errCannotRenderX, errVarVarTypeNotAllowed, errInstantiateXExplicitely,
errOnlyACallOpCanBeDelegator,
errOnlyACallOpCanBeDelegator, errUsingNoSymbol,
errXExpectsTwoArguments,
errXExpectsObjectTypes, errXcanNeverBeOfThisSubtype, errTooManyIterations,
@@ -318,6 +318,7 @@ const
errVarVarTypeNotAllowed: "type \'var var\' is not allowed",
errInstantiateXExplicitely: "instantiate '$1' explicitely",
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",
errXExpectsObjectTypes: "\'$1\' expects object types",
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 tkBind: result = parseBind(p, nkBindStmt)
of tkMixin: result = parseBind(p, nkMixinStmt)
of tkUsing: result = parseBind(p, nkUsingStmt)
else: result = simpleStmt(p)
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)
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,
filter: TSymKinds): TCandidate =
var initialBinding: PNode
@@ -109,11 +114,27 @@ proc resolveOverloads(c: PContext, n, orig: PNode,
initialBinding = nil
var errors: seq[string]
var usedSyms: seq[PNode]
template pickBest(headSymbol: expr) =
pickBestCandidate(c, headSymbol, n, orig, initialBinding,
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)
let overloadsState = result.state

View File

@@ -1329,6 +1329,22 @@ proc newAnonSym(kind: TSymKind, info: TLineInfo,
result = newSym(kind, idAnon, owner, info)
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 =
var macroCall = n[1]
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 nkCaseStmt: result = semCase(c, n)
of nkReturnStmt: result = semReturn(c, n)
of nkUsingStmt: result = semUsing(c, n)
of nkAsmStmt: result = semAsm(c, n)
of nkYieldStmt: result = semYield(c, n)
of nkPragma: pragma(c, c.p.owner, n, stmtPragmas)

View File

@@ -28,7 +28,7 @@ type
wElif, wElse, wEnd, wEnum, wExcept, wExport,
wFinally, wFor, wFrom, wGeneric, wIf, wImport, wIn,
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,
wShared, wShl, wShr, wStatic, wTemplate, wTry, wTuple, wType, wVar,
wWhen, wWhile, wWith, wWithout, wXor, wYield,
@@ -72,7 +72,7 @@ type
wPrivate, wProtected, wPublic, wRegister, wReinterpret_cast,
wShort, wSigned, wSizeof, wStatic_cast, wStruct, wSwitch,
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,
wThread_local, wStatic_assert, wChar16_t, wChar32_t,
@@ -95,7 +95,7 @@ const
cppNimSharedKeywords* = {
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] = ["",
@@ -107,7 +107,7 @@ const
"finally", "for", "from", "generic", "if",
"import", "in", "include", "interface", "is", "isnot", "iterator",
"lambda", "let",
"macro", "method", "mixin", "mod", "nil", "not", "notin",
"macro", "method", "mixin", "using", "mod", "nil", "not", "notin",
"object", "of", "or",
"out", "proc", "ptr", "raise", "ref", "return",
"shared", "shl", "shr", "static",
@@ -154,7 +154,7 @@ const
"private", "protected", "public", "register", "reinterpret_cast",
"short", "signed", "sizeof", "static_cast", "struct", "switch",
"this", "throw", "true", "typedef", "typeid",
"typename", "union", "unsigned", "using", "virtual", "void", "volatile",
"typename", "union", "unsigned", "virtual", "void", "volatile",
"wchar_t",
"alignas", "alignof", "constexpr", "decltype", "nullptr", "noexcept",

View File

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

View File

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