diff options
author | Zahary Karadjov <zahary@gmail.com> | 2012-06-02 19:52:06 +0300 |
---|---|---|
committer | Zahary Karadjov <zahary@gmail.com> | 2012-06-02 19:52:06 +0300 |
commit | 88f7b7bc500325cc7399022c3dc137539d0f2640 (patch) | |
tree | d9e0d97895dc413b52c3eb9f9b523618fe76bfdc /compiler | |
parent | a1da1f987b28ed041c3f3ad2317e756e2125aa30 (diff) | |
parent | 232ab71f208e341da327e54afa8a6d287141836b (diff) | |
download | Nim-88f7b7bc500325cc7399022c3dc137539d0f2640.tar.gz |
Merge branch 'master' of github.com:Araq/Nimrod into upstream
Diffstat (limited to 'compiler')
-rwxr-xr-x | compiler/ast.nim | 3 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 15 | ||||
-rwxr-xr-x | compiler/ccgexprs.nim | 36 | ||||
-rwxr-xr-x | compiler/ccgstmts.nim | 31 | ||||
-rwxr-xr-x | compiler/ccgtypes.nim | 11 | ||||
-rwxr-xr-x | compiler/ccgutils.nim | 9 | ||||
-rwxr-xr-x | compiler/ecmasgen.nim | 3 | ||||
-rwxr-xr-x | compiler/evals.nim | 2 | ||||
-rwxr-xr-x | compiler/lookups.nim | 21 | ||||
-rwxr-xr-x | compiler/renderer.nim | 2 | ||||
-rwxr-xr-x | compiler/semgnrc.nim | 2 | ||||
-rwxr-xr-x | compiler/semstmts.nim | 8 | ||||
-rwxr-xr-x | compiler/transf.nim | 6 | ||||
-rwxr-xr-x | compiler/types.nim | 13 |
14 files changed, 111 insertions, 51 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index c59c47453..d9ec70450 100755 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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, diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index f2fa6a280..17139f055 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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)) diff --git a/compiler/ccgexprs.nim b/compiler/ccgexprs.nim index eb20153fc..7a0face5e 100755 --- a/compiler/ccgexprs.nim +++ b/compiler/ccgexprs.nim @@ -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", diff --git a/compiler/ccgstmts.nim b/compiler/ccgstmts.nim index db6d5bd67..46e4f75df 100755 --- a/compiler/ccgstmts.nim +++ b/compiler/ccgstmts.nim @@ -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 & ')') diff --git a/compiler/ccgtypes.nim b/compiler/ccgtypes.nim index 1b3e84cc4..4492c2fea 100755 --- a/compiler/ccgtypes.nim +++ b/compiler/ccgtypes.nim @@ -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) = diff --git a/compiler/ccgutils.nim b/compiler/ccgutils.nim index 12795358a..5ba523070 100755 --- a/compiler/ccgutils.nim +++ b/compiler/ccgutils.nim @@ -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 diff --git a/compiler/ecmasgen.nim b/compiler/ecmasgen.nim index 9c9c01734..07754ee13 100755 --- a/compiler/ecmasgen.nim +++ b/compiler/ecmasgen.nim @@ -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) diff --git a/compiler/evals.nim b/compiler/evals.nim index 002fed194..5c77a4d94 100755 --- a/compiler/evals.nim +++ b/compiler/evals.nim @@ -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) diff --git a/compiler/lookups.nim b/compiler/lookups.nim index 62f4a3391..d9725eedf 100755 --- a/compiler/lookups.nim +++ b/compiler/lookups.nim @@ -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)) diff --git a/compiler/renderer.nim b/compiler/renderer.nim index 67b657657..a5e79762c 100755 --- a/compiler/renderer.nim +++ b/compiler/renderer.nim @@ -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) diff --git a/compiler/semgnrc.nim b/compiler/semgnrc.nim index d8f017c4c..f7e64bdee 100755 --- a/compiler/semgnrc.nim +++ b/compiler/semgnrc.nim @@ -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) diff --git a/compiler/semstmts.nim b/compiler/semstmts.nim index 943c49bad..82f43e787 100755 --- a/compiler/semstmts.nim +++ b/compiler/semstmts.nim @@ -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) diff --git a/compiler/transf.nim b/compiler/transf.nim index 9e0d4051f..0ab8bc8d3 100755 --- a/compiler/transf.nim +++ b/compiler/transf.nim @@ -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)) diff --git a/compiler/types.nim b/compiler/types.nim index 633524eff..2f201b9de 100755 --- a/compiler/types.nim +++ b/compiler/types.nim @@ -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: |