diff options
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/lexer.nim | 4 | ||||
-rw-r--r-- | compiler/msgs.nim | 3 | ||||
-rw-r--r-- | compiler/parser.nim | 1 | ||||
-rw-r--r-- | compiler/semcall.nim | 23 | ||||
-rw-r--r-- | compiler/semexprs.nim | 17 | ||||
-rw-r--r-- | compiler/wordrecg.nim | 10 | ||||
-rw-r--r-- | doc/keywords.txt | 2 | ||||
-rw-r--r-- | lib/core/macros.nim | 2 |
9 files changed, 53 insertions, 11 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 4ed44a8fe..6e0cafd74 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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 diff --git a/compiler/lexer.nim b/compiler/lexer.nim index 9e5f4e9d7..1d34c59ab 100644 --- a/compiler/lexer.nim +++ b/compiler/lexer.nim @@ -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", diff --git a/compiler/msgs.nim b/compiler/msgs.nim index 47a4d284b..c0b1221ef 100644 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -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", diff --git a/compiler/parser.nim b/compiler/parser.nim index ae9ec6105..d19149073 100644 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -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 = diff --git a/compiler/semcall.nim b/compiler/semcall.nim index 8c20d0faa..b2f41d509 100644 --- a/compiler/semcall.nim +++ b/compiler/semcall.nim @@ -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 diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index b9df29d39..30b28a35d 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -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) diff --git a/compiler/wordrecg.nim b/compiler/wordrecg.nim index f8a19ae19..b37a7bb4f 100644 --- a/compiler/wordrecg.nim +++ b/compiler/wordrecg.nim @@ -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", diff --git a/doc/keywords.txt b/doc/keywords.txt index 2a775cd94..fa3ce4786 100644 --- a/doc/keywords.txt +++ b/doc/keywords.txt @@ -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 diff --git a/lib/core/macros.nim b/lib/core/macros.nim index 362e670e6..9ac6b0082 100644 --- a/lib/core/macros.nim +++ b/lib/core/macros.nim @@ -56,7 +56,7 @@ type nnkFromStmt, nnkIncludeStmt, - nnkBindStmt, nnkMixinStmt, + nnkBindStmt, nnkMixinStmt, nnkUsingStmt, nnkCommentStmt, nnkStmtListExpr, nnkBlockExpr, nnkStmtListType, nnkBlockType, nnkTypeOfExpr, nnkObjectTy, nnkTupleTy, nnkTypeClassTy, nnkRecList, nnkRecCase, nnkRecWhen, |