implemented builtin noncopying slice
This commit is contained in:
parent
81d4049797
commit
d0438540d0
7 changed files with 42 additions and 18 deletions
|
|
@ -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,
|
||||||
|
|
|
||||||
|
|
@ -77,18 +77,38 @@ 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
|
||||||
initLocExpr(p, n, a)
|
|
||||||
case skipTypes(a.t, abstractVar).kind
|
let q = skipConv(n)
|
||||||
of tyOpenArray, tyVarargs:
|
if getMagic(q) == mSlice:
|
||||||
result = ropef("$1, $1Len0", [rdLoc(a)])
|
# magic: pass slice to openArray:
|
||||||
of tyString, tySequence:
|
var b, c: TLoc
|
||||||
if skipTypes(n.typ, abstractInst).kind == tyVar:
|
initLocExpr(p, q[1], a)
|
||||||
result = ropef("(*$1)->data, (*$1)->$2", [a.rdLoc, lenField()])
|
initLocExpr(p, q[2], b)
|
||||||
else:
|
initLocExpr(p, q[3], c)
|
||||||
result = ropef("$1->data, $1->$2", [a.rdLoc, lenField()])
|
let fmt =
|
||||||
of tyArray, tyArrayConstr:
|
case skipTypes(a.t, abstractVar).kind
|
||||||
result = ropef("$1, $2", [rdLoc(a), toRope(lengthOrd(a.t))])
|
of tyOpenArray, tyVarargs, tyArray, tyArrayConstr:
|
||||||
else: internalError("openArrayLoc: " & typeToString(a.t))
|
"($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,
|
proc genArgStringToCString(p: BProc,
|
||||||
n: PNode): PRope {.inline.} =
|
n: PNode): PRope {.inline.} =
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
|
|
@ -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
|
||||||
|
|
|
||||||
|
|
@ -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.
|
||||||
|
|
|
||||||
|
|
@ -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)
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue