implemented region pointers

This commit is contained in:
Araq
2014-04-09 00:33:51 +02:00
parent 3e25d5f247
commit 4196757de7
14 changed files with 83 additions and 40 deletions

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View 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

View File

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