Merge branch 'devel' of gh:/Araq/Nimrod into devel
This commit is contained in:
commit
f701ee086a
30 changed files with 240 additions and 76 deletions
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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]) =
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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))
|
||||
|
||||
|
|
|
|||
|
|
@ -17,4 +17,6 @@ import:testability
|
|||
cincludes: "$lib/wrappers/libffi/common"
|
||||
@end
|
||||
|
||||
define:useStdoutAsStdmsg
|
||||
|
||||
cs:partial
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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)
|
||||
|
|
|
|||
|
|
@ -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):
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
|
|
@ -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:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue