mirror of
https://github.com/nim-lang/Nim.git
synced 2026-07-19 07:21:19 +00:00
implemented region pointers
This commit is contained in:
@@ -780,7 +780,7 @@ proc genSeqElem(p: BProc, e: PNode, d: var TLoc) =
|
||||
initLocExpr(p, e.sons[1], b)
|
||||
var ty = skipTypes(a.t, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}:
|
||||
ty = skipTypes(ty.sons[0], abstractVarRange) # emit range check:
|
||||
ty = skipTypes(ty.lastSon, abstractVarRange) # emit range check:
|
||||
if optBoundsCheck in p.options:
|
||||
if ty.kind == tyString:
|
||||
linefmt(p, cpsStmts,
|
||||
@@ -1121,7 +1121,7 @@ proc genOf(p: BProc, x: PNode, typ: PType, d: var TLoc) =
|
||||
while t.kind in {tyVar, tyPtr, tyRef}:
|
||||
if t.kind != tyVar: nilCheck = r
|
||||
r = rfmt(nil, "(*$1)", r)
|
||||
t = skipTypes(t.sons[0], typedescInst)
|
||||
t = skipTypes(t.lastSon, typedescInst)
|
||||
if gCmd != cmdCompileToCpp:
|
||||
while (t.kind == tyObject) and (t.sons[0] != nil):
|
||||
app(r, ~".Sup")
|
||||
@@ -1737,7 +1737,7 @@ proc upConv(p: BProc, n: PNode, d: var TLoc) =
|
||||
while t.kind in {tyVar, tyPtr, tyRef}:
|
||||
if t.kind != tyVar: nilCheck = r
|
||||
r = ropef("(*$1)", [r])
|
||||
t = skipTypes(t.sons[0], abstractInst)
|
||||
t = skipTypes(t.lastSon, abstractInst)
|
||||
if gCmd != cmdCompileToCpp:
|
||||
while t.kind == tyObject and t.sons[0] != nil:
|
||||
app(r, ".Sup")
|
||||
@@ -1885,7 +1885,7 @@ proc expr(p: BProc, n: PNode, d: var TLoc) =
|
||||
of nkHiddenAddr, nkAddr: genAddr(p, n, d)
|
||||
of nkBracketExpr:
|
||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||
case ty.kind
|
||||
of tyArray, tyArrayConstr: genArrayElem(p, n, d)
|
||||
of tyOpenArray, tyVarargs: genOpenArrayElem(p, n, d)
|
||||
|
||||
@@ -183,7 +183,7 @@ proc mapType(typ: PType): TCTypeKind =
|
||||
else: internalError("mapType")
|
||||
of tyRange: result = mapType(typ.sons[0])
|
||||
of tyPtr, tyVar, tyRef:
|
||||
var base = skipTypes(typ.sons[0], typedescInst)
|
||||
var base = skipTypes(typ.lastSon, typedescInst)
|
||||
case base.kind
|
||||
of tyOpenArray, tyArrayConstr, tyArray, tyVarargs: result = ctPtrToArray
|
||||
else: result = ctPtr
|
||||
@@ -269,7 +269,7 @@ proc fillResult(param: PSym) =
|
||||
proc getParamTypeDesc(m: BModule, t: PType, check: var TIntSet): PRope =
|
||||
when false:
|
||||
if t.Kind in {tyRef, tyPtr, tyVar}:
|
||||
var b = skipTypes(t.sons[0], typedescInst)
|
||||
var b = skipTypes(t.lastson, typedescInst)
|
||||
if b.kind == tySet and mapSetType(b) == ctArray:
|
||||
return getTypeDescAux(m, b, check)
|
||||
result = getTypeDescAux(m, t, check)
|
||||
@@ -530,7 +530,7 @@ proc getTypeDescAux(m: BModule, typ: PType, check: var TIntSet): PRope =
|
||||
# C type generation into an analysis and a code generation phase somehow.
|
||||
case t.kind
|
||||
of tyRef, tyPtr, tyVar:
|
||||
et = getUniqueType(t.sons[0])
|
||||
et = getUniqueType(t.lastSon)
|
||||
if et.kind in {tyArrayConstr, tyArray, tyOpenArray, tyVarargs}:
|
||||
# this is correct! sets have no proper base type, so we treat
|
||||
# ``var set[char]`` in `getParamTypeDesc`
|
||||
|
||||
@@ -59,8 +59,8 @@ proc sameMethodBucket(a, b: PSym): bool =
|
||||
aa = skipTypes(aa, {tyGenericInst})
|
||||
bb = skipTypes(bb, {tyGenericInst})
|
||||
if (aa.kind == bb.kind) and (aa.kind in {tyVar, tyPtr, tyRef}):
|
||||
aa = aa.sons[0]
|
||||
bb = bb.sons[0]
|
||||
aa = aa.lastSon
|
||||
bb = bb.lastSon
|
||||
else:
|
||||
break
|
||||
if sameType(aa, bb) or
|
||||
|
||||
@@ -116,7 +116,7 @@ proc packSize(v: PNode, typ: PType): int =
|
||||
if v.kind in {nkNilLit, nkPtrLit}:
|
||||
result = sizeof(pointer)
|
||||
else:
|
||||
result = sizeof(pointer) + packSize(v.sons[0], typ.sons[0])
|
||||
result = sizeof(pointer) + packSize(v.sons[0], typ.lastSon)
|
||||
of tyDistinct, tyGenericInst:
|
||||
result = packSize(v, typ.sons[0])
|
||||
of tyArray, tyArrayConstr:
|
||||
@@ -219,7 +219,7 @@ proc pack(v: PNode, typ: PType, res: pointer) =
|
||||
packRecCheck = 0
|
||||
globalError(v.info, "cannot map value to FFI " & typeToString(v.typ))
|
||||
inc packRecCheck
|
||||
pack(v.sons[0], typ.sons[0], res +! sizeof(pointer))
|
||||
pack(v.sons[0], typ.lastSon, res +! sizeof(pointer))
|
||||
dec packRecCheck
|
||||
awr(pointer, res +! sizeof(pointer))
|
||||
of tyArray, tyArrayConstr:
|
||||
@@ -371,7 +371,7 @@ proc unpack(x: pointer, typ: PType, n: PNode): PNode =
|
||||
awi(nkPtrLit, cast[TAddress](p))
|
||||
elif n != nil and n.len == 1:
|
||||
internalAssert n.kind == nkRefTy
|
||||
n.sons[0] = unpack(p, typ.sons[0], n.sons[0])
|
||||
n.sons[0] = unpack(p, typ.lastSon, n.sons[0])
|
||||
result = n
|
||||
else:
|
||||
globalError(n.info, "cannot map value from FFI " & typeToString(typ))
|
||||
|
||||
@@ -111,7 +111,7 @@ proc mapType(typ: PType): TJSTypeKind =
|
||||
let t = skipTypes(typ, abstractInst)
|
||||
case t.kind
|
||||
of tyVar, tyRef, tyPtr:
|
||||
if skipTypes(t.sons[0], abstractInst).kind in MappedToObject:
|
||||
if skipTypes(t.lastSon, abstractInst).kind in MappedToObject:
|
||||
result = etyObject
|
||||
else:
|
||||
result = etyBaseIndex
|
||||
@@ -912,7 +912,7 @@ proc genArrayAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
|
||||
proc genArrayAccess(p: PProc, n: PNode, r: var TCompRes) =
|
||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||
case ty.kind
|
||||
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
||||
tyVarargs:
|
||||
@@ -957,7 +957,7 @@ proc genAddr(p: PProc, n: PNode, r: var TCompRes) =
|
||||
genFieldAddr(p, n, r)
|
||||
of nkBracketExpr:
|
||||
var ty = skipTypes(n.sons[0].typ, abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.sons[0], abstractVarRange)
|
||||
if ty.kind in {tyRef, tyPtr}: ty = skipTypes(ty.lastSon, abstractVarRange)
|
||||
case ty.kind
|
||||
of tyArray, tyArrayConstr, tyOpenArray, tySequence, tyString, tyCString,
|
||||
tyVarargs:
|
||||
|
||||
@@ -134,7 +134,7 @@ proc genTypeInfo(p: PProc, typ: PType): PRope =
|
||||
[result, toRope(ord(t.kind))])
|
||||
prepend(p.g.typeInfo, s)
|
||||
appf(p.g.typeInfo, "$1.base = $2;$n",
|
||||
[result, genTypeInfo(p, typ.sons[0])])
|
||||
[result, genTypeInfo(p, typ.lastSon)])
|
||||
of tyArrayConstr, tyArray:
|
||||
var s = ropef(
|
||||
"var $1 = {size: 0,kind: $2,base: null,node: null,finalizer: null};$n",
|
||||
|
||||
@@ -118,8 +118,8 @@ proc commonType*(x, y: PType): PType =
|
||||
if a.kind in {tyRef, tyPtr}:
|
||||
k = a.kind
|
||||
if b.kind != a.kind: return x
|
||||
a = a.sons[0]
|
||||
b = b.sons[0]
|
||||
a = a.lastSon
|
||||
b = b.lastSon
|
||||
if a.kind == tyObject and b.kind == tyObject:
|
||||
result = commonSuperclass(a, b)
|
||||
# this will trigger an error later:
|
||||
|
||||
@@ -155,8 +155,8 @@ proc checkConvertible(c: PContext, castDest, src: PType): TConvStatus =
|
||||
var d = skipTypes(castDest, abstractVar)
|
||||
var s = skipTypes(src, abstractVar-{tyTypeDesc})
|
||||
while (d != nil) and (d.kind in {tyPtr, tyRef}) and (d.kind == s.kind):
|
||||
d = base(d)
|
||||
s = base(s)
|
||||
d = d.lastSon
|
||||
s = s.lastSon
|
||||
if d == nil:
|
||||
result = convNotLegal
|
||||
elif d.kind == tyObject and s.kind == tyObject:
|
||||
@@ -930,7 +930,7 @@ proc makeDeref(n: PNode): PNode =
|
||||
var a = result
|
||||
result = newNodeIT(nkHiddenDeref, n.info, t.sons[0])
|
||||
addSon(result, a)
|
||||
t = skipTypes(t.sons[0], {tyGenericInst})
|
||||
t = skipTypes(t.lastSon, {tyGenericInst})
|
||||
|
||||
const
|
||||
tyTypeParamsHolders = {tyGenericInst, tyCompositeTypeClass}
|
||||
@@ -1072,7 +1072,7 @@ proc semDeref(c: PContext, n: PNode): PNode =
|
||||
result = n
|
||||
var t = skipTypes(n.sons[0].typ, {tyGenericInst, tyVar})
|
||||
case t.kind
|
||||
of tyRef, tyPtr: n.typ = t.sons[0]
|
||||
of tyRef, tyPtr: n.typ = t.lastSon
|
||||
else: result = nil
|
||||
#GlobalError(n.sons[0].info, errCircumNeedsPointer)
|
||||
|
||||
|
||||
@@ -817,8 +817,8 @@ proc typeSectionFinalPass(c: PContext, n: PNode) =
|
||||
var st = s.typ
|
||||
if st.kind == tyGenericBody: st = st.lastSon
|
||||
internalAssert st.kind in {tyPtr, tyRef}
|
||||
internalAssert st.sons[0].sym == nil
|
||||
st.sons[0].sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||
internalAssert st.lastSon.sym == nil
|
||||
st.lastSon.sym = newSym(skType, getIdent(s.name.s & ":ObjectType"),
|
||||
getCurrOwner(), s.info)
|
||||
|
||||
proc semTypeSection(c: PContext, n: PNode): PNode =
|
||||
|
||||
@@ -120,15 +120,23 @@ proc semVarargs(c: PContext, n: PNode, prev: PType): PType =
|
||||
else:
|
||||
localError(n.info, errXExpectsOneTypeParam, "varargs")
|
||||
addSonSkipIntLit(result, errorType(c))
|
||||
|
||||
proc semAnyRef(c: PContext, n: PNode, kind: TTypeKind, prev: PType): PType =
|
||||
if sonsLen(n) == 1:
|
||||
result = newOrPrevType(kind, prev, c)
|
||||
var base = semTypeNode(c, n.sons[0], nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
else:
|
||||
|
||||
proc semAnyRef(c: PContext; n: PNode; kind: TTypeKind; prev: PType): PType =
|
||||
if n.len < 1:
|
||||
result = newConstraint(c, kind)
|
||||
|
||||
else:
|
||||
let n = if n[0].kind == nkBracket: n[0] else: n
|
||||
checkMinSonsLen(n, 1)
|
||||
result = newOrPrevType(kind, prev, c)
|
||||
# check every except the last is an object:
|
||||
for i in 0 .. n.len-2:
|
||||
let region = semTypeNode(c, n[i], nil)
|
||||
if region.skipTypes({tyGenericInst}).kind notin {tyError, tyObject}:
|
||||
message n[i].info, errGenerated, "region needs to be an object type"
|
||||
addSonSkipIntLit(result, region)
|
||||
var base = semTypeNode(c, n.lastSon, nil)
|
||||
addSonSkipIntLit(result, base)
|
||||
|
||||
proc semVarType(c: PContext, n: PNode, prev: PType): PType =
|
||||
if sonsLen(n) == 1:
|
||||
result = newOrPrevType(tyVar, prev, c)
|
||||
|
||||
@@ -740,8 +740,10 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
result = isNone # BUGFIX!
|
||||
of tyPtr:
|
||||
case a.kind
|
||||
of tyPtr:
|
||||
result = typeRel(c, base(f), base(a))
|
||||
of tyPtr:
|
||||
for i in 0..min(f.len, a.len)-2:
|
||||
if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
|
||||
result = typeRel(c, f.lastSon, a.lastSon)
|
||||
if result <= isConvertible: result = isNone
|
||||
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
result = isNilConversion
|
||||
@@ -750,6 +752,8 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
of tyRef:
|
||||
case a.kind
|
||||
of tyRef:
|
||||
for i in 0..min(f.len, a.len)-2:
|
||||
if typeRel(c, f.sons[i], a.sons[i]) == isNone: return isNone
|
||||
result = typeRel(c, base(f), base(a))
|
||||
if result <= isConvertible: result = isNone
|
||||
elif tfNotNil in f.flags and tfNotNil notin a.flags:
|
||||
@@ -792,8 +796,9 @@ proc typeRel(c: var TCandidate, f, aOrig: PType, doBind = true): TTypeRelation =
|
||||
of tyNil: result = f.allowsNil
|
||||
of tyString: result = isConvertible
|
||||
of tyPtr:
|
||||
if a.sons[0].kind == tyChar: result = isConvertible
|
||||
of tyArray:
|
||||
# ptr[Tag, char] is not convertible to 'cstring' for now:
|
||||
if a.len == 1 and a.sons[0].kind == tyChar: result = isConvertible
|
||||
of tyArray:
|
||||
if (firstOrd(a.sons[0]) == 0) and
|
||||
(skipTypes(a.sons[0], {tyRange}).kind in {tyInt..tyInt64}) and
|
||||
(a.sons[1].kind == tyChar):
|
||||
|
||||
@@ -508,7 +508,16 @@ proc typeToString(typ: PType, prefer: TPreferedDesc = preferName): string =
|
||||
if i < sonsLen(t) - 1: add(result, ", ")
|
||||
add(result, ']')
|
||||
of tyPtr, tyRef, tyVar, tyMutable, tyConst:
|
||||
result = typeToStr[t.kind] & typeToString(t.sons[0])
|
||||
result = typeToStr[t.kind]
|
||||
if t.len >= 2:
|
||||
setLen(result, result.len-1)
|
||||
result.add '['
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
add(result, typeToString(t.sons[i]))
|
||||
if i < sonsLen(t) - 1: add(result, ", ")
|
||||
result.add ']'
|
||||
else:
|
||||
result.add typeToString(t.sons[0])
|
||||
of tyRange:
|
||||
result = "range " & rangeToStr(t.n)
|
||||
if prefer != preferExported:
|
||||
@@ -1082,9 +1091,9 @@ proc typeAllowedAux(marker: var TIntSet, typ: PType, kind: TSymKind,
|
||||
typeAllowedAux(marker, t.sons[1], skVar, flags)
|
||||
of tyRef:
|
||||
if kind == skConst: return false
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||
result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
|
||||
of tyPtr:
|
||||
result = typeAllowedAux(marker, t.sons[0], skVar, flags+{taHeap})
|
||||
result = typeAllowedAux(marker, t.lastSon, skVar, flags+{taHeap})
|
||||
of tyArrayConstr, tySet, tyConst, tyMutable, tyIter:
|
||||
for i in countup(0, sonsLen(t) - 1):
|
||||
result = typeAllowedAux(marker, t.sons[i], kind, flags)
|
||||
@@ -1293,7 +1302,7 @@ proc baseOfDistinct*(t: PType): PType =
|
||||
var it = result
|
||||
while it.kind in {tyPtr, tyRef}:
|
||||
parent = it
|
||||
it = it.sons[0]
|
||||
it = it.lastSon
|
||||
if it.kind == tyDistinct:
|
||||
internalAssert parent != nil
|
||||
parent.sons[0] = it.sons[0]
|
||||
|
||||
16
tests/typerel/tregionptrs.nim
Normal file
16
tests/typerel/tregionptrs.nim
Normal file
@@ -0,0 +1,16 @@
|
||||
discard """
|
||||
line: 16
|
||||
errormsg: "type mismatch: got (BPtr) but expected 'APtr'"
|
||||
"""
|
||||
|
||||
type
|
||||
RegionA = object
|
||||
APtr = ptr[RegionA, int]
|
||||
RegionB = object
|
||||
BPtr = ptr[RegionB, int]
|
||||
|
||||
var x,xx: APtr
|
||||
var y: BPtr
|
||||
x = nil
|
||||
x = xx
|
||||
x = y
|
||||
@@ -1,3 +1,8 @@
|
||||
<a class="news" href="news.html#Z2014-XX-XX-version-0-9-4-released">
|
||||
<h3>April 20, 2014</h3>
|
||||
<p>Nimrod version 0.9.4 has been released!</p>
|
||||
</a>
|
||||
|
||||
<a class="news" href="news.html#Z2014-02-11-nimrod-featured-in-dr-dobb-s-journal">
|
||||
<h3>Feb 11, 2014</h3>
|
||||
<p>Nimrod featured in Dr. Dobb's Journal</p>
|
||||
|
||||
Reference in New Issue
Block a user