diff options
Diffstat (limited to 'compiler/semexprs.nim')
-rw-r--r-- | compiler/semexprs.nim | 111 |
1 files changed, 57 insertions, 54 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 6b32fa66c..f0cda504f 100644 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -26,10 +26,10 @@ proc semTemplateExpr(c: PContext, n: PNode, s: PSym, flags: TExprFlags = {}): PNode = markUsed(c.config, n.info, s, c.graph.usageSym) styleCheckUse(n.info, s) - pushInfoContext(n.info) + pushInfoContext(c.config, n.info) result = evalTemplate(n, s, getCurrOwner(c), c.config, efFromHlo in flags) if efNoSemCheck notin flags: result = semAfterMacroCall(c, n, result, s, flags) - popInfoContext() + popInfoContext(c.config) proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags = {}): PNode @@ -58,7 +58,7 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: #raiseRecoverableError("") result = errorNode(c, n) - if result.typ == nil or result.typ == enforceVoidContext: + if result.typ == nil or result.typ == c.enforceVoidContext: localError(c.config, n.info, errExprXHasNoType % renderTree(result, {renderNoComments})) result.typ = errorType(c) @@ -137,7 +137,7 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus = else: discard -proc isCastable(dst, src: PType): bool = +proc isCastable(conf: ConfigRef; dst, src: PType): bool = ## Checks whether the source type can be cast to the destination type. ## Casting is very unrestrictive; casts are allowed as long as ## castDest.size >= src.size, and typeAllowed(dst, skParam) @@ -152,8 +152,8 @@ proc isCastable(dst, src: PType): bool = return false var dstSize, srcSize: BiggestInt - dstSize = computeSize(dst) - srcSize = computeSize(src) + dstSize = computeSize(conf, dst) + srcSize = computeSize(conf, src) if dstSize < 0: result = false elif srcSize < 0: @@ -167,7 +167,7 @@ proc isCastable(dst, src: PType): bool = (skipTypes(dst, abstractInst).kind in IntegralTypes) or (skipTypes(src, abstractInst-{tyTypeDesc}).kind in IntegralTypes) if result and src.kind == tyNil: - result = dst.size <= platform.ptrSize + result = dst.size <= conf.target.ptrSize proc isSymChoice(n: PNode): bool {.inline.} = result = n.kind in nkSymChoices @@ -251,7 +251,7 @@ proc semCast(c: PContext, n: PNode): PNode = let castedExpr = semExprWithType(c, n.sons[1]) if tfHasMeta in targetType.flags: localError(c.config, n.sons[0].info, "cannot cast to a non concrete type: '$1'" % $targetType) - if not isCastable(targetType, castedExpr.typ): + if not isCastable(c.config, targetType, castedExpr.typ): let tar = $targetType let alt = typeToString(targetType, preferDesc) let msg = if tar != alt: tar & "=" & alt else: tar @@ -353,7 +353,7 @@ proc semOpAux(c: PContext, n: PNode) = var a = n.sons[i] if a.kind == nkExprEqExpr and sonsLen(a) == 2: let info = a.sons[0].info - a.sons[0] = newIdentNode(considerQuotedIdent(c.config, a.sons[0], a), info) + a.sons[0] = newIdentNode(considerQuotedIdent(c, a.sons[0], a), info) a.sons[1] = semExprWithType(c, a.sons[1], flags) a.typ = a.sons[1].typ else: @@ -361,7 +361,7 @@ proc semOpAux(c: PContext, n: PNode) = proc overloadedCallOpr(c: PContext, n: PNode): PNode = # quick check if there is *any* () operator overloaded: - var par = getIdent("()") + var par = getIdent(c.cache, "()") if searchInScopes(c, par) == nil: result = nil else: @@ -407,7 +407,7 @@ proc changeType(c: PContext; n: PNode, newType: PType, check: bool) = of nkCharLit..nkUInt64Lit: if check and n.kind != nkUInt64Lit: let value = n.intVal - if value < firstOrd(newType) or value > lastOrd(newType): + if value < firstOrd(c.config, newType) or value > lastOrd(c.config, newType): localError(c.config, n.info, "cannot convert " & $value & " to " & typeToString(newType)) else: discard @@ -617,12 +617,12 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = call.add(a) #echo "NOW evaluating at compile time: ", call.renderTree if sfCompileTime in callee.flags: - result = evalStaticExpr(c.module, c.cache, c.graph, call, c.p.owner) + result = evalStaticExpr(c.module, c.graph, call, c.p.owner) if result.isNil: localError(c.config, n.info, errCannotInterpretNodeX % renderTree(call)) else: result = fixupTypeAfterEval(c, result, n) else: - result = evalConstExpr(c.module, c.cache, c.graph, call) + result = evalConstExpr(c.module, c.graph, call) if result.isNil: result = n else: result = fixupTypeAfterEval(c, result, n) #if result != n: @@ -631,10 +631,10 @@ proc evalAtCompileTime(c: PContext, n: PNode): PNode = proc semStaticExpr(c: PContext, n: PNode): PNode = let a = semExpr(c, n.sons[0]) if a.findUnresolvedStatic != nil: return a - result = evalStaticExpr(c.module, c.cache, c.graph, a, c.p.owner) + result = evalStaticExpr(c.module, c.graph, a, c.p.owner) if result.isNil: localError(c.config, n.info, errCannotInterpretNodeX % renderTree(n)) - result = emptyNode + result = c.graph.emptyNode else: result = fixupTypeAfterEval(c, result, a) @@ -742,10 +742,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = # This is a proc variable, apply normal overload resolution let m = resolveIndirectCall(c, n, nOrig, t) if m.state != csMatch: - if errorOutputs == {}: + if c.config.m.errorOutputs == {}: # speed up error generation: globalError(c.config, n.info, "type mismatch") - return emptyNode + return c.graph.emptyNode else: var hasErrorType = false var msg = "type mismatch: got <" @@ -802,7 +802,7 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = proc buildEchoStmt(c: PContext, n: PNode): PNode = # we MUST not check 'n' for semantics again here! But for now we give up: result = newNodeI(nkCall, n.info) - var e = strTableGet(c.graph.systemModule.tab, getIdent"echo") + var e = strTableGet(c.graph.systemModule.tab, getIdent(c.cache, "echo")) if e != nil: add(result, newSymNode(e)) else: @@ -866,7 +866,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, else: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, ast.emptyNode) # make space for access node + addSon(check, c.graph.emptyNode) # make space for access node s = newNodeIT(nkCurly, n.info, setType) for j in countup(0, sonsLen(it) - 2): addSon(s, copyTree(it.sons[j])) var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) @@ -881,7 +881,7 @@ proc lookupInRecordAndBuildCheck(c: PContext, n, r: PNode, field: PIdent, if result != nil: if check == nil: check = newNodeI(nkCheckedFieldExpr, n.info) - addSon(check, ast.emptyNode) # make space for access node + addSon(check, c.graph.emptyNode) # make space for access node var inExpr = newNodeIT(nkCall, n.info, getSysType(c.graph, n.info, tyBool)) addSon(inExpr, newSymNode(c.graph.opContains, n.info)) addSon(inExpr, s) @@ -938,7 +938,7 @@ proc readTypeParameter(c: PContext, typ: PType, if rawTyp.n != nil: return rawTyp.n else: - return emptyNode + return c.graph.emptyNode else: let foundTyp = makeTypeDesc(c, rawTyp) return newSymNode(copySym(tParam.sym).linkTo(foundTyp), info) @@ -1082,7 +1082,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = when defined(nimsuggest): if c.config.cmd == cmdIdeTools: suggestExpr(c, n) - if exactEquals(gTrackPos, n[1].info): suggestExprNoCheck(c, n) + if exactEquals(c.config.m.trackPos, n[1].info): suggestExprNoCheck(c, n) var s = qualifiedLookUp(c, n, {checkAmbiguity, checkUndeclared, checkModule}) if s != nil: @@ -1097,7 +1097,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = n.sons[0] = semExprWithType(c, n.sons[0], flags+{efDetermineType}) #restoreOldStyleType(n.sons[0]) - var i = considerQuotedIdent(c.config, n.sons[1], n) + var i = considerQuotedIdent(c, n.sons[1], n) var ty = n.sons[0].typ var f: PSym = nil result = nil @@ -1106,7 +1106,7 @@ proc builtinFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = case t.kind of tyTypeParamsHolders: result = readTypeParameter(c, t, i, n.info) - if result == emptyNode: + if result == c.graph.emptyNode: result = n n.typ = makeTypeFromExpr(c, n.copyTree) return @@ -1217,7 +1217,7 @@ proc dotTransformation(c: PContext, n: PNode): PNode = addSon(result, n.sons[1]) addSon(result, copyTree(n[0])) else: - var i = considerQuotedIdent(c.config, n.sons[1], n) + var i = considerQuotedIdent(c, n.sons[1], n) result = newNodeI(nkDotCall, n.info) result.flags.incl nfDotField addSon(result, newIdentNode(i, n[1].info)) @@ -1328,11 +1328,11 @@ proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semSubscript(c, n, flags) if result == nil: # overloaded [] operator: - result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]")) + result = semExpr(c, buildOverloadedSubscripts(n, getIdent(c.cache, "[]"))) proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode = - var id = considerQuotedIdent(c.config, a[1], a) - var setterId = newIdentNode(getIdent(id.s & '='), n.info) + var id = considerQuotedIdent(c, a[1], a) + var setterId = newIdentNode(getIdent(c.cache, id.s & '='), n.info) # a[0] is already checked for semantics, that does ``builtinFieldAccess`` # this is ugly. XXX Semantic checking should use the ``nfSem`` flag for # nodes? @@ -1409,7 +1409,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = # --> `[]=`(a, i, x) a = semSubscript(c, a, {efLValue}) if a == nil: - result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=") + result = buildOverloadedSubscripts(n.sons[0], getIdent(c.cache, "[]=")) add(result, n[1]) if mode == noOverloadedSubscript: bracketNotFoundError(c, result) @@ -1419,7 +1419,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = return result of nkCurlyExpr: # a{i} = x --> `{}=`(a, i, x) - result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=") + result = buildOverloadedSubscripts(n.sons[0], getIdent(c.cache, "{}=")) add(result, n[1]) return semExprNoType(c, result) of nkPar, nkTupleConstr: @@ -1427,7 +1427,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = # unfortunately we need to rewrite ``(x, y) = foo()`` already here so # that overloading of the assignment operator still works. Usually we # prefer to do these rewritings in transf.nim: - return semStmt(c, lowerTupleUnpackingForAsgn(n, c.p.owner)) + return semStmt(c, lowerTupleUnpackingForAsgn(c.graph, n, c.p.owner)) else: a = semExprWithType(c, a, {efLValue}) else: @@ -1450,7 +1450,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode = rhs = semExprWithType(c, n.sons[1], if lhsIsResult: {efAllowDestructor} else: {}) if lhsIsResult: - n.typ = enforceVoidContext + n.typ = c.enforceVoidContext if c.p.owner.kind != skMacro and resultTypeIsInferrable(lhs.sym.typ): var rhsTyp = rhs.typ if rhsTyp.kind in tyUserTypeClasses and rhsTyp.isResolvedUserTypeClass: @@ -1489,7 +1489,7 @@ proc semReturn(c: PContext, n: PNode): PNode = n.sons[0] = semAsgn(c, a) # optimize away ``result = result``: if n[0][1].kind == nkSym and n[0][1].sym == c.p.resultSym: - n.sons[0] = ast.emptyNode + n.sons[0] = c.graph.emptyNode else: localError(c.config, n.info, errNoReturnTypeDeclared) else: @@ -1593,13 +1593,13 @@ proc lookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = checkSonsLen(n, 2, c.config) var m = lookUpForDefined(c, n.sons[0], onlyCurrentScope) if m != nil and m.kind == skModule: - let ident = considerQuotedIdent(c.config, n[1], n) + let ident = considerQuotedIdent(c, n[1], n) if m == c.module: result = strTableGet(c.topLevelScope.symbols, ident) else: result = strTableGet(m.tab, ident) of nkAccQuoted: - result = lookUpForDefined(c, considerQuotedIdent(c.config, n), onlyCurrentScope) + result = lookUpForDefined(c, considerQuotedIdent(c, n), onlyCurrentScope) of nkSym: result = n.sym of nkOpenSymChoice, nkClosedSymChoice: @@ -1612,7 +1612,7 @@ proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = checkSonsLen(n, 2, c.config) # we replace this node by a 'true' or 'false' node: result = newIntNode(nkIntLit, 0) - if not onlyCurrentScope and considerQuotedIdent(c.config, n[0], n).s == "defined": + if not onlyCurrentScope and considerQuotedIdent(c, n[0], n).s == "defined": if n.sons[1].kind != nkIdent: localError(c.config, n.info, "obsolete usage of 'defined', use 'declared' instead") elif isDefined(c.config, n.sons[1].ident.s): @@ -1711,7 +1711,7 @@ proc processQuotations(c: PContext; n: var PNode, op: string, ids: var seq[PNode]) = template returnQuote(q) = quotes.add q - n = newIdentNode(getIdent($quotes.len), n.info) + n = newIdentNode(getIdent(c.cache, $quotes.len), n.info) ids.add n return @@ -1722,7 +1722,7 @@ proc processQuotations(c: PContext; n: var PNode, op: string, if examinedOp == op: returnQuote n[1] elif examinedOp.startsWith(op): - n.sons[0] = newIdentNode(getIdent(examinedOp.substr(op.len)), n.info) + n.sons[0] = newIdentNode(getIdent(c.cache, examinedOp.substr(op.len)), n.info) elif n.kind == nkAccQuoted and op == "``": returnQuote n[0] @@ -1748,14 +1748,17 @@ proc semQuoteAst(c: PContext, n: PNode): PNode = processQuotations(c, quotedBlock, op, quotes, ids) var dummyTemplate = newProcNode( - nkTemplateDef, quotedBlock.info, quotedBlock, - name = newAnonSym(c, skTemplate, n.info).newSymNode) + nkTemplateDef, quotedBlock.info, body = quotedBlock, + params = c.graph.emptyNode, + name = newAnonSym(c, skTemplate, n.info).newSymNode, + pattern = c.graph.emptyNode, genericParams = c.graph.emptyNode, + pragmas = c.graph.emptyNode, exceptions = c.graph.emptyNode) if ids.len > 0: dummyTemplate.sons[paramsPos] = newNodeI(nkFormalParams, n.info) dummyTemplate[paramsPos].add getSysSym(c.graph, n.info, "typed").newSymNode # return type ids.add getSysSym(c.graph, n.info, "untyped").newSymNode # params type - ids.add emptyNode # no default value + ids.add c.graph.emptyNode # no default value dummyTemplate[paramsPos].add newNode(nkIdentDefs, n.info, ids) var tmpl = semTemplateDef(c, dummyTemplate) @@ -1780,9 +1783,9 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = openScope(c) let oldOwnerLen = len(c.graph.owners) let oldGenerics = c.generics - let oldErrorOutputs = errorOutputs - if efExplain notin flags: errorOutputs = {} - let oldContextLen = msgs.getInfoContextLen() + let oldErrorOutputs = c.config.m.errorOutputs + if efExplain notin flags: c.config.m.errorOutputs = {} + let oldContextLen = msgs.getInfoContextLen(c.config) let oldInGenericContext = c.inGenericContext let oldInUnrolledContext = c.inUnrolledContext @@ -1804,10 +1807,10 @@ proc tryExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = c.inGenericInst = oldInGenericInst c.inStaticContext = oldInStaticContext c.p = oldProcCon - msgs.setInfoContextLen(oldContextLen) + msgs.setInfoContextLen(c.config, oldContextLen) setLen(c.graph.owners, oldOwnerLen) c.currentScope = oldScope - errorOutputs = oldErrorOutputs + c.config.m.errorOutputs = oldErrorOutputs c.config.errorCounter = oldErrorCount c.config.errorMax = oldErrorMax @@ -1913,7 +1916,7 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = result.typ = typ result.add instantiateCreateFlowVarCall(c, typ, n.info).newSymNode else: - result.add emptyNode + result.add c.graph.emptyNode of mProcCall: result = setMs(n, s) result.sons[1] = semExpr(c, n.sons[1]) @@ -1937,17 +1940,17 @@ proc semMagic(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = of mRunnableExamples: if c.config.cmd == cmdDoc and n.len >= 2 and n.lastSon.kind == nkStmtList: if sfMainModule in c.module.flags: - let inp = toFullPath(c.module.info) + let inp = toFullPath(c.config, c.module.info) if c.runnableExamples == nil: c.runnableExamples = newTree(nkStmtList, newTree(nkImportStmt, newStrNode(nkStrLit, expandFilename(inp)))) let imports = newTree(nkStmtList) extractImports(n.lastSon, imports) for imp in imports: c.runnableExamples.add imp - c.runnableExamples.add newTree(nkBlockStmt, emptyNode, copyTree n.lastSon) + c.runnableExamples.add newTree(nkBlockStmt, c.graph.emptyNode, copyTree n.lastSon) result = setMs(n, s) else: - result = emptyNode + result = c.graph.emptyNode else: result = semDirectOp(c, n, flags) @@ -2040,7 +2043,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if not isOrdinalType(typ): localError(c.config, n.info, errOrdinalTypeExpected) typ = makeRangeType(c, 0, MaxSetElements-1, n.info) - elif lengthOrd(typ) > MaxSetElements: + elif lengthOrd(c.config, typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements-1, n.info) addSonSkipIntLit(result.typ, typ) for i in countup(0, sonsLen(n) - 1): @@ -2306,7 +2309,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # check if it is an expression macro: checkMinSonsLen(n, 1, c.config) #when defined(nimsuggest): - # if gIdeCmd == ideCon and gTrackPos == n.info: suggestExprNoCheck(c, n) + # if gIdeCmd == ideCon and c.config.m.trackPos == n.info: suggestExprNoCheck(c, n) let mode = if nfDotField in n.flags: {} else: {checkUndeclared} var s = qualifiedLookUp(c, n.sons[0], mode) if s != nil: @@ -2363,12 +2366,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = checkMinSonsLen(n, 1, c.config) result = semArrayAccess(c, n, flags) of nkCurlyExpr: - result = semExpr(c, buildOverloadedSubscripts(n, getIdent"{}"), flags) + result = semExpr(c, buildOverloadedSubscripts(n, getIdent(c.cache, "{}")), flags) of nkPragmaExpr: var expr = n[0] pragma = n[1] - pragmaName = considerQuotedIdent(c.config, pragma[0]) + pragmaName = considerQuotedIdent(c, pragma[0]) flags = flags case whichKeyword(pragmaName) |