Merge branch 'devel' of gh:/Araq/Nimrod into devel

This commit is contained in:
Zahary Karadjov 2014-02-15 20:46:54 +02:00
commit f701ee086a
30 changed files with 240 additions and 76 deletions

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -42,17 +42,23 @@ proc compilerMsgHandler(filename: string, line, col: int,
of mwUnsupportedLanguage: k = warnLanguageXNotSupported
globalError(newLineInfo(filename, line, col), k, arg)
proc docgenFindFile(s: string): string {.procvar.} =
result = options.findFile(s)
if result.len == 0:
result = getCurrentDir() / s
if not existsFile(result): result = ""
proc parseRst(text, filename: string,
line, column: int, hasToc: var bool,
rstOptions: TRstParseOptions): PRstNode =
result = rstParse(text, filename, line, column, hasToc, rstOptions,
options.findFile, compilerMsgHandler)
docgenFindFile, compilerMsgHandler)
proc newDocumentor*(filename: string, config: PStringTable): PDoc =
new(result)
initRstGenerator(result[], (if gCmd != cmdRst2tex: outHtml else: outLatex),
options.gConfigVars, filename, {roSupportRawDirective},
options.findFile, compilerMsgHandler)
docgenFindFile, compilerMsgHandler)
result.id = 100
proc dispA(dest: var PRope, xml, tex: string, args: openArray[PRope]) =

View file

@ -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

View file

@ -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))

View file

@ -17,4 +17,6 @@ import:testability
cincludes: "$lib/wrappers/libffi/common"
@end
define:useStdoutAsStdmsg
cs:partial

View file

@ -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)

View file

@ -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):
@ -477,7 +476,6 @@ proc track(tracked: PEffects, n: PNode) =
if warnProveField in gNotes: checkFieldAccess(tracked.guards, n)
of nkTryStmt: trackTryStmt(tracked, n)
of nkPragma: trackPragmaStmt(tracked, n)
of nkMacroDef, nkTemplateDef: discard
of nkAsgn, nkFastAsgn:
track(tracked, n.sons[1])
initVar(tracked, n.sons[0])
@ -527,7 +525,9 @@ proc track(tracked: PEffects, n: PNode) =
if sfDiscriminant in x.sons[0].sym.flags:
addDiscriminantFact(tracked.guards, x)
setLen(tracked.guards, oldFacts)
of nkTypeSection: discard
of nkTypeSection, nkProcDef, nkConverterDef, nkMethodDef, nkIteratorDef,
nkMacroDef, nkTemplateDef:
discard
else:
for i in 0 .. <safeLen(n): track(tracked, n.sons[i])
@ -581,22 +581,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 +623,12 @@ proc trackProc*(s: PSym, body: PNode) =
# after the check, use the formal spec:
effects.sons[tagEffects] = tagsSpec
proc trackTopLevelStmt*(module: PSym; n: PNode) =
if n.kind in {nkPragma, nkMacroDef, nkTemplateDef, nkProcDef,
nkTypeSection, nkConverterDef, nkMethodDef, nkIteratorDef}:
return
var effects = newNode(nkEffectList, n.info)
var t: TEffects
initEffects(effects, module, t)
track(t, n)

View file

@ -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):

View file

@ -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:

View file

@ -857,7 +857,7 @@ proc sameTypeAux(x, y: PType, c: var TSameTypeClosure): bool =
if a.kind != b.kind: return false
of dcEqOrDistinctOf:
while a.kind == tyDistinct: a = a.sons[0]
if a.kind != b.kind: return false
if a.kind != b.kind: return false
case a.kind
of tyEmpty, tyChar, tyBool, tyNil, tyPointer, tyString, tyCString,
tyInt..tyBigNum, tyStmt, tyExpr:

View file

@ -441,7 +441,7 @@ proc rawExecute(c: PCtx, start: int, tos: PStackFrame): PNode =
decodeBImm(nkIntLit)
#assert regs[rb].kind == nkBracket
# also used by mNLen:
regs[ra].intVal = regs[rb].skipMeta.len - imm
regs[ra].intVal = regs[rb].skipMeta.safeLen - imm
of opcLenStr:
decodeBImm(nkIntLit)
if regs[rb].kind == nkNilLit: