mirror of
https://github.com/nim-lang/Nim.git
synced 2026-01-03 03:32:32 +00:00
implemented builtin noncopying slice
This commit is contained in:
@@ -597,7 +597,7 @@ const
|
||||
mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr,
|
||||
mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet,
|
||||
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
|
||||
mConTArr, mConTT, mSlice,
|
||||
mConTArr, mConTT,
|
||||
mAppendStrCh, mAppendStrStr, mAppendSeqElem,
|
||||
mInRange, mInSet, mRepr,
|
||||
mRand,
|
||||
|
||||
@@ -77,18 +77,38 @@ proc isInCurrentFrame(p: BProc, n: PNode): bool =
|
||||
|
||||
proc openArrayLoc(p: BProc, n: PNode): PRope =
|
||||
var a: TLoc
|
||||
initLocExpr(p, n, a)
|
||||
case skipTypes(a.t, abstractVar).kind
|
||||
of tyOpenArray, tyVarargs:
|
||||
result = ropef("$1, $1Len0", [rdLoc(a)])
|
||||
of tyString, tySequence:
|
||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
|
||||
else:
|
||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
|
||||
of tyArray, tyArrayConstr:
|
||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
||||
|
||||
let q = skipConv(n)
|
||||
if getMagic(q) == mSlice:
|
||||
# magic: pass slice to openArray:
|
||||
var b, c: TLoc
|
||||
initLocExpr(p, q[1], a)
|
||||
initLocExpr(p, q[2], b)
|
||||
initLocExpr(p, q[3], c)
|
||||
let fmt =
|
||||
case skipTypes(a.t, abstractVar).kind
|
||||
of tyOpenArray, tyVarargs, tyArray, tyArrayConstr:
|
||||
"($1)+($2), ($3)-($2)+1"
|
||||
of tyString, tySequence:
|
||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
||||
"(*$1)->data+($2), ($3)-($2)+1"
|
||||
else:
|
||||
"$1->data+($2), ($3)-($2)+1"
|
||||
else: (internalError("openArrayLoc: " & typeToString(a.t)); "")
|
||||
result = ropef(fmt, [rdLoc(a), rdLoc(b), rdLoc(c)])
|
||||
else:
|
||||
initLocExpr(p, n, a)
|
||||
case skipTypes(a.t, abstractVar).kind
|
||||
of tyOpenArray, tyVarargs:
|
||||
result = ropef("$1, $1Len0", [rdLoc(a)])
|
||||
of tyString, tySequence:
|
||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
|
||||
else:
|
||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
|
||||
of tyArray, tyArrayConstr:
|
||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
||||
|
||||
proc genArgStringToCString(p: BProc,
|
||||
n: PNode): PRope {.inline.} =
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
## This module implements the pattern matching features for term rewriting
|
||||
## macro support.
|
||||
|
||||
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg
|
||||
import strutils, ast, astalgo, types, msgs, idents, renderer, wordrecg, trees
|
||||
|
||||
# we precompile the pattern here for efficiency into some internal
|
||||
# stack based VM :-) Why? Because it's fun; I did no benchmarks to see if that
|
||||
@@ -215,6 +215,9 @@ proc isAssignable*(owner: PSym, n: PNode): TAssignableResult =
|
||||
result = arLValue
|
||||
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
|
||||
result = isAssignable(owner, n.sons[0])
|
||||
of nkCallKinds:
|
||||
# builtin slice keeps lvalue-ness:
|
||||
if getMagic(n) == mSlice: result = isAssignable(owner, n.sons[1])
|
||||
else:
|
||||
discard
|
||||
|
||||
|
||||
@@ -207,7 +207,7 @@ const
|
||||
largeInstrs* = { # instructions which use 2 int32s instead of 1:
|
||||
opcSubStr, opcConv, opcCast, opcNewSeq, opcOf}
|
||||
slotSomeTemp* = slotTempUnknown
|
||||
relativeJumps* = {opcTJmp, opcFJmp, opcJmp}
|
||||
relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack}
|
||||
|
||||
template opcode*(x: TInstr): TOpcode {.immediate.} = TOpcode(x.uint32 and 0xff'u32)
|
||||
template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u32 and 0xff'u32)
|
||||
|
||||
@@ -1622,7 +1622,7 @@ proc genProc(c: PCtx; s: PSym): int =
|
||||
c.gABC(body, opcEof, eofInstr.regA)
|
||||
c.optimizeJumps(result)
|
||||
s.offset = c.prc.maxSlots
|
||||
#if s.name.s == "addStuff":
|
||||
#if s.name.s == "parse_until_symbol":
|
||||
# echo renderTree(body)
|
||||
# c.echoCode(result)
|
||||
c.prc = oldPrc
|
||||
|
||||
@@ -2620,7 +2620,7 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) =
|
||||
if L == b.len:
|
||||
for i in 0 .. <L: a[i+x.a] = b[i]
|
||||
else:
|
||||
sysFatal(EOutOfRange, "differing lengths for slice assignment")
|
||||
sysFatal(EOutOfRange, "different lengths for slice assignment")
|
||||
|
||||
proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] =
|
||||
## slice operation for arrays. Negative indexes are **not** supported
|
||||
@@ -2642,7 +2642,7 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[Idx], b: openArray[T]) =
|
||||
a[j] = b[i]
|
||||
inc(j)
|
||||
else:
|
||||
sysFatal(EOutOfRange, "differing lengths for slice assignment")
|
||||
sysFatal(EOutOfRange, "different lengths for slice assignment")
|
||||
|
||||
proc `[]`*[T](s: seq[T], x: TSlice[int]): seq[T] =
|
||||
## slice operation for sequences. Negative indexes are supported.
|
||||
|
||||
@@ -313,6 +313,7 @@ proc mark(gch: var TGcHeap, c: PCell) =
|
||||
if not containsOrIncl(gch.marked, d):
|
||||
forAllChildren(d, waMarkPrecise)
|
||||
else:
|
||||
# XXX no 'if c.refCount != rcBlack' here?
|
||||
c.refCount = rcBlack
|
||||
gcAssert gch.tempStack.len == 0, "stack not empty!"
|
||||
forAllChildren(c, waMarkPrecise)
|
||||
|
||||
Reference in New Issue
Block a user