Merge branch 'master' of github.com:Araq/Nimrod into upstream

This commit is contained in:
Zahary Karadjov 2012-06-02 19:52:06 +03:00
commit 88f7b7bc50
31 changed files with 459 additions and 114 deletions

View file

@ -145,6 +145,7 @@ type
nkIfStmt, # an if statement
nkWhenStmt, # a when expression or statement
nkForStmt, # a for statement
nkParForStmt, # a parallel for statement
nkWhileStmt, # a while statement
nkCaseStmt, # a case statement
nkTypeSection, # a type section (consists of type definitions)
@ -396,7 +397,7 @@ type
mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet,
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
mConTArr, mConTT, mSlice,
mFields, mFieldPairs,
mFields, mFieldPairs, mOmpParFor,
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
mInRange, mInSet, mRepr, mExit, mSetLengthStr, mSetLengthSeq,
mIsPartOf, mAstToStr, mRand,

View file

@ -20,7 +20,8 @@ proc hasNoInit(call: PNode): bool {.inline.} =
proc fixupCall(p: BProc, le, ri: PNode, d: var TLoc, pl: PRope) =
var pl = pl
var typ = ri.sons[0].typ # getUniqueType() is too expensive here!
# 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, ", ")
@ -124,7 +125,8 @@ proc genPrefixCall(p: BProc, le, ri: PNode, d: var TLoc) =
# this is a hotspot in the compiler
initLocExpr(p, ri.sons[0], op)
var pl = con(op.r, "(")
var typ = ri.sons[0].typ # getUniqueType() is too expensive here!
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
for i in countup(1, length - 1):
@ -150,7 +152,8 @@ proc genClosureCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op: TLoc
initLocExpr(p, ri.sons[0], op)
var pl: PRope
var typ = ri.sons[0].typ
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
for i in countup(1, length - 1):
@ -201,7 +204,8 @@ proc genInfixCall(p: BProc, le, ri: PNode, d: var TLoc) =
var op, a: TLoc
initLocExpr(p, ri.sons[0], op)
var pl: PRope = nil
var typ = ri.sons[0].typ # getUniqueType() is too expensive here!
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
assert(sonsLen(typ) == sonsLen(typ.n))
@ -228,7 +232,8 @@ proc genNamedParamCall(p: BProc, ri: PNode, d: var TLoc) =
var op, a: TLoc
initLocExpr(p, ri.sons[0], op)
var pl = toRope"["
var typ = ri.sons[0].typ # getUniqueType() is too expensive here!
# getUniqueType() is too expensive here:
var typ = skipTypes(ri.sons[0].typ, abstractInst)
assert(typ.kind == tyProc)
var length = sonsLen(ri)
assert(sonsLen(typ) == sonsLen(typ.n))

View file

