diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-10-03 21:11:41 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-10-04 15:37:26 +0300 |
commit | d9d82fb0af8688e7c847bb7b0c3b2e38f7c8a735 (patch) | |
tree | 2e547df69eead6665ca4127f63872f0bbd67f275 /compiler | |
parent | a6d5707faff21722f22f91c56704c44fc03d47f6 (diff) | |
download | Nim-d9d82fb0af8688e7c847bb7b0c3b2e38f7c8a735.tar.gz |
syntax compatibility between do blocks and stmt blocks
See the section `do notation` in the manual for more info. * nkMacroStmt has been removed Macro statements are now mapped to regular nkCall nodes. The support for additional clauses (such as else, except, of, etc) have been restored - they will now appear as additional arguments for the nkCall node (as nkElse, nkExcept, etc nodes) * fixed some regressions in the `is` operator and semCompiles
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 13 | ||||
-rwxr-xr-x | compiler/c2nim/cparse.nim | 2 | ||||
-rwxr-xr-x | compiler/evals.nim | 2 | ||||
-rwxr-xr-x | compiler/idents.nim | 4 | ||||
-rwxr-xr-x | compiler/msgs.nim | 19 | ||||
-rwxr-xr-x | compiler/options.nim | 6 | ||||
-rwxr-xr-x | compiler/parser.nim | 59 | ||||
-rwxr-xr-x | compiler/renderer.nim | 1 | ||||
-rwxr-xr-x | compiler/sem.nim | 9 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 85 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 13 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 44 | ||||
-rwxr-xr-x | compiler/semtypinst.nim | 3 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 8 | ||||
-rwxr-xr-x | compiler/suggest.nim | 3 |
15 files changed, 124 insertions, 147 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index aa94644aa..340a14888 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -145,7 +145,6 @@ type nkElifBranch, # used in if statements nkExceptBranch, # an except section nkElse, # an else part - nkMacroStmt, # a macro statement nkAsmStmt, # an assembler block nkPragma, # a pragma statement nkPragmaBlock, # a pragma with a block @@ -911,6 +910,18 @@ proc newMetaNodeIT*(tree: PNode, info: TLineInfo, typ: PType): PNode = result = newNodeIT(nkMetaNode, info, typ) result.add(tree) +var emptyParams = newNode(nkFormalParams) +emptyParams.addSon(emptyNode) + +proc newProcNode*(kind: TNodeKind, info: TLineInfo, body: PNode, + params = emptyParams, + name, pattern, genericParams, + pragmas, exceptions = ast.emptyNode): PNode = + result = newNodeI(kind, info) + result.sons = @[name, pattern, genericParams, params, + pragmas, exceptions, body] + + proc NewType(kind: TTypeKind, owner: PSym): PType = new(result) result.kind = kind diff --git a/compiler/c2nim/cparse.nim b/compiler/c2nim/cparse.nim index cb023411d..9f7a7bf36 100755 --- a/compiler/c2nim/cparse.nim +++ b/compiler/c2nim/cparse.nim @@ -1382,7 +1382,7 @@ proc nestedStatement(p: var TParser): PNode = # Nimrod requires complex statements to be nested in whitespace! const complexStmt = {nkProcDef, nkMethodDef, nkConverterDef, nkMacroDef, - nkTemplateDef, nkIteratorDef, nkMacroStmt, nkIfStmt, + nkTemplateDef, nkIteratorDef, nkIfStmt, nkWhenStmt, nkForStmt, nkWhileStmt, nkCaseStmt, nkVarSection, nkConstSection, nkTypeSection, nkTryStmt, nkBlockStmt, nkStmtList, nkCommentStmt, nkStmtListExpr, nkBlockExpr, nkStmtListType, nkBlockType} diff --git a/compiler/evals.nim b/compiler/evals.nim index e72231bf5..c6248e823 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -1296,7 +1296,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode = of nkEmpty: result = n of nkSym: result = evalSym(c, n, flags) of nkType..nkNilLit: result = copyNode(n) # end of atoms - of nkCall, nkHiddenCallConv, nkMacroStmt, nkCommand, nkCallStrLit, nkInfix, + of nkCall, nkHiddenCallConv, nkCommand, nkCallStrLit, nkInfix, nkPrefix, nkPostfix: result = evalMagicOrCall(c, n) of nkCurly, nkBracket, nkRange: diff --git a/compiler/idents.nim b/compiler/idents.nim index f6df3ba93..838d445d3 100755 --- a/compiler/idents.nim +++ b/compiler/idents.nim @@ -101,4 +101,6 @@ proc getIdent*(identifier: string, h: THash): PIdent = proc IdentEq*(id: PIdent, name: string): bool = result = id.id == getIdent(name).id - + +let idAnon* = getIdent":anonymous" + diff --git a/compiler/msgs.nim b/compiler/msgs.nim index e29142e4f..0d9a05240 100755 --- a/compiler/msgs.nim +++ b/compiler/msgs.nim @@ -585,22 +585,25 @@ proc inCheckpoint*(current: TLineInfo): TCheckPointResult = type TErrorHandling = enum doNothing, doAbort, doRaise -proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = - if msg == errInternal: - assert(false) # we want a stack trace here +proc handleError(msg: TMsgKind, eh: TErrorHandling, s: string) = + template maybeTrace = + if defined(debug) or gVerbosity >= 3: + writeStackTrace() + + if msg == errInternal: + writeStackTrace() # we always want a stack trace here if msg >= fatalMin and msg <= fatalMax: - if gVerbosity >= 3: assert(false) + maybeTrace() quit(1) if msg >= errMin and msg <= errMax: - if gVerbosity >= 3: assert(false) + maybeTrace() inc(gErrorCounter) options.gExitcode = 1'i8 if gErrorCounter >= gErrorMax or eh == doAbort: - if gVerbosity >= 3: assert(false) - quit(1) # one error stops the compiler + quit(1) # one error stops the compiler elif eh == doRaise: raiseRecoverableError(s) - + proc `==`*(a, b: TLineInfo): bool = result = a.line == b.line and a.fileIndex == b.fileIndex diff --git a/compiler/options.nim b/compiler/options.nim index c6b2053b1..316ec2b14 100755 --- a/compiler/options.nim +++ b/compiler/options.nim @@ -227,5 +227,7 @@ proc binaryStrSearch*(x: openarray[string], y: string): int = result = - 1 # Can we keep this? I'm using it all the time -template nimdbg*: expr = c.filename.endsWith"nimdbg.nim" -template cnimdbg*: expr = p.module.filename.endsWith"nimdbg.nim" +template nimdbg*: expr = c.filename.endsWith"hallo.nim" +template cnimdbg*: expr = p.module.filename.endsWith"hallo.nim" +template enimdbg*: expr = c.module.name.s == "hallo" +template pnimdbg*: expr = p.lex.fileIdx.ToFilename.endsWith"hallo.nim" diff --git a/compiler/parser.nim b/compiler/parser.nim index 7612980c5..095252d59 100755 --- a/compiler/parser.nim +++ b/compiler/parser.nim @@ -693,20 +693,15 @@ proc optPragmas(p: var TParser): PNode = else: result = ast.emptyNode proc parseDoBlock(p: var TParser): PNode = - var info = parLineInfo(p) + let info = parLineInfo(p) getTok(p) - var params = parseParamList(p, retColon=false) - var pragmas = optPragmas(p) + let params = parseParamList(p, retColon=false) + let pragmas = optPragmas(p) eat(p, tkColon) - result = newNodeI(nkDo, info) - addSon(result, ast.emptyNode) # no name part - addSon(result, ast.emptyNode) # no pattern part - addSon(result, ast.emptyNode) # no generic parameters - addSon(result, params) - addSon(result, pragmas) skipComment(p, result) - addSon(result, ast.emptyNode) # no exception list - addSon(result, parseStmt(p)) + result = newProcNode(nkDo, info, parseStmt(p), + params = params, + pragmas = pragmas) proc parseDoBlocks(p: var TParser, call: PNode) = while p.tok.tokType == tkDo: @@ -723,16 +718,11 @@ proc parseProcExpr(p: var TParser, isExpr: bool): PNode = params = parseParamList(p) pragmas = optPragmas(p) if p.tok.tokType == tkEquals and isExpr: - result = newNodeI(nkLambda, info) - addSon(result, ast.emptyNode) # no name part - addSon(result, ast.emptyNode) # no pattern - addSon(result, ast.emptyNode) # no generic parameters - addSon(result, params) - addSon(result, pragmas) getTok(p) skipComment(p, result) - addSon(result, ast.emptyNode) # no exception list - addSon(result, parseStmt(p)) + result = newProcNode(nkLambda, info, parseStmt(p), + params = params, + pragmas = pragmas) else: result = newNodeI(nkProcTy, info) if hasSignature: @@ -822,7 +812,7 @@ proc primary(p: var TParser, skipSuffix = false): PNode = proc parseTypeDesc(p: var TParser): PNode = if p.tok.toktype == tkProc: result = parseProcExpr(p, false) else: result = parseExpr(p) - + proc parseExprStmt(p: var TParser): PNode = var a = lowestExpr(p) if p.tok.tokType == tkEquals: @@ -832,32 +822,29 @@ proc parseExprStmt(p: var TParser): PNode = result = newNodeI(nkAsgn, a.info) addSon(result, a) addSon(result, b) - else: - result = newNodeP(nkCommand, p) - result.info = a.info - addSon(result, a) - while true: + else: + var call = if a.kind == nkCall: a + else: newNode(nkCommand, a.info, @[a]) + while true: if not isExprStart(p): break var e = parseExpr(p) - addSon(result, e) + addSon(call, e) if p.tok.tokType != tkComma: break getTok(p) optInd(p, a) if p.tok.tokType == tkDo: - parseDoBlocks(p, result) + parseDoBlocks(p, call) return - if sonsLen(result) <= 1: result = a - else: a = result + result = if call.sonsLen <= 1: a + else: call if p.tok.tokType == tkColon: - # macro statement - result = newNodeP(nkMacroStmt, p) - result.info = a.info - addSon(result, a) + result = call getTok(p) skipComment(p, result) if p.tok.tokType == tkSad: getTok(p) - if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}): - addSon(result, parseStmt(p)) + if not (p.tok.TokType in {tkOf, tkElif, tkElse, tkExcept}): + let body = parseStmt(p) + addSon(result, newProcNode(nkDo, body.info, body)) while true: if p.tok.tokType == tkSad: getTok(p) var b: PNode @@ -882,7 +869,7 @@ proc parseExprStmt(p: var TParser): PNode = else: break addSon(b, parseStmt(p)) addSon(result, b) - if b.kind == nkElse: break + if b.kind == nkElse: break proc parseImportOrIncludeStmt(p: var TParser, kind: TNodeKind): PNode = var a: PNode diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 5199e234d..de642eccb 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -1051,7 +1051,6 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) = of nkWhileStmt: gwhile(g, n) of nkPragmaBlock: gpragmaBlock(g, n) of nkCaseStmt, nkRecCase: gcase(g, n) - of nkMacroStmt: gmacro(g, n) of nkTryStmt: gtry(g, n) of nkForStmt, nkParForStmt: gfor(g, n) of nkBlockStmt, nkBlockExpr: gblock(g, n) diff --git a/compiler/sem.nim b/compiler/sem.nim index 0a6159dfa..9289df61c 100755 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -22,8 +22,7 @@ proc semPass*(): TPass type TExprFlag = enum - efLValue, efWantIterator, efInTypeof, efWantStmt, - efMacroStmt # expr to semcheck is a macro statement + efLValue, efWantIterator, efInTypeof, efWantStmt, efDetermineType TExprFlags = set[TExprFlag] proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode @@ -35,7 +34,7 @@ proc semProcBody(c: PContext, n: PNode): PNode proc fitNode(c: PContext, formal: PType, arg: PNode): PNode proc changeType(n: PNode, newType: PType) -proc semLambda(c: PContext, n: PNode): PNode +proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode proc semTypeNode(c: PContext, n: PNode, prev: PType): PType proc semStmt(c: PContext, n: PNode): PNode proc semParamList(c: PContext, n, genericParams: PNode, s: PSym) @@ -44,6 +43,8 @@ proc addResult(c: PContext, t: PType, info: TLineInfo, owner: TSymKind) proc addResultNode(c: PContext, n: PNode) proc instGenericContainer(c: PContext, n: PNode, header: PType): PType proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode +proc fixImmediateParams(n: PNode): PNode +proc activate(c: PContext, n: PNode) proc typeMismatch(n: PNode, formal, actual: PType) = if formal.kind != tyError and actual.kind != tyError: @@ -91,8 +92,6 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, semCheck = true): PNode proc semMacroExpr(c: PContext, n, nOrig: PNode, sym: PSym, semCheck: bool = true): PNode -proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags, - semCheck = true): PNode proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode proc semWhen(c: PContext, n: PNode, semCheck: bool = true): PNode diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index e9dc5a8e9..adcd67ea3 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -304,16 +304,17 @@ proc semIs(c: PContext, n: PNode): PNode = # BUGFIX: don't evaluate this too early: ``T is void`` if not containsGenericType(t1): result = evalIsOp(n) -proc semOpAux(c: PContext, n: PNode, tailToExclude = 1) = - for i in countup(1, sonsLen(n) - tailToExclude): +proc semOpAux(c: PContext, n: PNode) = + let flags = {efDetermineType} + for i in countup(1, n.sonsLen- 1): var a = n.sons[i] if a.kind == nkExprEqExpr and sonsLen(a) == 2: var info = a.sons[0].info a.sons[0] = newIdentNode(considerAcc(a.sons[0]), info) - a.sons[1] = semExprWithType(c, a.sons[1]) + a.sons[1] = semExprWithType(c, a.sons[1], flags) a.typ = a.sons[1].typ else: - n.sons[i] = semExprWithType(c, a) + n.sons[i] = semExprWithType(c, a, flags) proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: @@ -668,8 +669,7 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = # this seems to be a hotspot in the compiler! let nOrig = n.copyTree - semOpAux(c, n, 1 + ord(efMacroStmt in flags)) - let flags = flags - {efMacroStmt} + semOpAux(c, n) result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags) if result == nil: result = overloadedCallOpr(c, n) @@ -679,8 +679,9 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = let callee = result.sons[0].sym case callee.kind of skMacro: result = semMacroExpr(c, result, nOrig, callee) - of skTemplate: result = semTemplateExpr(c, nOrig, callee) + of skTemplate: result = semTemplateExpr(c, result, callee) else: + activate(c, n) fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) if callee.magic != mNone: @@ -1281,7 +1282,7 @@ proc semCompiles(c: PContext, n: PNode, flags: TExprFlags): PNode = # we replace this node by a 'true' or 'false' node: if sonsLen(n) != 2: return semDirectOp(c, n, flags) - result = newIntNode(nkIntLit, ord(tryExpr(c, n, flags) != nil)) + result = newIntNode(nkIntLit, ord(tryExpr(c, n[1], flags) != nil)) result.info = n.info result.typ = getSysType(tyBool) @@ -1496,52 +1497,6 @@ proc buildCall(n: PNode): PNode = else: result = n -proc semMacroStmt(c: PContext, n: PNode, flags: TExprFlags, - semCheck = true): PNode = - checkMinSonsLen(n, 2) - var a: PNode - if isCallExpr(n.sons[0]): a = n.sons[0].sons[0] - else: a = n.sons[0] - var s = qualifiedLookup(c, a, {checkUndeclared}) - if s != nil: - # transform - # nkMacroStmt(nkCall(a...), stmt, b...) - # to - # nkCall(a..., stmt, b...) - result = newNodeI(nkCall, n.info) - addSon(result, a) - if isCallExpr(n.sons[0]): - for i in countup(1, sonsLen(n.sons[0]) - 1): - addSon(result, n.sons[0].sons[i]) - # for sigmatch this need to have a type; we use 'void': - for i in countup(1, sonsLen(n) - 1): - n.sons[i].typ = newTypeS(tyEmpty, c) - addSon(result, n.sons[i]) - - case s.kind - of skMacro: - if sfImmediate notin s.flags: - result = semDirectOp(c, result, flags+{efMacroStmt}) - else: - result = semMacroExpr(c, result, n, s, semCheck) - of skTemplate: - if sfImmediate notin s.flags: - result = semDirectOp(c, result, flags+{efMacroStmt}) - else: - result = semTemplateExpr(c, result, s, semCheck) - else: - LocalError(n.info, errXisNoMacroOrTemplate, s.name.s) - result = errorNode(c, n) - elif a.kind == nkDotExpr: - # 'x.m(y): stmt' == nkMacroStmt(nkCall(nkDotExpr(x, m), y), stmt) - # --> nkMacroStmt(nkCall(m, x, y), stmt) - n.sons[0] = buildCall(n.sons[0]) - result = semMacroStmt(c, n, flags, semCheck) - else: - LocalError(n.info, errInvalidExpressionX, - renderTree(a, {renderNoComments})) - result = errorNode(c, n) - proc semCaseExpr(c: PContext, caseStmt: PNode): PNode = # The case expression is simply rewritten to a StmtListExpr: # var res {.noInit, genSym.}: type(values) @@ -1553,7 +1508,7 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode = # res var info = caseStmt.info - resVar = newSym(skVar, getIdent":res", getCurrOwner(), info) + resVar = newSym(skVar, idAnon, getCurrOwner(), info) resNode = newSymNode(resVar, info) resType: PType @@ -1592,7 +1547,15 @@ proc semCaseExpr(c: PContext, caseStmt: PNode): PNode = resNode]) result = semStmtListExpr(c, result) - + +proc fixImmediateParams(n: PNode): PNode = + # XXX: Temporary work-around until we carry out + # the planned overload resolution reforms + for i in 1 .. <n.len: + if n[i].kind == nkDo: n.sons[i] = n[i][bodyPos] + + result = n + proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = n if gCmd == cmdIdeTools: suggestExpr(c, n) @@ -1670,12 +1633,14 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if sfImmediate notin s.flags: result = semDirectOp(c, n, flags) else: - result = semMacroExpr(c, n, n, s) + var p = fixImmediateParams(n) + result = semMacroExpr(c, p, p, s) of skTemplate: if sfImmediate notin s.flags: result = semDirectOp(c, n, flags) else: - result = semTemplateExpr(c, n, s) + var p = fixImmediateParams(n) + result = semTemplateExpr(c, p, s) of skType: # XXX think about this more (``set`` procs) if n.len == 2: @@ -1695,8 +1660,6 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semDirectOp(c, n, flags) else: result = semIndirectOp(c, n, flags) - of nkMacroStmt: - result = semMacroStmt(c, n, flags) of nkWhen: if efWantStmt in flags: result = semWhen(c, n, true) @@ -1725,7 +1688,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of paSingle: result = semExpr(c, n.sons[0], flags) of nkCurly: result = semSetConstr(c, n) of nkBracket: result = semArrayConstr(c, n) - of nkLambdaKinds: result = semLambda(c, n) + of nkLambdaKinds: result = semLambda(c, n, flags) of nkDerefExpr: result = semDeref(c, n) of nkAddr: result = n diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index bffa8ad8e..4b0c81433 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -53,6 +53,7 @@ proc semGenericStmtSymbol(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s, scOpen) of skTemplate: if macroToExpand(s): + let n = fixImmediateParams(n) result = semTemplateExpr(c, n, s, false) else: result = symChoice(c, n, s, scOpen) @@ -123,6 +124,7 @@ proc semGenericStmt(c: PContext, n: PNode, result = n of skTemplate: if macroToExpand(s): + let n = fixImmediateParams(n) result = semTemplateExpr(c, n, s, false) else: n.sons[0] = symChoice(c, n.sons[0], s, scOpen) @@ -151,17 +153,6 @@ proc semGenericStmt(c: PContext, n: PNode, let flags = if isDefinedMagic: flags+{withinMixin} else: flags for i in countup(first, sonsLen(result) - 1): result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind) - of nkMacroStmt: - checkMinSonsLen(n, 2) - var a: PNode - if isCallExpr(n.sons[0]): a = n.sons[0].sons[0] - else: a = n.sons[0] - let luf = if withinMixin notin flags: {checkUndeclared} else: {} - var s = qualifiedLookup(c, a, luf) - if s != nil and macroToExpand(s): - result = semMacroStmt(c, n, {}, false) - for i in countup(0, sonsLen(result)-1): - result.sons[i] = semGenericStmt(c, result.sons[i], flags, toBind) of nkIfStmt: for i in countup(0, sonsLen(n)-1): n.sons[i] = semGenericStmtScope(c, n.sons[i], flags, toBind) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 2dad56272..0a2275229 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -623,9 +623,9 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode = var key = if it.kind == nkExprColonExpr: it.sons[0] else: it let m = lookupMacro(c, key) if m == nil: continue - # we transform ``proc p {.m, rest.}`` into ``m: proc p {.rest.}`` and + # we transform ``proc p {.m, rest.}`` into ``m(proc p {.rest.})`` and # let the semantic checker deal with it: - var x = newNodeI(nkMacroStmt, n.info) + var x = newNodeI(nkCall, n.info) x.add(newSymNode(m)) prc.sons[pragmasPos] = copyExcept(n, i) if it.kind == nkExprColonExpr: @@ -634,15 +634,19 @@ proc semProcAnnotation(c: PContext, prc: PNode): PNode = x.add(prc) # recursion assures that this works for multiple macro annotations too: return semStmt(c, x) - -proc semLambda(c: PContext, n: PNode): PNode = + +proc semLambda(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semProcAnnotation(c, n) if result != nil: return result result = n checkSonsLen(n, bodyPos + 1) - var s = newSym(skProc, getIdent":anonymous", getCurrOwner(), n.info) - s.ast = n - n.sons[namePos] = newSymNode(s) + var s: PSym + if n[namePos].kind != nkSym: + s = newSym(skProc, idAnon, getCurrOwner(), n.info) + s.ast = n + n.sons[namePos] = newSymNode(s) + else: + s = n[namePos].sym pushOwner(s) openScope(c.tab) if n.sons[genericParamsPos].kind != nkEmpty: @@ -659,19 +663,31 @@ proc semLambda(c: PContext, n: PNode): PNode = if n.sons[bodyPos].kind != nkEmpty: if sfImportc in s.flags: LocalError(n.sons[bodyPos].info, errImplOfXNotAllowed, s.name.s) - pushProcCon(c, s) - addResult(c, s.typ.sons[0], n.info, skProc) - let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) - n.sons[bodyPos] = transformBody(c.module, semBody, s) - addResultNode(c, n) - popProcCon(c) + if efDetermineType notin flags: + pushProcCon(c, s) + addResult(c, s.typ.sons[0], n.info, skProc) + let semBody = hloBody(c, semProcBody(c, n.sons[bodyPos])) + n.sons[bodyPos] = transformBody(c.module, semBody, s) + addResultNode(c, n) + popProcCon(c) + sideEffectsCheck(c, s) else: LocalError(n.info, errImplOfXexpected, s.name.s) - sideEffectsCheck(c, s) closeScope(c.tab) # close scope for parameters popOwner() result.typ = s.typ +proc activate(c: PContext, n: PNode) = + # XXX: This proc is part of my plan for getting rid of + # forward declarations. stay tuned. + case n.kind + of nkLambdaKinds: + discard semLambda(c, n, {}) + of nkCallKinds: + for i in 1 .. <n.len: activate(c, n[i]) + else: + nil + proc instantiateDestructor*(c: PContext, typ: PType): bool proc doDestructorStuff(c: PContext, s: PSym, n: PNode) = diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index 70453c6db..d51e24c89 100755 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -64,10 +64,11 @@ proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode proc prepareNode(cl: var TReplTypeVars, n: PNode): PNode = result = copyNode(n) result.typ = ReplaceTypeVarsT(cl, n.typ) + if result.kind == nkSym: result.sym = ReplaceTypeVarsS(cl, n.sym) for i in 0 .. safeLen(n)-1: # XXX HACK: ``f(a, b)``, avoid to instantiate `f` if i == 0: result.add(n[i]) - else: result.add(ReplaceTypeVarsN(cl, n[i])) + else: result.add(prepareNode(cl, n[i])) proc ReplaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = if n == nil: return diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index 8f1ca5f36..cfae74119 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -637,8 +637,12 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, of isGeneric: inc(m.genericMatches) if m.calleeSym != nil and m.calleeSym.kind in {skMacro, skTemplate}: - if f.kind == tyTypeDesc: result = arg - else: result = argOrig + if f.kind == tyStmt and argOrig.kind == nkDo: + result = argOrig[bodyPos] + elif f.kind == tyTypeDesc: + result = arg + else: + result = argOrig else: result = copyTree(arg) result.typ = getInstantiatedType(c, arg, m, f) diff --git a/compiler/suggest.nim b/compiler/suggest.nim index 719d0aa42..51f250251 100755 --- a/compiler/suggest.nim +++ b/compiler/suggest.nim @@ -175,8 +175,7 @@ proc findClosestDot(n: PNode): PNode = if result != nil: return const - CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit, - nkMacroStmt} + CallNodes = {nkCall, nkInfix, nkPrefix, nkPostfix, nkCommand, nkCallStrLit} proc findClosestCall(n: PNode): PNode = if n.kind in callNodes and msgs.inCheckpoint(n.info) == cpExact: |