diff --git a/compiler/ast.nim b/compiler/ast.nim index 97f48b2531..172dd1fce4 100644 --- a/compiler/ast.nim +++ b/compiler/ast.nim @@ -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, diff --git a/compiler/ccgcalls.nim b/compiler/ccgcalls.nim index 84c5bf4199..a7840305dd 100644 --- a/compiler/ccgcalls.nim +++ b/compiler/ccgcalls.nim @@ -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.} = diff --git a/compiler/parampatterns.nim b/compiler/parampatterns.nim index e94068776c..bbdba8c225 100644 --- a/compiler/parampatterns.nim +++ b/compiler/parampatterns.nim @@ -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 diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index d0c38a2ad4..c391d8415f 100644 --- a/compiler/vmdef.nim +++ b/compiler/vmdef.nim @@ -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) diff --git a/compiler/vmgen.nim b/compiler/vmgen.nim index 84577bb229..c5eb670251 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -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 diff --git a/lib/system.nim b/lib/system.nim index 6263f7b246..cfc8ceb6f4 100644 --- a/lib/system.nim +++ b/lib/system.nim @@ -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 ..