@ -283,7 +283,7 @@ proc genAssignment(p: BProc, dest, src: TLoc, flags: TAssignmentFlags) =
proc expr(p: BProc, e: PNode, d: var TLoc)
proc initLocExpr(p: BProc, e: PNode, result: var TLoc) =
initLoc(result, locNone, getUniqueType(e.typ), OnUnknown)
initLoc(result, locNone, e.typ, OnUnknown)
expr(p, e, result)
proc getDestLoc(p: BProc, d: var TLoc, typ: PType) =
@ -543,17 +543,17 @@ proc genAddr(p: BProc, e: PNode, d: var TLoc) =
proc genRecordFieldAux(p: BProc, e: PNode, d, a: var TLoc): PType =
initLocExpr(p, e.sons[0], a)
if (e.sons[1].kind != nkSym): InternalError(e.info, "genRecordFieldAux")
if e.sons[1].kind != nkSym: InternalError(e.info, "genRecordFieldAux")
if d.k == locNone: d.s = a.s
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
result = getUniqueType(a.t)
result = a.t
proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
var a: TLoc
var ty = genRecordFieldAux(p, e, d, a)
var r = rdLoc(a)
var f = e.sons[1].sym
if ty.n == nil:
if ty.kind == tyTuple:
# we found a unique tuple type which lacks field information
# so we use Field$i
appf(r, ".Field$1", [toRope(f.position)])
@ -561,14 +561,14 @@ proc genRecordField(p: BProc, e: PNode, d: var TLoc) =
else:
var field: PSym = nil
while ty != nil:
if not (ty.kind in {tyTuple, tyObject}):
if ty.kind notin {tyTuple, tyObject}:
InternalError(e.info, "genRecordField")
field = lookupInRecord(ty.n, f.name)
if field != nil: break
if gCmd != cmdCompileToCpp: app(r, ".Sup")
ty = GetUniqueType(ty.sons[0])
if field == nil: InternalError(e.info, "genRecordField")
if field.loc.r == nil: InternalError(e.info, "genRecordField")
if field == nil: InternalError(e.info, "genRecordField 2 ")
if field.loc.r == nil: InternalError(e.info, "genRecordField 3")
appf(r, ".$1", [field.loc.r])
putIntoDest(p, d, field.typ, r)
@ -579,16 +579,17 @@ proc genTupleElem(p: BProc, e: PNode, d: var TLoc) =
initLocExpr(p, e.sons[0], a)
if d.k == locNone: d.s = a.s
discard getTypeDesc(p.module, a.t) # fill the record's fields.loc
var ty = getUniqueType(a.t)
var ty = a.t
var r = rdLoc(a)
case e.sons[1].kind
of nkIntLit..nkInt64Lit: i = int(e.sons[1].intVal)
else: internalError(e.info, "genTupleElem")
if ty.n != nil:
var field = ty.n.sons[i].sym
if field == nil: InternalError(e.info, "genTupleElem")
if field.loc.r == nil: InternalError(e.info, "genTupleElem")
appf(r, ".$1", [field.loc.r])
when false:
if ty.n != nil:
var field = ty.n.sons[i].sym
if field == nil: InternalError(e.info, "genTupleElem")
if field.loc.r == nil: InternalError(e.info, "genTupleElem")
appf(r, ".$1", [field.loc.r])
else:
appf(r, ".Field$1", [toRope(i)])
putIntoDest(p, d, ty.sons[i], r)
@ -1510,11 +1511,10 @@ proc genTupleConstr(p: BProc, n: PNode, d: var TLoc) =
for i in countup(0, sonsLen(n) - 1):
var it = n.sons[i]
if it.kind == nkExprColonExpr: it = it.sons[1]
if t.n == nil:
initLoc(rec, locExpr, it.typ, d.s)
rec.r = ropef("$1.Field$2", [rdLoc(d), toRope(i)])
expr(p, it, rec)
else:
initLoc(rec, locExpr, it.typ, d.s)
rec.r = ropef("$1.Field$2", [rdLoc(d), toRope(i)])
expr(p, it, rec)
when false:
initLoc(rec, locExpr, it.typ, d.s)
if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genTupleConstr")
rec.r = ropef("$1.$2",

View file

@ -32,7 +32,7 @@ proc genVarTuple(p: BProc, n: PNode) =
assignLocalVar(p, v)
initLocalVar(p, v, immediateAsgn=true)
initLoc(field, locExpr, t.sons[i], tup.s)
if t.n == nil:
if t.kind == tyTuple:
field.r = ropef("$1.Field$2", [rdLoc(tup), toRope(i)])
else:
if (t.n.sons[i].kind != nkSym): InternalError(n.info, "genVarTuple")
@ -258,6 +258,34 @@ proc genBlock(p: BProc, t: PNode, d: var TLoc) =
else: genStmts(p, t.sons[1])
endBlock(p)
proc genParForStmt(p: BProc, t: PNode) =
assert(sonsLen(t) == 3)
inc(p.withinLoop)
genLineDir(p, t)
preserveBreakIdx:
let forLoopVar = t.sons[0].sym
var rangeA, rangeB: TLoc
assignLocalVar(P, forLoopVar)
#initLoc(forLoopVar.loc, locLocalVar, forLoopVar.typ, onStack)
#discard mangleName(forLoopVar)
let call = t.sons[1]
initLocExpr(p, call.sons[1], rangeA)
initLocExpr(p, call.sons[2], rangeB)
appf(p.s(cpsStmts), "#pragma omp parallel for $4$n" &
"for ($1 = $2; $1 <= $3; ++$1)",
forLoopVar.loc.rdLoc,
rangeA.rdLoc, rangeB.rdLoc,
call.sons[3].getStr.toRope)
p.breakIdx = startBlock(p)
p.blocks[p.breakIdx].isLoop = true
genStmts(p, t.sons[2])
endBlock(p)
dec(p.withinLoop)
proc genBreakStmt(p: BProc, t: PNode) =
var idx = p.breakIdx
if t.sons[0].kind != nkEmpty:
@ -815,5 +843,6 @@ proc genStmts(p: BProc, t: PNode) =
# we have not only the header:
if prc.getBody.kind != nkEmpty or lfDynamicLib in prc.loc.flags:
genProc(p.module, prc)
of nkParForStmt: genParForStmt(p, t)
else: internalError(t.info, "genStmts(" & $t.kind & ')')

View file

@ -144,7 +144,7 @@ proc mapSetType(typ: PType): TCTypeKind =
proc mapType(typ: PType): TCTypeKind =
case typ.kind
of tyNone: result = ctVoid
of tyNone, tyStmt: result = ctVoid
of tyBool: result = ctBool
of tyChar: result = ctChar
of tySet: result = mapSetType(typ)
@ -561,7 +561,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
appf(m.s[cfsForwardTypes], getForwardStructFormat(), [result])
IdTablePut(m.forwTypeCache, t, result)
IdTablePut(m.typeCache, t, result) # always call for sideeffects:
if t.n != nil: recdesc = getRecordDesc(m, t, result, check)
if t.kind != tyTuple: recdesc = getRecordDesc(m, t, result, check)
else: recdesc = getTupleDesc(m, t, result, check)
if not isImportedType(t): app(m.s[cfsTypes], recdesc)
of tySet:
@ -889,8 +889,11 @@ proc genTypeInfo(m: BModule, typ: PType): PRope =
of tyEnum: genEnumInfo(gNimDat, t, result)
of tyObject: genObjectInfo(gNimDat, t, result)
of tyTuple:
if t.n != nil: genObjectInfo(gNimDat, t, result)
else: genTupleInfo(gNimDat, t, result)
# if t.n != nil: genObjectInfo(gNimDat, t, result)
# else:
# BUGFIX: use consistently RTTI without proper field names; otherwise
# results are not deterministic!
genTupleInfo(gNimDat, t, result)
else: InternalError("genTypeInfo(" & $t.kind & ')')
proc genTypeSection(m: BModule, n: PNode) =

View file

@ -87,14 +87,19 @@ proc GetUniqueType*(key: PType): PType =
of tyGenericInst, tyDistinct, tyOrdinal, tyMutable, tyConst, tyIter:
result = GetUniqueType(lastSon(key))
of tyArrayConstr, tyGenericInvokation, tyGenericBody,
tyOpenArray, tyArray, tyTuple, tySet, tyRange,
tyOpenArray, tyArray, tySet, tyRange, tyTuple,
tyPtr, tyRef, tySequence, tyForward, tyVarargs, tyProxy, tyVar:
# tuples are quite horrible as C does not support them directly and
# tuple[string, string] is a (strange) subtype of
# tuple[nameA, nameB: string]. This bites us here, so we
# use 'sameBackendType' instead of 'sameType'.
# we have to do a slow linear search because types may need
# to be compared by their structure:
if IdTableHasObjectAsKey(gTypeTable[k], key): return key
for h in countup(0, high(gTypeTable[k].data)):
var t = PType(gTypeTable[k].data[h].key)
if t != nil and sameType(t, key):
if t != nil and sameBackendType(t, key):
return t
IdTablePut(gTypeTable[k], key, key)
result = key

View file

@ -1343,7 +1343,8 @@ proc genStmt(p: var TProc, n: PNode, r: var TCompRes) =
of nkWhileStmt: genWhileStmt(p, n, r)
of nkVarSection, nkLetSection: genVarStmt(p, n, r)
of nkConstSection: genConstStmt(p, n, r)
of nkForStmt: internalError(n.info, "for statement not eliminated")
of nkForStmt, nkParForStmt:
internalError(n.info, "for statement not eliminated")
of nkCaseStmt: genCaseStmt(p, n, r)
of nkReturnStmt: genReturnStmt(p, n, r)
of nkBreakStmt: genBreakStmt(p, n, r)

View file

@ -1331,7 +1331,7 @@ proc evalAux(c: PEvalContext, n: PNode, flags: TEvalFlags): PNode =
of nkPragmaBlock:
result = evalAux(c, n.sons[1], flags)
of nkIdentDefs, nkCast, nkYieldStmt, nkAsmStmt, nkForStmt, nkPragmaExpr,
nkLambdaKinds, nkContinueStmt, nkIdent:
nkLambdaKinds, nkContinueStmt, nkIdent, nkParForStmt:
result = raiseCannotEval(c, n.info)
of nkRefTy:
result = evalAux(c, n.sons[0], flags)

View file

@ -21,18 +21,19 @@ proc considerAcc*(n: PNode): PIdent =
case n.len
of 0: GlobalError(n.info, errIdentifierExpected, renderTree(n))
of 1: result = considerAcc(n.sons[0])
of 2:
if n[0].ident.id == ord(wStar):
else:
if n.len == 2 and n[0].kind == nkIdent and n[0].ident.id == ord(wStar):
# XXX find a better way instead of `*x` for 'genSym'
result = genSym(n[1].ident.s)
else:
result = getIdent(n[0].ident.s & n[1].ident.s)
else:
var id = ""
for i in 0.. <n.len:
if n.sons[i].kind != nkIdent:
GlobalError(n.info, errIdentifierExpected, renderTree(n))
id.add(n.sons[i].ident.s)
result = getIdent(id)
var id = ""
for i in 0.. <n.len:
let x = n.sons[i]
case x.kind
of nkIdent: id.add(x.ident.s)
of nkSym: id.add(x.sym.name.s)
else: GlobalError(n.info, errIdentifierExpected, renderTree(n))
result = getIdent(id)
else:
GlobalError(n.info, errIdentifierExpected, renderTree(n))

View file

@ -984,7 +984,7 @@ proc gsub(g: var TSrcGen, n: PNode, c: TContext) =
of nkCaseStmt, nkRecCase: gcase(g, n)
of nkMacroStmt: gmacro(g, n)
of nkTryStmt: gtry(g, n)
of nkForStmt: gfor(g, n)
of nkForStmt, nkParForStmt: gfor(g, n)
of nkBlockStmt, nkBlockExpr: gblock(g, n)
of nkStaticStmt: gstaticStmt(g, n)
of nkAsmStmt: gasm(g, n)

View file

@ -142,7 +142,7 @@ proc semGenericStmt(c: PContext, n: PNode,
a.sons[j] = semGenericStmt(c, a.sons[j], flags, toBind)
a.sons[L - 1] = semGenericStmtScope(c, a.sons[L-1], flags, toBind)
closeScope(c.tab)
of nkForStmt:
of nkForStmt, nkParForStmt:
var L = sonsLen(n)
openScope(c.tab)
n.sons[L - 2] = semGenericStmt(c, n.sons[L-2], flags, toBind)

View file

@ -465,7 +465,11 @@ proc semFor(c: PContext, n: PNode): PNode =
else:
GlobalError(n.sons[length - 2].info, errIteratorExpected)
elif call.sons[0].sym.magic != mNone:
result = semForFields(c, n, call.sons[0].sym.magic)
if call.sons[0].sym.magic == mOmpParFor:
result = semForVars(c, n)
result.kind = nkParForStmt
else:
result = semForFields(c, n, call.sons[0].sym.magic)
else:
result = semForVars(c, n)
closeScope(c.tab)
@ -979,7 +983,7 @@ proc SemStmt(c: PContext, n: PNode): PNode =
of nkWhileStmt: result = semWhile(c, n)
of nkTryStmt: result = semTry(c, n)
of nkBreakStmt, nkContinueStmt: result = semBreakOrContinue(c, n)
of nkForStmt: result = semFor(c, n)
of nkForStmt, nkParForStmt: result = semFor(c, n)
of nkCaseStmt: result = semCase(c, n)
of nkReturnStmt: result = semReturn(c, n)
of nkAsmStmt: result = semAsm(c, n)

View file

@ -247,7 +247,7 @@ proc transformConstSection(c: PTransf, v: PNode): PTransNode =
proc hasContinue(n: PNode): bool =
case n.kind
of nkEmpty..nkNilLit, nkForStmt, nkWhileStmt: nil
of nkEmpty..nkNilLit, nkForStmt, nkParForStmt, nkWhileStmt: nil
of nkContinueStmt: result = true
else:
for i in countup(0, sonsLen(n) - 1):
@ -659,6 +659,10 @@ proc transform(c: PTransf, n: PNode): PTransNode =
inc c.inLoop
result = transformFor(c, n)
dec c.inLoop
of nkParForStmt:
inc c.inLoop
result = transformSons(c, n)
dec c.inLoop
of nkCaseStmt: result = transformCase(c, n)
of nkContinueStmt:
result = PTransNode(newNode(nkBreakStmt))

View file

@ -550,6 +550,7 @@ type
TSameTypeClosure = object {.pure.}
cmp: TDistinctCompare
ignoreTupleFields: bool
recCheck: int
s: seq[tuple[a,b: int]] # seq for a set as it's hopefully faster
# (few elements expected)
@ -645,7 +646,7 @@ proc sameTuple(a, b: PType, c: var TSameTypeClosure): bool =
for i in countup(0, sonsLen(a) - 1):
result = SameTypeAux(a.sons[i], b.sons[i], c)
if not result: return
if a.n != nil and b.n != nil:
if a.n != nil and b.n != nil and not c.ignoreTupleFields:
for i in countup(0, sonsLen(a.n) - 1):
# check field names:
if a.n.sons[i].kind != nkSym: InternalError(a.n.info, "sameTuple")
@ -787,6 +788,11 @@ proc SameType*(x, y: PType): bool =
var c = initSameTypeClosure()
result = sameTypeAux(x, y, c)
proc sameBackendType*(x, y: PType): bool =
var c = initSameTypeClosure()
c.ignoreTupleFields = true
result = sameTypeAux(x, y, c)
proc compareTypes*(x, y: PType, cmp: TDistinctCompare): bool =
## compares two type for equality (modulo type distinction)
var c = initSameTypeClosure()
@ -863,8 +869,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind): bool =
result = typeAllowedAux(marker, t.sons[0], skResult)
of tyExpr, tyStmt, tyTypeDesc:
result = true
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation, tyTypeClass:
result = false #InternalError('shit found');
of tyGenericBody, tyGenericParam, tyForward, tyNone, tyGenericInvokation,
tyTypeClass:
result = false
of tyEmpty, tyNil:
result = kind == skConst
of tyString, tyBool, tyChar, tyEnum, tyInt..tyBigNum, tyCString, tyPointer: