diff options
Diffstat (limited to 'compiler/semexprs.nim')
-rwxr-xr-x | compiler/semexprs.nim | 164 |
1 files changed, 93 insertions, 71 deletions
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index d1606eef6..6a9af12ab 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -42,8 +42,9 @@ proc semExprWithType(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = if result.typ != nil: if result.typ.kind == tyVar: result = newDeref(result) else: - GlobalError(n.info, errExprXHasNoType, - renderTree(result, {renderNoComments})) + LocalError(n.info, errExprXHasNoType, + renderTree(result, {renderNoComments})) + result.typ = errorType(c) proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = semExpr(c, n, flags) @@ -51,8 +52,9 @@ proc semExprNoDeref(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = # do not produce another redundant error message: raiseRecoverableError("") if result.typ == nil: - GlobalError(n.info, errExprXHasNoType, - renderTree(result, {renderNoComments})) + LocalError(n.info, errExprXHasNoType, + renderTree(result, {renderNoComments})) + result.typ = errorType(c) proc semSymGenericInstantiation(c: PContext, n: PNode, s: PSym): PNode = result = symChoice(c, n, s) @@ -113,7 +115,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = c.p.owner.typ.callConv = ccClosure if illegalCapture(s) or c.p.next.owner != s.owner: # Currently captures are restricted to a single level of nesting: - GlobalError(n.info, errIllegalCaptureX, s.name.s) + LocalError(n.info, errIllegalCaptureX, s.name.s) result = newSymNode(s, n.info) of skGenericParam: if s.ast == nil: InternalError(n.info, "no default for") @@ -129,7 +131,7 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) = var diff = inheritanceDiff(castDest, src) if diff == high(int): - GlobalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [ + LocalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [ src.typeToString, castDest.typeToString]) const @@ -147,7 +149,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) = d = base(d) s = base(s) if d == nil: - GlobalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [ + LocalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [ src.typeToString, castDest.typeToString]) elif d.Kind == tyObject and s.Kind == tyObject: checkConversionBetweenObjects(info, d, s) @@ -159,7 +161,7 @@ proc checkConvertible(info: TLineInfo, castDest, src: PType) = case cmpTypes(d, s) of isNone, isGeneric: if not compareTypes(castDest, src, dcEqIgnoreDistinct): - GlobalError(info, errGenerated, `%`( + LocalError(info, errGenerated, `%`( MsgKindToString(errIllegalConvFromXtoY), [typeToString(src), typeToString(castDest)])) else: @@ -184,7 +186,9 @@ proc isCastable(dst, src: PType): bool = (skipTypes(src, abstractInst).kind in IntegralTypes) proc semConv(c: PContext, n: PNode, s: PSym): PNode = - if sonsLen(n) != 2: GlobalError(n.info, errConvNeedsOneArg) + if sonsLen(n) != 2: + LocalError(n.info, errConvNeedsOneArg) + return n result = newNodeI(nkConv, n.info) result.typ = semTypeNode(c, n.sons[0], nil) addSon(result, copyTree(n.sons[0])) @@ -210,14 +214,14 @@ proc semCast(c: PContext, n: PNode): PNode = addSon(result, copyTree(n.sons[0])) addSon(result, semExprWithType(c, n.sons[1])) if not isCastable(result.typ, result.sons[1].Typ): - GlobalError(result.info, errExprCannotBeCastedToX, - typeToString(result.Typ)) + LocalError(result.info, errExprCannotBeCastedToX, + typeToString(result.Typ)) proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = const opToStr: array[mLow..mHigh, string] = ["low", "high"] if sonsLen(n) != 2: - GlobalError(n.info, errXExpectsTypeOrValue, opToStr[m]) + LocalError(n.info, errXExpectsTypeOrValue, opToStr[m]) else: n.sons[1] = semExprWithType(c, n.sons[1]) restoreOldStyleType(n.sons[1]) @@ -229,12 +233,12 @@ proc semLowHigh(c: PContext, n: PNode, m: TMagic): PNode = n.typ = n.sons[1].typ.sons[0] # indextype of tyInt..tyInt64, tyChar, tyBool, tyEnum, tyUInt8, tyUInt16, tyUInt32: n.typ = n.sons[1].typ - else: GlobalError(n.info, errInvalidArgForX, opToStr[m]) + else: LocalError(n.info, errInvalidArgForX, opToStr[m]) result = n proc semSizeof(c: PContext, n: PNode): PNode = if sonsLen(n) != 2: - GlobalError(n.info, errXExpectsTypeOrValue, "sizeof") + LocalError(n.info, errXExpectsTypeOrValue, "sizeof") else: n.sons[1] = semExprWithType(c, n.sons[1]) restoreOldStyleType(n.sons[1]) @@ -253,26 +257,27 @@ proc semOf(c: PContext, n: PNode): PNode = let y = skipTypes(n.sons[2].typ, abstractPtrs) if x.kind == tyTypeDesc or y.kind != tyTypeDesc: - GlobalError(n.info, errXExpectsObjectTypes, "of") + LocalError(n.info, errXExpectsObjectTypes, "of") elif b.kind != tyObject or a.kind != tyObject: - GlobalError(n.info, errXExpectsObjectTypes, "of") - let diff = inheritanceDiff(a, b) - # | returns: 0 iff `a` == `b` - # | returns: -x iff `a` is the x'th direct superclass of `b` - # | returns: +x iff `a` is the x'th direct subclass of `b` - # | returns: `maxint` iff `a` and `b` are not compatible at all - if diff <= 0: - # optimize to true: - Message(n.info, hintConditionAlwaysTrue, renderTree(n)) - result = newIntNode(nkIntLit, 1) - result.info = n.info - result.typ = getSysType(tyBool) - return result - elif diff == high(int): - GlobalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) - n.typ = getSysType(tyBool) - else: - GlobalError(n.info, errXExpectsTwoArguments, "of") + LocalError(n.info, errXExpectsObjectTypes, "of") + else: + let diff = inheritanceDiff(a, b) + # | returns: 0 iff `a` == `b` + # | returns: -x iff `a` is the x'th direct superclass of `b` + # | returns: +x iff `a` is the x'th direct subclass of `b` + # | returns: `maxint` iff `a` and `b` are not compatible at all + if diff <= 0: + # optimize to true: + Message(n.info, hintConditionAlwaysTrue, renderTree(n)) + result = newIntNode(nkIntLit, 1) + result.info = n.info + result.typ = getSysType(tyBool) + return result + elif diff == high(int): + LocalError(n.info, errXcanNeverBeOfThisSubtype, typeToString(a)) + else: + LocalError(n.info, errXExpectsTwoArguments, "of") + n.typ = getSysType(tyBool) result = n proc semIs(c: PContext, n: PNode): PNode = @@ -283,9 +288,9 @@ proc semIs(c: PContext, n: PNode): PNode = if n[2].kind notin {nkStrLit..nkTripleStrLit}: let b = semTypeNode(c, n[2], nil) n.sons[2] = newNodeIT(nkType, n[2].info, b) - result = n else: - GlobalError(n.info, errXExpectsTwoArguments, "is") + LocalError(n.info, errXExpectsTwoArguments, "is") + result = n proc semOpAux(c: PContext, n: PNode) = for i in countup(1, sonsLen(n) - 1): @@ -590,7 +595,7 @@ proc semOverloadedCallAnalyseEffects(c: PContext, n: PNode, nOrig: PNode, of skMacro, skTemplate: nil else: if (callee.kind == skIterator) and (callee.id == c.p.owner.id): - GlobalError(n.info, errRecursiveDependencyX, callee.name.s) + LocalError(n.info, errRecursiveDependencyX, callee.name.s) if sfNoSideEffect notin callee.flags: if {sfImportc, sfSideEffect} * callee.flags != {}: incl(c.p.owner.flags, sfSideEffect) @@ -625,7 +630,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = if m.state != csMatch: if c.inCompilesContext > 0: # speed up error generation: - GlobalError(n.Info, errTypeMismatch, "") + LocalError(n.Info, errTypeMismatch, "") + return emptyNode else: var msg = msgKindToString(errTypeMismatch) for i in countup(1, sonsLen(n) - 1): @@ -633,7 +639,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = add(msg, typeToString(n.sons[i].typ)) add(msg, ")\n" & msgKindToString(errButExpected) & "\n" & typeToString(n.sons[0].typ)) - GlobalError(n.Info, errGenerated, msg) + LocalError(n.Info, errGenerated, msg) + return emptyNode result = nil else: result = m.call @@ -649,8 +656,9 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = nOrig.sons[0] = prc result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags) if result == nil: - GlobalError(n.info, errExprXCannotBeCalled, - renderTree(n, {renderNoComments})) + LocalError(n.info, errExprXCannotBeCalled, + renderTree(n, {renderNoComments})) + return emptyNode fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) if result.sons[0].kind == nkSym and result.sons[0].sym.magic != mNone: @@ -664,7 +672,9 @@ proc semDirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = result = semOverloadedCallAnalyseEffects(c, n, nOrig, flags) if result == nil: result = overloadedCallOpr(c, n) - if result == nil: GlobalError(n.Info, errGenerated, getNotFoundError(c, n)) + if result == nil: + LocalError(n.Info, errGenerated, getNotFoundError(c, n)) + return emptyNode let callee = result.sons[0].sym case callee.kind of skMacro: result = semMacroExpr(c, nOrig, callee) @@ -696,8 +706,11 @@ proc buildEchoStmt(c: PContext, n: PNode): PNode = # we MUST not check 'n' for semantics again here! result = newNodeI(nkCall, n.info) var e = StrTableGet(magicsys.systemModule.Tab, getIdent"echo") - if e == nil: GlobalError(n.info, errSystemNeeds, "echo") - addSon(result, newSymNode(e)) + if e != nil: + addSon(result, newSymNode(e)) + else: + LocalError(n.info, errSystemNeeds, "echo") + addSon(result, emptyNode) var arg = buildStringify(c, n) # problem is: implicit '$' is not checked for semantics yet. So we give up # and check 'arg' for semantics again: @@ -890,7 +903,8 @@ proc semFieldAccess(c: PContext, n: PNode, flags: TExprFlags): PNode = addSon(result, newIdentNode(i, n.info)) addSon(result, copyTree(n[0])) else: - GlobalError(n.Info, errUndeclaredFieldX, i.s) + LocalError(n.Info, errUndeclaredFieldX, i.s) + result = emptyNode proc buildOverloadedSubscripts(n: PNode, ident: PIdent): PNode = result = newNodeI(nkCall, n.info) @@ -946,9 +960,9 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = {tyInt..tyInt64}: var idx = getOrdValue(n.sons[1]) if idx >= 0 and idx < sonsLen(arr): n.typ = arr.sons[int(idx)] - else: GlobalError(n.info, errInvalidIndexValueForTuple) + else: LocalError(n.info, errInvalidIndexValueForTuple) else: - GlobalError(n.info, errIndexTypesDoNotMatch) + LocalError(n.info, errIndexTypesDoNotMatch) result = n else: nil @@ -972,7 +986,7 @@ proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode = fixAbstractType(c, result) analyseIfAddressTakenInCall(c, result) else: - globalError(n.Info, errUndeclaredFieldX, id.s) + LocalError(n.Info, errUndeclaredFieldX, id.s) proc takeImplicitAddr(c: PContext, n: PNode): PNode = case n.kind @@ -984,9 +998,9 @@ proc takeImplicitAddr(c: PContext, n: PNode): PNode = var valid = isAssignable(c, n) if valid != arLValue: if valid == arLocalLValue: - GlobalError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) + LocalError(n.info, errXStackEscape, renderTree(n, {renderNoComments})) else: - GlobalError(n.info, errExprHasNoAddress) + LocalError(n.info, errExprHasNoAddress) result = newNodeIT(nkHiddenAddr, n.info, makePtrType(c, n.typ)) result.add(n) @@ -1062,13 +1076,13 @@ proc LookUpForDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PSym = else: result = StrTableGet(m.tab, ident) else: - GlobalError(n.sons[1].info, errIdentifierExpected, "") + LocalError(n.sons[1].info, errIdentifierExpected, "") of nkAccQuoted: result = lookupForDefined(c, considerAcc(n), onlyCurrentScope) of nkSym: result = n.sym else: - GlobalError(n.info, errIdentifierExpected, renderTree(n)) + LocalError(n.info, errIdentifierExpected, renderTree(n)) result = nil proc semDefined(c: PContext, n: PNode, onlyCurrentScope: bool): PNode = @@ -1091,17 +1105,20 @@ proc setMs(n: PNode, s: PSym): PNode = proc expectMacroOrTemplateCall(c: PContext, n: PNode): PSym = ## The argument to the proc should be nkCall(...) or similar ## Returns the macro/template symbol - if not isCallExpr(n): - GlobalError(n.info, errXisNoMacroOrTemplate, n.renderTree) - - var expandedSym = qualifiedLookup(c, n[0], {checkUndeclared}) - if expandedSym == nil: - GlobalError(n.info, errUndeclaredIdentifier, n[0].renderTree) + if isCallExpr(n): + var expandedSym = qualifiedLookup(c, n[0], {checkUndeclared}) + if expandedSym == nil: + LocalError(n.info, errUndeclaredIdentifier, n[0].renderTree) + return errorSym(n[0]) - if expandedSym.kind notin {skMacro, skTemplate}: - GlobalError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s) + if expandedSym.kind notin {skMacro, skTemplate}: + LocalError(n.info, errXisNoMacroOrTemplate, expandedSym.name.s) + return errorSym(n[0]) - result = expandedSym + result = expandedSym + else: + LocalError(n.info, errXisNoMacroOrTemplate, n.renderTree) + result = errorSym(n) proc semExpandToAst(c: PContext, n: PNode, magicSym: PSym, flags: TExprFlags): PNode = @@ -1240,7 +1257,7 @@ proc semSetConstr(c: PContext, n: PNode): PNode = if typ == nil: typ = skipTypes(n.sons[i].typ, {tyGenericInst, tyVar, tyOrdinal}) if not isOrdinalType(typ): - GlobalError(n.info, errOrdinalTypeExpected) + LocalError(n.info, errOrdinalTypeExpected) return if lengthOrd(typ) > MaxSetElements: typ = makeRangeType(c, 0, MaxSetElements - 1, n.info) @@ -1288,11 +1305,11 @@ proc checkPar(n: PNode): TParKind = if result == paTupleFields: if (n.sons[i].kind != nkExprColonExpr) or not (n.sons[i].sons[0].kind in {nkSym, nkIdent}): - GlobalError(n.sons[i].info, errNamedExprExpected) + LocalError(n.sons[i].info, errNamedExprExpected) return paNone else: if n.sons[i].kind == nkExprColonExpr: - GlobalError(n.sons[i].info, errNamedExprNotAllowed) + LocalError(n.sons[i].info, errNamedExprNotAllowed) return paNone proc semTupleFieldsConstr(c: PContext, n: PNode): PNode = @@ -1369,10 +1386,13 @@ proc semMacroStmt(c: PContext, n: PNode, semCheck = true): PNode = addSon(result, n.sons[0].sons[i]) for i in countup(1, sonsLen(n) - 1): addSon(result, n.sons[i]) result = semTemplateExpr(c, result, s, semCheck) - else: GlobalError(n.info, errXisNoMacroOrTemplate, s.name.s) - else: - GlobalError(n.info, errInvalidExpressionX, - renderTree(a, {renderNoComments})) + else: + LocalError(n.info, errXisNoMacroOrTemplate, s.name.s) + result = emptyNode + else: + LocalError(n.info, errInvalidExpressionX, + renderTree(a, {renderNoComments})) + result = emptyNode proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = result = n @@ -1505,7 +1525,7 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = checkSonsLen(n, 1) n.sons[0] = semExprWithType(c, n.sons[0]) if isAssignable(c, n.sons[0]) notin {arLValue, arLocalLValue}: - GlobalError(n.info, errExprHasNoAddress) + LocalError(n.info, errExprHasNoAddress) n.typ = makePtrType(c, n.sons[0].typ) of nkHiddenAddr, nkHiddenDeref: checkSonsLen(n, 1) @@ -1525,10 +1545,12 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkTableConstr: result = semTableConstr(c, n) of nkSymChoice: - GlobalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments})) + LocalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments})) + # error correction: Pick first element: + result = n.sons[0] of nkStaticExpr: result = semStaticExpr(c, n) else: - GlobalError(n.info, errInvalidExpressionX, - renderTree(n, {renderNoComments})) + LocalError(n.info, errInvalidExpressionX, + renderTree(n, {renderNoComments})) incl(result.flags, nfSem) |