implemented builtin noncopying slice

This commit is contained in:
Araq 2014-05-02 08:44:03 +02:00
commit d0438540d0
7 changed files with 42 additions and 18 deletions

View file

@ -597,7 +597,7 @@ const
mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr, mIntToStr, mInt64ToStr, mFloatToStr, mCStrToStr, mStrToStr, mEnumToStr,
mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet, mAnd, mOr, mEqStr, mLeStr, mLtStr, mEqSet, mLeSet, mLtSet, mMulSet,
mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT, mPlusSet, mMinusSet, mSymDiffSet, mConStrStr, mConArrArr, mConArrT,
mConTArr, mConTT, mSlice, mConTArr, mConTT,
mAppendStrCh, mAppendStrStr, mAppendSeqElem, mAppendStrCh, mAppendStrStr, mAppendSeqElem,
mInRange, mInSet, mRepr, mInRange, mInSet, mRepr,
mRand, mRand,

View file

@ -77,6 +77,26 @@ proc isInCurrentFrame(p: BProc, n: PNode): bool =
proc openArrayLoc(p: BProc, n: PNode): PRope = proc openArrayLoc(p: BProc, n: PNode): PRope =
var a: TLoc var a: TLoc
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) initLocExpr(p, n, a)
case skipTypes(a.t, abstractVar).kind case skipTypes(a.t, abstractVar).kind
of tyOpenArray, tyVarargs: of tyOpenArray, tyVarargs:

View file

@ -10,7 +10,7 @@
## This module implements the pattern matching features for term rewriting ## This module implements the pattern matching features for term rewriting
## macro support. ## 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 # 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 # 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 result = arLValue
of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr: of nkObjUpConv, nkObjDownConv, nkCheckedFieldExpr:
result = isAssignable(owner, n.sons[0]) result = isAssignable(owner, n.sons[0])
of nkCallKinds:
# builtin slice keeps lvalue-ness:
if getMagic(n) == mSlice: result = isAssignable(owner, n.sons[1])
else: else:
discard discard

View file

@ -207,7 +207,7 @@ const
largeInstrs* = { # instructions which use 2 int32s instead of 1: largeInstrs* = { # instructions which use 2 int32s instead of 1:
opcSubStr, opcConv, opcCast, opcNewSeq, opcOf} opcSubStr, opcConv, opcCast, opcNewSeq, opcOf}
slotSomeTemp* = slotTempUnknown slotSomeTemp* = slotTempUnknown
relativeJumps* = {opcTJmp, opcFJmp, opcJmp} relativeJumps* = {opcTJmp, opcFJmp, opcJmp, opcJmpBack}
template opcode*(x: TInstr): TOpcode {.immediate.} = TOpcode(x.uint32 and 0xff'u32) 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) template regA*(x: TInstr): TRegister {.immediate.} = TRegister(x.uint32 shr 8'u32 and 0xff'u32)

View file

@ -1622,7 +1622,7 @@ proc genProc(c: PCtx; s: PSym): int =
c.gABC(body, opcEof, eofInstr.regA) c.gABC(body, opcEof, eofInstr.regA)
c.optimizeJumps(result) c.optimizeJumps(result)
s.offset = c.prc.maxSlots s.offset = c.prc.maxSlots
#if s.name.s == "addStuff": #if s.name.s == "parse_until_symbol":
# echo renderTree(body) # echo renderTree(body)
# c.echoCode(result) # c.echoCode(result)
c.prc = oldPrc c.prc = oldPrc

View file

@ -2620,7 +2620,7 @@ proc `[]=`*[Idx, T](a: var array[Idx, T], x: TSlice[int], b: openArray[T]) =
if L == b.len: if L == b.len:
for i in 0 .. <L: a[i+x.a] = b[i] for i in 0 .. <L: a[i+x.a] = b[i]
else: 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] = proc `[]`*[Idx, T](a: array[Idx, T], x: TSlice[Idx]): seq[T] =
## slice operation for arrays. Negative indexes are **not** supported ## 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] a[j] = b[i]
inc(j) inc(j)
else: 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] = proc `[]`*[T](s: seq[T], x: TSlice[int]): seq[T] =
## slice operation for sequences. Negative indexes are supported. ## slice operation for sequences. Negative indexes are supported.

View file

@ -313,6 +313,7 @@ proc mark(gch: var TGcHeap, c: PCell) =
if not containsOrIncl(gch.marked, d): if not containsOrIncl(gch.marked, d):
forAllChildren(d, waMarkPrecise) forAllChildren(d, waMarkPrecise)
else: else:
# XXX no 'if c.refCount != rcBlack' here?
c.refCount = rcBlack c.refCount = rcBlack
gcAssert gch.tempStack.len == 0, "stack not empty!" gcAssert gch.tempStack.len == 0, "stack not empty!"
forAllChildren(c, waMarkPrecise) forAllChildren(c, waMarkPrecise)