diff options
author | Araq <rumpf_a@web.de> | 2012-10-19 01:59:51 +0200 |
---|---|---|
committer | Araq <rumpf_a@web.de> | 2012-10-19 01:59:51 +0200 |
commit | e6b52fe219f42d0483f467c3ad12b86949fe8eba (patch) | |
tree | 3557225c527837e436b657c155f85c9b00d2f428 /compiler | |
parent | 3f82352c2e53247650a66bff52f552517cff8121 (diff) | |
parent | 2efdf3df81fc1a451f4444e822a870c59e27e586 (diff) | |
download | Nim-e6b52fe219f42d0483f467c3ad12b86949fe8eba.tar.gz |
Merge branch 'master' of github.com:Araq/Nimrod
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 1 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 21 | ||||
-rwxr-xr-x | compiler/ccgexprs.nim | 4 | ||||
-rwxr-xr-x | compiler/cgen.nim | 2 | ||||
-rwxr-xr-x | compiler/semexprs.nim | 98 | ||||
-rwxr-xr-x | compiler/sigmatch.nim | 4 |
6 files changed, 76 insertions, 54 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 83bd360f2..870b2c016 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -715,6 +715,7 @@ const nkCommand, nkCallStrLit} nkLambdaKinds* = {nkLambda, nkDo} + nkSymChoices* = {nkClosedSymChoice, nkOpenSymChoice} skLocalVars* = {skVar, skLet, skForVar, skParam} diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 665d80e32..2673f98b8 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -18,13 +18,14 @@ proc leftAppearsOnRightSide(le, ri: PNode): bool = proc hasNoInit(call: PNode): bool {.inline.} = result = call.sons[0].kind == nkSym and sfNoInit in call.sons[0].sym.flags -proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, pl: PRope) = - var pl = pl +proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, + callee, params: PRope) = + var pl = con(callee, "(".toRope, params) # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) if typ.sons[0] != nil: if isInvalidReturnType(typ.sons[0]): - if sonsLen(ri) > 1: app(pl, ", ") + if params != nil: pl.app(", ") # beware of 'result = p(result)'. We may need to allocate a temporary: if d.k in {locTemp, locNone} or not leftAppearsOnRightSide(le, ri): # Great, we can use 'd': @@ -125,9 +126,9 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) = # getUniqueType() is too expensive here: var typ = skipTypes(ri.sons[0].typ, abstractInst) assert(typ.kind == tyProc) + assert(sonsLen(typ) == sonsLen(typ.n)) var length = sonsLen(ri) for i in countup(1, length - 1): - assert(sonsLen(typ) == sonsLen(typ.n)) if ri.sons[i].typ.isCompileTimeOnly: continue if params != nil: app(params, ", ") if i < sonsLen(typ): @@ -135,7 +136,7 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) = app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym)) else: app(params, genArgNoParam(p, ri.sons[i])) - fixupCall(p, le, ri, d, con(op.r, "(".toRope, params)) + fixupCall(p, le, ri, d, op.r, params) proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) = @@ -210,16 +211,16 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) = if skipTypes(param.typ, {tyGenericInst}).kind == tyPtr: app(pl, "->") else: app(pl, ".") app(pl, op.r) - app(pl, "(") + var params: PRope for i in countup(2, length - 1): + if params != nil: params.app(", ") assert(sonsLen(typ) == sonsLen(typ.n)) if i < sonsLen(typ): assert(typ.n.sons[i].kind == nkSym) - app(pl, genArg(p, ri.sons[i], typ.n.sons[i].sym)) + app(params, genArg(p, ri.sons[i], typ.n.sons[i].sym)) else: - app(pl, genArgNoParam(p, ri.sons[i])) - if i < length - 1: app(pl, ", ") - fixupCall(p, le, ri, d, pl) + app(params, genArgNoParam(p, ri.sons[i])) + fixupCall(p, le, ri, d, pl, params) proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) = # generates a crappy ObjC call diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index d10b37432..d6666d88b 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -223,7 +223,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = # little HACK to support the new 'var T' as return type: lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) return - var ty = skipTypes(dest.t, abstractVarRange) + var ty = skipTypes(dest.t, abstractRange) case ty.kind of tyRef: genRefAssign(p, dest, src, flags) @@ -282,7 +282,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) = else: lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) of tyPtr, tyPointer, tyChar, tyBool, tyEnum, tyCString, - tyInt..tyUInt64, tyRange: + tyInt..tyUInt64, tyRange, tyVar: lineCg(p, cpsStmts, "$1 = $2;$n", [rdLoc(dest), rdLoc(src)]) else: InternalError("genAssignment(" & $ty.kind & ')') diff --git a/compiler/cgen.nim b/compiler/cgen.nim index ffd9babde..0e0962936 100755 --- a/compiler/cgen.nim +++ b/compiler/cgen.nim @@ -271,7 +271,7 @@ proc resetLoc(p: BProc, loc: var TLoc) = genObjectInit(p, cpsStmts, loc.t, loc, true) proc constructLoc(p: BProc, loc: TLoc, section = cpsStmts) = - if not isComplexValueType(skipTypes(loc.t, abstractVarRange)): + if not isComplexValueType(skipTypes(loc.t, abstractRange)): lineF(p, section, "$1 = 0;$n", [rdLoc(loc)]) else: lineF(p, section, "memset((void*)$1, 0, sizeof($2));$n", diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim index 2c98d9de6..2b39f6190 100755 --- a/compiler/semexprs.nim +++ b/compiler/semexprs.nim @@ -125,44 +125,48 @@ proc semSym(c: PContext, n: PNode, s: PSym, flags: TExprFlags): PNode = else: markUsed(n, s) result = newSymNode(s, n.info) - -proc checkConversionBetweenObjects(info: TLineInfo, castDest, src: PType) = - var diff = inheritanceDiff(castDest, src) - if diff == high(int): - LocalError(info, errGenerated, MsgKindToString(errIllegalConvFromXtoY) % [ - src.typeToString, castDest.typeToString]) + +type + TConvStatus = enum + convOK, + convNotNeedeed, + convNotLegal + +proc checkConversionBetweenObjects(castDest, src: PType): TConvStatus = + return if inheritanceDiff(castDest, src) == high(int): + convNotLegal + else: + convOK const IntegralTypes = {tyBool, tyEnum, tyChar, tyInt..tyUInt64} -proc checkConvertible(info: TLineInfo, castDest, src: PType) = - if sameType(castDest, src) and castDest.sym == src.sym: +proc checkConvertible(castDest, src: PType): TConvStatus = + result = convOK + if sameType(castDest, src) and castDest.sym == src.sym: # don't annoy conversions that may be needed on another processor: if castDest.kind notin IntegralTypes+{tyRange}: - Message(info, hintConvFromXtoItselfNotNeeded, typeToString(castDest)) + result = convNotNeedeed return var d = skipTypes(castDest, abstractVar) var s = skipTypes(src, abstractVar) - while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind): + while (d != nil) and (d.Kind in {tyPtr, tyRef}) and (d.Kind == s.Kind): d = base(d) s = base(s) if d == nil: - LocalError(info, errGenerated, msgKindToString(errIllegalConvFromXtoY) % [ - src.typeToString, castDest.typeToString]) - elif d.Kind == tyObject and s.Kind == tyObject: - checkConversionBetweenObjects(info, d, s) + result = convNotLegal + elif d.Kind == tyObject and s.Kind == tyObject: + result = checkConversionBetweenObjects(d, s) elif (skipTypes(castDest, abstractVarRange).Kind in IntegralTypes) and - (skipTypes(src, abstractVarRange).Kind in IntegralTypes): + (skipTypes(src, abstractVarRange).Kind in IntegralTypes): # accept conversion between integral types - else: + else: # we use d, s here to speed up that operation a bit: case cmpTypes(d, s) - of isNone, isGeneric: + of isNone, isGeneric: if not compareTypes(castDest, src, dcEqIgnoreDistinct): - LocalError(info, errGenerated, `%`( - MsgKindToString(errIllegalConvFromXtoY), - [typeToString(src), typeToString(castDest)])) - else: + result = convNotLegal + else: nil proc isCastable(dst, src: PType): bool = @@ -184,23 +188,32 @@ proc isCastable(dst, src: PType): bool = (skipTypes(src, abstractInst).kind in IntegralTypes) proc isSymChoice(n: PNode): bool {.inline.} = - result = n.kind in {nkClosedSymChoice, nkOpenSymChoice} + result = n.kind in nkSymChoices -proc semConv(c: PContext, n: PNode, s: PSym): PNode = - if sonsLen(n) != 2: +proc semConv(c: PContext, n: PNode, s: PSym): PNode = + if sonsLen(n) != 2: LocalError(n.info, errConvNeedsOneArg) return n result = newNodeI(nkConv, n.info) - result.typ = semTypeNode(c, n.sons[0], nil) + result.typ = semTypeNode(c, n.sons[0], nil).skipTypes({tyGenericInst}) addSon(result, copyTree(n.sons[0])) addSon(result, semExprWithType(c, n.sons[1])) var op = result.sons[1] + if not isSymChoice(op): - checkConvertible(result.info, result.typ, op.typ) - else: + let status = checkConvertible(result.typ, op.typ) + case status + of convOK: nil + of convNotNeedeed: + Message(n.info, hintConvFromXtoItselfNotNeeded, result.typ.typeToString) + of convNotLegal: + LocalError(n.info, errGenerated, MsgKindToString(errIllegalConvFromXtoY)% + [op.typ.typeToString, result.typ.typeToString]) + else: for i in countup(0, sonsLen(op) - 1): let it = op.sons[i] - if sameType(result.typ, it.typ): + let status = checkConvertible(result.typ, it.typ) + if status == convOK: markUsed(n, it.sym) markIndirect(c, it.sym) return it @@ -492,12 +505,16 @@ proc analyseIfAddressTaken(c: PContext, n: PNode): PNode = result = newHiddenAddrTaken(c, n) # BUGFIX! proc analyseIfAddressTakenInCall(c: PContext, n: PNode) = + checkMinSonsLen(n, 1) const FakeVarParams = {mNew, mNewFinalize, mInc, ast.mDec, mIncl, mExcl, mSetLengthStr, mSetLengthSeq, mAppendStrCh, mAppendStrStr, mSwap, mAppendSeqElem, mNewSeq, mReset, mShallowCopy} - checkMinSonsLen(n, 1) - var t = n.sons[0].typ + + # get the real type of the callee + # it may be a proc var with a generic alias type, so we skip over them + var t = n.sons[0].typ.skipTypes({tyGenericInst}) + if n.sons[0].kind == nkSym and n.sons[0].sym.magic in FakeVarParams: # BUGFIX: check for L-Value still needs to be done for the arguments! for i in countup(1, sonsLen(n) - 1): @@ -618,7 +635,8 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = semOpAux(c, n) var t: PType = nil if (n.sons[0].typ != nil): t = skipTypes(n.sons[0].typ, abstractInst) - if (t != nil) and (t.kind == tyProc): + if (t != nil) and (t.kind == tyProc): + # This is a proc variable, apply normal overload resolution var m: TCandidate initCandidate(m, t) matches(c, n, nOrig, m) @@ -648,6 +666,10 @@ proc semIndirectOp(c: PContext, n: PNode, flags: TExprFlags): PNode = # we assume that a procedure that calls something indirectly # has side-effects: if tfNoSideEffect notin t.flags: incl(c.p.owner.flags, sfSideEffect) + elif (t != nil) and t.kind == tyTypeDesc: + let destType = t.skipTypes({tyTypeDesc, tyGenericInst}) + result = semConv(c, n, symFromType(destType, n.info)) + return else: result = overloadedCallOpr(c, n) # Now that nkSym does not imply an iteration over the proc/iterator space, @@ -956,10 +978,10 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode = result.typ = elemType(arr) #GlobalError(n.info, errIndexTypesDoNotMatch) of tyTypeDesc: - result = n.sons[0] # The result so far is a tyTypeDesc bound to - # a tyGenericBody. The line below will substitute - # it with the instantiated type. - result.typ.sons[0] = semTypeNode(c, n, nil).linkTo(result.sym) + # The result so far is a tyTypeDesc bound + # a tyGenericBody. The line below will substitute + # it with the instantiated type. + result = symNodeFromType(c, semTypeNode(c, n, nil), n.info) of tyTuple: checkSonsLen(n, 2) n.sons[0] = makeDeref(n.sons[0]) @@ -1715,12 +1737,10 @@ proc semExpr(c: PContext, n: PNode, flags: TExprFlags = {}): PNode = of nkTableConstr: result = semTableConstr(c, n) of nkClosedSymChoice, nkOpenSymChoice: - LocalError(n.info, errExprXAmbiguous, renderTree(n, {renderNoComments})) - # error correction: Pick first element: - result = n.sons[0] + # handling of sym choices is context dependent + # the node is left intact for now of nkStaticExpr: result = semStaticExpr(c, n) - of nkAsgn: result = semAsgn(c, n) of nkBlockStmt: result = semBlock(c, n) of nkStmtList: result = semStmtList(c, n) diff --git a/compiler/sigmatch.nim b/compiler/sigmatch.nim index f1920a255..a9753f97d 100755 --- a/compiler/sigmatch.nim +++ b/compiler/sigmatch.nim @@ -685,8 +685,8 @@ proc ParamTypesMatchAux(c: PContext, m: var TCandidate, f, a: PType, result = userConvMatch(c, m, base(f), a, arg) proc ParamTypesMatch(c: PContext, m: var TCandidate, f, a: PType, - arg, argOrig: PNode): PNode = - if arg == nil or arg.kind != nkClosedSymChoice: + arg, argOrig: PNode): PNode = + if arg == nil or arg.kind notin nkSymChoices: result = ParamTypesMatchAux(c, m, f, a, arg, argOrig) else: # CAUTION: The order depends on the used hashing scheme. Thus it is |