mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-29 01:14:41 +00:00
produce runtime type information for reified openArrays (#15415)
* produce runtime type information for reified openArrays * added a test case
This commit is contained in:
@@ -171,7 +171,7 @@ proc genOpenArraySlice(p: BProc; q: PNode; formalType, destType: PType): (Rope,
|
||||
lengthExpr)
|
||||
of tyOpenArray, tyVarargs:
|
||||
if reifiedOpenArray(q[1]):
|
||||
result = ("($3*)($1.d)+($2)" % [rdLoc(a), rdLoc(b), dest],
|
||||
result = ("($3*)($1.Field0)+($2)" % [rdLoc(a), rdLoc(b), dest],
|
||||
lengthExpr)
|
||||
else:
|
||||
result = ("($3*)($1)+($2)" % [rdLoc(a), rdLoc(b), dest],
|
||||
@@ -215,7 +215,10 @@ proc openArrayLoc(p: BProc, formalType: PType, n: PNode): Rope =
|
||||
case skipTypes(a.t, abstractVar).kind
|
||||
of tyOpenArray, tyVarargs:
|
||||
if reifiedOpenArray(n):
|
||||
result = "$1.d, $1.l" % [rdLoc(a)]
|
||||
if a.t.kind in {tyVar, tyLent}:
|
||||
result = "$1->Field0, $1->Field1" % [rdLoc(a)]
|
||||
else:
|
||||
result = "$1.Field0, $1.Field1" % [rdLoc(a)]
|
||||
else:
|
||||
result = "$1, $1Len_0" % [rdLoc(a)]
|
||||
of tyString, tySequence:
|
||||
|
||||
@@ -278,23 +278,23 @@ proc genOpenArrayConv(p: BProc; d: TLoc; a: TLoc) =
|
||||
case a.t.skipTypes(abstractVar).kind
|
||||
of tyOpenArray, tyVarargs:
|
||||
if reifiedOpenArray(a.lode):
|
||||
linefmt(p, cpsStmts, "$1.d = $2.d; $1.l = $2.l;$n",
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2.Field0; $1.Field1 = $2.Field1;$n",
|
||||
[rdLoc(d), a.rdLoc])
|
||||
else:
|
||||
linefmt(p, cpsStmts, "$1.d = $2; $1.l = $2Len_0;$n",
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $2Len_0;$n",
|
||||
[rdLoc(d), a.rdLoc])
|
||||
of tySequence:
|
||||
linefmt(p, cpsStmts, "$1.d = $2$3; $1.l = $4;$n",
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)])
|
||||
of tyArray:
|
||||
linefmt(p, cpsStmts, "$1.d = $2; $1.l = $3;$n",
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n",
|
||||
[rdLoc(d), rdLoc(a), rope(lengthOrd(p.config, a.t))])
|
||||
of tyString:
|
||||
let etyp = skipTypes(a.t, abstractInst)
|
||||
if etyp.kind in {tyVar} and optSeqDestructors in p.config.globalOptions:
|
||||
linefmt(p, cpsStmts, "#nimPrepareStrMutationV2($1);$n", [byRefLoc(p, a)])
|
||||
|
||||
linefmt(p, cpsStmts, "$1.d = $2$3; $1.l = $4;$n",
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2$3; $1.Field1 = $4;$n",
|
||||
[rdLoc(d), a.rdLoc, dataField(p), lenExpr(p, a)])
|
||||
else:
|
||||
internalError(p.config, a.lode.info, "cannot handle " & $a.t.kind)
|
||||
@@ -943,7 +943,7 @@ proc genBoundsCheck(p: BProc; arr, a, b: TLoc) =
|
||||
if reifiedOpenArray(arr.lode):
|
||||
linefmt(p, cpsStmts,
|
||||
"if ($2-$1 != -1 && " &
|
||||
"((NU)($1) >= (NU)($3.l) || (NU)($2) >= (NU)($3.l))){ #raiseIndexError(); $4}$n",
|
||||
"((NU)($1) >= (NU)($3.Field1) || (NU)($2) >= (NU)($3.Field1))){ #raiseIndexError(); $4}$n",
|
||||
[rdLoc(a), rdLoc(b), rdLoc(arr), raiseInstr(p)])
|
||||
else:
|
||||
linefmt(p, cpsStmts,
|
||||
@@ -977,11 +977,11 @@ proc genOpenArrayElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||
ropecg(p.module, "$1[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
|
||||
else:
|
||||
if optBoundsCheck in p.options:
|
||||
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2.l)){ #raiseIndexError2($1,$2.l-1); $3}$n",
|
||||
linefmt(p, cpsStmts, "if ((NU)($1) >= (NU)($2.Field1)){ #raiseIndexError2($1,$2.Field1-1); $3}$n",
|
||||
[rdLoc(b), rdLoc(a), raiseInstr(p)]) # BUGFIX: ``>=`` and not ``>``!
|
||||
inheritLocation(d, a)
|
||||
putIntoDest(p, d, n,
|
||||
ropecg(p.module, "$1.d[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
|
||||
ropecg(p.module, "$1.Field0[$2]", [rdLoc(a), rdCharLoc(b)]), a.storage)
|
||||
|
||||
proc genSeqElem(p: BProc, n, x, y: PNode, d: var TLoc) =
|
||||
var a, b: TLoc
|
||||
@@ -1739,8 +1739,8 @@ proc genArrayLen(p: BProc, e: PNode, d: var TLoc, op: TMagic) =
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1Len_0-1)")
|
||||
else: unaryExpr(p, e, d, "$1Len_0")
|
||||
else:
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1.l-1)")
|
||||
else: unaryExpr(p, e, d, "$1.l")
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1.Field1-1)")
|
||||
else: unaryExpr(p, e, d, "$1.Field1")
|
||||
of tyCString:
|
||||
if op == mHigh: unaryExpr(p, e, d, "($1 ? (#nimCStrLen($1)-1) : -1)")
|
||||
else: unaryExpr(p, e, d, "($1 ? #nimCStrLen($1) : 0)")
|
||||
@@ -2218,7 +2218,7 @@ proc genDispose(p: BProc; n: PNode) =
|
||||
proc genSlice(p: BProc; e: PNode; d: var TLoc) =
|
||||
let (x, y) = genOpenArraySlice(p, e, e.typ, e.typ.lastSon)
|
||||
if d.k == locNone: getTemp(p, e.typ, d)
|
||||
linefmt(p, cpsStmts, "$1.d = $2; $1.l = $3;$n", [rdLoc(d), x, y])
|
||||
linefmt(p, cpsStmts, "$1.Field0 = $2; $1.Field1 = $3;$n", [rdLoc(d), x, y])
|
||||
when false:
|
||||
localError(p.config, e.info, "invalid context for 'toOpenArray'; " &
|
||||
"'toOpenArray' is only valid within a call expression")
|
||||
|
||||
@@ -693,7 +693,7 @@ proc getOpenArrayDesc(m: BModule, t: PType, check: var IntSet; kind: TSymKind):
|
||||
result = getTypeName(m, t, sig)
|
||||
m.typeCache[sig] = result
|
||||
let elemType = getTypeDescWeak(m, t[0], check, kind)
|
||||
m.s[cfsTypes].addf("typedef struct {$n$2* d;$nNI l;$n} $1;$n",
|
||||
m.s[cfsTypes].addf("typedef struct {$n$2* Field0;$nNI Field1;$n} $1;$n",
|
||||
[result, elemType])
|
||||
|
||||
proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKind): Rope =
|
||||
@@ -724,7 +724,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet; kind: TSymKin
|
||||
compileToCpp(m): "&" else: "*"
|
||||
var et = origTyp.skipTypes(abstractInst).lastSon
|
||||
var etB = et.skipTypes(abstractInst)
|
||||
if mapType(m.config, t, kind) == ctPtrToArray:
|
||||
if mapType(m.config, t, kind) == ctPtrToArray and (etB.kind != tyOpenArray or kind == skParam):
|
||||
if etB.kind == tySet:
|
||||
et = getSysType(m.g.graph, unknownLineInfo, tyUInt8)
|
||||
else:
|
||||
@@ -1030,7 +1030,7 @@ proc genTypeInfoAuxBase(m: BModule; typ, origType: PType;
|
||||
if tfIncompleteStruct in typ.flags:
|
||||
size = rope"void*"
|
||||
else:
|
||||
size = getTypeDesc(m, origType)
|
||||
size = getTypeDesc(m, origType, skVar)
|
||||
m.s[cfsTypeInit3].addf(
|
||||
"$1.size = sizeof($2);$n$1.align = NIM_ALIGNOF($2);$n$1.kind = $3;$n$1.base = $4;$n",
|
||||
[nameHcr, size, rope(nimtypeKind), base]
|
||||
@@ -1128,7 +1128,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
|
||||
m.s[cfsTypeInit3].addf("$1.kind = 3;$n" &
|
||||
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
||||
"$1.name = $5;$n" & "$1.sons = &$6[0];$n" &
|
||||
"$1.len = $7;$n", [expr, getTypeDesc(m, origType), field.loc.r,
|
||||
"$1.len = $7;$n", [expr, getTypeDesc(m, origType, skVar), field.loc.r,
|
||||
genTypeInfoV1(m, field.typ, info),
|
||||
makeCString(field.name.s),
|
||||
tmp, rope(L)])
|
||||
@@ -1165,7 +1165,7 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
|
||||
internalError(m.config, n.info, "genObjectFields")
|
||||
m.s[cfsTypeInit3].addf("$1.kind = 1;$n" &
|
||||
"$1.offset = offsetof($2, $3);$n" & "$1.typ = $4;$n" &
|
||||
"$1.name = $5;$n", [expr, getTypeDesc(m, origType),
|
||||
"$1.name = $5;$n", [expr, getTypeDesc(m, origType, skVar),
|
||||
field.loc.r, genTypeInfoV1(m, field.typ, info), makeCString(field.name.s)])
|
||||
else: internalError(m.config, n.info, "genObjectFields")
|
||||
|
||||
@@ -1201,7 +1201,7 @@ proc genTupleInfo(m: BModule, typ, origType: PType, name: Rope; info: TLineInfo)
|
||||
"$1.offset = offsetof($2, Field$3);$n" &
|
||||
"$1.typ = $4;$n" &
|
||||
"$1.name = \"Field$3\";$n",
|
||||
[tmp2, getTypeDesc(m, origType), rope(i), genTypeInfoV1(m, a, info)])
|
||||
[tmp2, getTypeDesc(m, origType, skVar), rope(i), genTypeInfoV1(m, a, info)])
|
||||
m.s[cfsTypeInit3].addf("$1.len = $2; $1.kind = 2; $1.sons = &$3[0];$n",
|
||||
[expr, rope(typ.len), tmp])
|
||||
else:
|
||||
@@ -1387,6 +1387,15 @@ proc genTypeInfoV2(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
genTypeInfoV2Impl(m, t, origType, result, info)
|
||||
result = prefixTI.rope & result & ")".rope
|
||||
|
||||
proc openArrayToTuple(m: BModule; t: PType): PType =
|
||||
result = newType(tyTuple, t.owner)
|
||||
let p = newType(tyPtr, t.owner)
|
||||
let a = newType(tyUncheckedArray, t.owner)
|
||||
a.add t.lastSon
|
||||
p.add a
|
||||
result.add p
|
||||
result.add getSysType(m.g.graph, t.owner.info, tyInt)
|
||||
|
||||
proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
let origType = t
|
||||
var t = skipTypes(origType, irrelevantForBackend + tyUserTypeClasses)
|
||||
@@ -1461,6 +1470,9 @@ proc genTypeInfoV1(m: BModule, t: PType; info: TLineInfo): Rope =
|
||||
# BUGFIX: use consistently RTTI without proper field names; otherwise
|
||||
# results are not deterministic!
|
||||
genTupleInfo(m, t, origType, result, info)
|
||||
of tyOpenArray:
|
||||
let x = openArrayToTuple(m, t)
|
||||
genTupleInfo(m, x, origType, result, info)
|
||||
else: internalError(m.config, "genTypeInfoV1(" & $t.kind & ')')
|
||||
|
||||
if t.attachedOps[attachedDeepCopy] != nil:
|
||||
|
||||
42
tests/views/tsplit_into_seq.nim
Normal file
42
tests/views/tsplit_into_seq.nim
Normal file
@@ -0,0 +1,42 @@
|
||||
discard """
|
||||
output: '''asdf
|
||||
asdf
|
||||
231
|
||||
231
|
||||
'''
|
||||
cmd: "nim c $file"
|
||||
"""
|
||||
|
||||
{.experimental: "views".}
|
||||
|
||||
const
|
||||
Whitespace = {' ', '\t', '\n', '\r'}
|
||||
|
||||
proc split*(s: string, seps: set[char] = Whitespace,
|
||||
maxsplit: int = -1): seq[openArray[char]] =
|
||||
var last = 0
|
||||
var splits = maxsplit
|
||||
result = @[]
|
||||
|
||||
while last <= len(s):
|
||||
var first = last
|
||||
while last < len(s) and s[last] notin seps:
|
||||
inc(last)
|
||||
if splits == 0: last = len(s)
|
||||
{.noSideEffect.}:
|
||||
result.add toOpenArray(s, first, last-1)
|
||||
result.add toOpenArray(s, first, last-1)
|
||||
if splits == 0: break
|
||||
dec(splits)
|
||||
inc(last)
|
||||
|
||||
proc `$`(x: openArray[char]): string =
|
||||
result = newString(x.len)
|
||||
for i in 0..<x.len: result[i] = x[i]
|
||||
|
||||
proc main() =
|
||||
let words = split("asdf 231")
|
||||
for x in words:
|
||||
echo x
|
||||
|
||||
main()
|
||||
Reference in New Issue
Block a user