diff options
Diffstat (limited to 'compiler')
-rw-r--r-- | compiler/ccgexprs.nim | 2 | ||||
-rw-r--r-- | compiler/ccgtypes.nim | 2 | ||||
-rw-r--r-- | compiler/cgendata.nim | 3 | ||||
-rw-r--r-- | compiler/guards.nim | 42 | ||||
-rw-r--r-- | compiler/lookups.nim | 1 | ||||
-rw-r--r-- | compiler/nimrod.nimrod.cfg | 2 | ||||
-rw-r--r-- | compiler/sem.nim | 3 | ||||
-rw-r--r-- | compiler/sempass2.nim | 33 | ||||
-rw-r--r-- | compiler/semtypinst.nim | 3 | ||||
-rw-r--r-- | compiler/transf.nim | 1 |
10 files changed, 62 insertions, 30 deletions
diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index 01f23850b..27f7f4ba5 100644 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -593,7 +593,7 @@ proc unaryArith(p: BProc, e: PNode, d: var TLoc, op: TMagic) = proc genDeref(p: BProc, e: PNode, d: var TLoc) = var a: TLoc - if mapType(e.sons[0].typ) == ctArray: + if mapType(e.sons[0].typ) in {ctArray, ctPtrToArray}: # XXX the amount of hacks for C's arrays is incredible, maybe we should # simply wrap them in a struct? --> Losing auto vectorization then? expr(p, e.sons[0], d) diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index c92c15fa9..673e888fe 100644 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -185,7 +185,7 @@ proc mapType(typ: PType): TCTypeKind = of tyPtr, tyVar, tyRef: var base = skipTypes(typ.sons[0], typedescInst) case base.kind - of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctArray + of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctPtrToArray else: result = ctPtr of tyPointer: result = ctPtr of tySequence: result = ctNimSeq diff --git a/compiler/cgendata.nim b/compiler/cgendata.nim index 9cd2c0d87..0e1148343 100644 --- a/compiler/cgendata.nim +++ b/compiler/cgendata.nim @@ -41,7 +41,8 @@ type ctInt, ctInt8, ctInt16, ctInt32, ctInt64, ctFloat, ctFloat32, ctFloat64, ctFloat128, ctUInt, ctUInt8, ctUInt16, ctUInt32, ctUInt64, - ctArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, ctCString + ctArray, ctPtrToArray, ctStruct, ctPtr, ctNimStr, ctNimSeq, ctProc, + ctCString TCFileSections* = array[TCFileSection, PRope] # represents a generated C file TCProcSection* = enum # the sections a generated C proc consists of cpsLocals, # section of local variables for C proc diff --git a/compiler/guards.nim b/compiler/guards.nim index 607bb074a..fe868054f 100644 --- a/compiler/guards.nim +++ b/compiler/guards.nim @@ -9,7 +9,7 @@ ## This module implements the 'implies' relation for guards. -import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer +import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents const someEq = {mEqI, mEqI64, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc, @@ -69,9 +69,23 @@ proc isLetLocation(m: PNode, isApprox: bool): bool = proc interestingCaseExpr*(m: PNode): bool = isLetLocation(m, true) -proc swapArgs(fact: PNode, newOp: string, m: TMagic): PNode = +proc getMagicOp(name: string, m: TMagic): PSym = + result = newSym(skProc, getIdent(name), nil, unknownLineInfo()) + result.magic = m + +let + opLe = getMagicOp("<=", mLeI) + opLt = getMagicOp("<", mLtI) + opAnd = getMagicOp("and", mAnd) + opOr = getMagicOp("or", mOr) + opNot = getMagicOp("not", mNot) + opIsNil = getMagicOp("isnil", mIsNil) + opContains = getMagicOp("contains", mInSet) + opEq = getMagicOp("==", mEqI) + +proc swapArgs(fact: PNode, newOp: PSym): PNode = result = newNodeI(nkCall, fact.info, 3) - result.sons[0] = newSymNode(getSysMagic(newOp, m)) + result.sons[0] = newSymNode(newOp) result.sons[1] = fact.sons[2] result.sons[2] = fact.sons[1] @@ -82,9 +96,9 @@ proc neg(n: PNode): PNode = result = n.sons[1] of someLt: # not (a < b) == a >= b == b <= a - result = swapArgs(n, "<=", mLeI) + result = swapArgs(n, opLe) of someLe: - result = swapArgs(n, "<", mLtI) + result = swapArgs(n, opLt) of mInSet: if n.sons[1].kind != nkCurly: return nil let t = n.sons[2].typ.skipTypes(abstractInst) @@ -110,7 +124,7 @@ proc neg(n: PNode): PNode = b = n.sons[2].neg if a != nil and b != nil: result = newNodeI(nkCall, n.info, 3) - result.sons[0] = newSymNode(getSysMagic("and", mAnd)) + result.sons[0] = newSymNode(opAnd) result.sons[1] = a result.sons[2] = b elif a != nil: @@ -120,12 +134,12 @@ proc neg(n: PNode): PNode = else: # leave not (a == 4) as it is result = newNodeI(nkCall, n.info, 2) - result.sons[0] = newSymNode(getSysMagic("not", mNot)) + result.sons[0] = newSymNode(opNot) result.sons[1] = n proc buildIsNil(arg: PNode): PNode = result = newNodeI(nkCall, arg.info, 2) - result.sons[0] = newSymNode(getSysMagic("isNil", mIsNil)) + result.sons[0] = newSymNode(opIsNil) result.sons[1] = arg proc usefulFact(n: PNode): PNode = @@ -154,7 +168,7 @@ proc usefulFact(n: PNode): PNode = b = usefulFact(n.sons[2]) if a != nil and b != nil: result = newNodeI(nkCall, n.info, 3) - result.sons[0] = newSymNode(getSysMagic("and", mAnd)) + result.sons[0] = newSymNode(opAnd) result.sons[1] = a result.sons[2] = b elif a != nil: @@ -177,7 +191,7 @@ proc usefulFact(n: PNode): PNode = b = usefulFact(n.sons[2]).neg if a != nil and b != nil: result = newNodeI(nkCall, n.info, 3) - result.sons[0] = newSymNode(getSysMagic("and", mAnd)) + result.sons[0] = newSymNode(opAnd) result.sons[1] = a result.sons[2] = b result = result.neg @@ -520,7 +534,7 @@ proc buildOf(it, loc: PNode): PNode = s.typ = settype(loc) for i in 0..it.len-2: s.sons[i] = it.sons[i] result = newNodeI(nkCall, it.info, 3) - result.sons[0] = newSymNode(getSysMagic("contains", mInSet)) + result.sons[0] = newSymNode(opContains) result.sons[1] = s result.sons[2] = loc @@ -532,20 +546,20 @@ proc buildElse(n: PNode): PNode = for j in 0..branch.len-2: s.add(branch.sons[j]) result = newNodeI(nkCall, n.info, 3) - result.sons[0] = newSymNode(getSysMagic("contains", mInSet)) + result.sons[0] = newSymNode(opContains) result.sons[1] = s result.sons[2] = n.sons[0] proc addDiscriminantFact*(m: var TModel, n: PNode) = var fact = newNodeI(nkCall, n.info, 3) - fact.sons[0] = newSymNode(getSysMagic("==", mEqI)) + fact.sons[0] = newSymNode(opEq) fact.sons[1] = n.sons[0] fact.sons[2] = n.sons[1] m.add fact proc addAsgnFact*(m: var TModel, key, value: PNode) = var fact = newNodeI(nkCall, key.info, 3) - fact.sons[0] = newSymNode(getSysMagic("==", mEqI)) + fact.sons[0] = newSymNode(opEq) fact.sons[1] = key fact.sons[2] = value m.add fact diff --git a/compiler/lookups.nim b/compiler/lookups.nim index c31eb3121..93a7b7c72 100644 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -32,6 +32,7 @@ proc considerAcc*(n: PNode): PIdent = of nkSym: id.add(x.sym.name.s) else: globalError(n.info, errIdentifierExpected, renderTree(n)) result = getIdent(id) + of nkOpenSymChoice, nkClosedSymChoice: result = n.sons[0].sym.name else: globalError(n.info, errIdentifierExpected, renderTree(n)) diff --git a/compiler/nimrod.nimrod.cfg b/compiler/nimrod.nimrod.cfg index 657c47b28..cc27d9f36 100644 --- a/compiler/nimrod.nimrod.cfg +++ b/compiler/nimrod.nimrod.cfg @@ -17,4 +17,6 @@ import:testability cincludes: "$lib/wrappers/libffi/common" @end +define:useStdoutAsStdmsg + cs:partial diff --git a/compiler/sem.nim b/compiler/sem.nim index 845d4ae71..140687721 100644 --- a/compiler/sem.nim +++ b/compiler/sem.nim @@ -120,7 +120,8 @@ proc commonType*(x, y: PType): PType = if a.kind == tyObject and b.kind == tyObject: result = commonSuperclass(a, b) # this will trigger an error later: - if result.isNil: return x + if result.isNil or result == a: return x + if result == b: return y if k != tyNone: let r = result result = newType(k, r.owner) diff --git a/compiler/sempass2.nim b/compiler/sempass2.nim index fb266ae3a..fedf19c79 100644 --- a/compiler/sempass2.nim +++ b/compiler/sempass2.nim @@ -84,10 +84,10 @@ proc initVar(a: PEffects, n: PNode) = proc initVarViaNew(a: PEffects, n: PNode) = if n.kind != nkSym: return let s = n.sym - if {tfNeedsInit, tfNotNil} * s.typ.flags == {tfNotNil}: + if {tfNeedsInit, tfNotNil} * s.typ.flags <= {tfNotNil}: # 'x' is not nil, but that doesn't mean it's not nil children # are initialized: - initVarViaNew(a, n) + initVar(a, n) proc useVar(a: PEffects, n: PNode) = let s = n.sym @@ -466,8 +466,7 @@ proc track(tracked: PEffects, n: PNode) = mergeEffects(tracked, effectList.sons[exceptionEffects], n) mergeTags(tracked, effectList.sons[tagEffects], n) for i in 1 .. <len(n): trackOperand(tracked, n.sons[i], paramType(op, i)) - if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, - mNewSeq, mShallowCopy}: + if a.kind == nkSym and a.sym.magic in {mNew, mNewFinalize, mNewSeq}: # may not look like an assignment, but it is: initVarViaNew(tracked, n.sons[1]) for i in 0 .. <safeLen(n): @@ -581,22 +580,26 @@ proc setEffectsForProcType*(t: PType, n: PNode) = if not isNil(tagsSpec): effects.sons[tagEffects] = tagsSpec +proc initEffects(effects: PNode; s: PSym; t: var TEffects) = + newSeq(effects.sons, effectListLen) + effects.sons[exceptionEffects] = newNodeI(nkArgList, s.info) + effects.sons[tagEffects] = newNodeI(nkArgList, s.info) + + t.exc = effects.sons[exceptionEffects] + t.tags = effects.sons[tagEffects] + t.owner = s + t.init = @[] + t.guards = @[] + proc trackProc*(s: PSym, body: PNode) = var effects = s.typ.n.sons[0] internalAssert effects.kind == nkEffectList # effects already computed? if sfForward in s.flags: return if effects.len == effectListLen: return - newSeq(effects.sons, effectListLen) - effects.sons[exceptionEffects] = newNodeI(nkArgList, body.info) - effects.sons[tagEffects] = newNodeI(nkArgList, body.info) var t: TEffects - t.exc = effects.sons[exceptionEffects] - t.tags = effects.sons[tagEffects] - t.owner = s - t.init = @[] - t.guards = @[] + initEffects(effects, s, t) track(t, body) if not isEmptyType(s.typ.sons[0]) and tfNeedsInit in s.typ.sons[0].flags and @@ -619,3 +622,9 @@ proc trackProc*(s: PSym, body: PNode) = # after the check, use the formal spec: effects.sons[tagEffects] = tagsSpec +proc trackTopLevelStmt*(module: PSym; n: PNode) = + var effects = newNode(nkEffectList, n.info) + var t: TEffects + initEffects(effects, module, t) + + track(t, n) diff --git a/compiler/semtypinst.nim b/compiler/semtypinst.nim index a07d91241..73b618f46 100644 --- a/compiler/semtypinst.nim +++ b/compiler/semtypinst.nim @@ -153,6 +153,9 @@ proc replaceTypeVarsN(cl: var TReplTypeVars, n: PNode): PNode = discard of nkSym: result.sym = replaceTypeVarsS(cl, n.sym) + if result.sym.typ.kind == tyEmpty: + # don't add the 'void' field + result = newNode(nkRecList, n.info) of nkRecWhen: var branch: PNode = nil # the branch to take for i in countup(0, sonsLen(n) - 1): diff --git a/compiler/transf.nim b/compiler/transf.nim index deb821eff..0911950d0 100644 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -754,6 +754,7 @@ proc transformStmt*(module: PSym, n: PNode): PNode = result = processTransf(c, n, module) result = liftLambdasForTopLevel(module, result) incl(result.flags, nfTransf) + when useEffectSystem: trackTopLevelStmt(module, result) proc transformExpr*(module: PSym, n: PNode): PNode = if nfTransf in n.flags: |