diff options
-rw-r--r-- | compiler/ast.nim | 2 | ||||
-rw-r--r-- | compiler/ccgcalls.nim | 44 | ||||
-rw-r--r-- | compiler/parampatterns.nim | 5 | ||||
-rw-r--r-- | compiler/vm.nim | 3 | ||||
-rw-r--r-- | compiler/vmdef.nim | 2 | ||||
-rw-r--r-- | compiler/vmgen.nim | 3 | ||||
-rw-r--r-- | lib/system.nim | 4 | ||||
-rw-r--r-- | lib/system/gc_ms.nim | 1 | ||||
-rw-r--r-- | lib/windows/winlean.nim | 10 | ||||
-rw-r--r-- | tests/macros/tgentemplates.nim | 35 |
10 files changed, 89 insertions, 20 deletions
diff --git a/compiler/ast.nim b/compiler/ast.nim index 97f48b253..172dd1fce 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 84c5bf419..a7840305d 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 e94068776..bbdba8c22 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/vm.nim b/compiler/vm.nim index 836f90967..218369fa1 100644 --- a/compiler/vm.nim +++ b/compiler/vm.nim @@ -127,7 +127,8 @@ proc createStrKeepNode(x: var TFullReg) = elif x.node.kind == nkNilLit: system.reset(x.node[]) x.node.kind = nkStrLit - elif x.node.kind notin {nkStrLit..nkTripleStrLit}: + elif x.node.kind notin {nkStrLit..nkTripleStrLit} or + nfAllConst in x.node.flags: # XXX this is hacky; tests/txmlgen triggers it: x.node = newNode(nkStrLit) # debug x.node diff --git a/compiler/vmdef.nim b/compiler/vmdef.nim index d0c38a2ad..c391d8415 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 84577bb22..ba1b33e77 100644 --- a/compiler/vmgen.nim +++ b/compiler/vmgen.nim @@ -331,6 +331,7 @@ proc canonValue*(n: PNode): PNode = proc rawGenLiteral(c: PCtx; n: PNode): int = result = c.constants.len assert(n.kind != nkCall) + n.flags.incl nfAllConst c.constants.add n.canonValue internalAssert result < 0x7fff @@ -1622,7 +1623,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 6263f7b24..cfc8ceb6f 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 .. <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. diff --git a/lib/system/gc_ms.nim b/lib/system/gc_ms.nim index 410243528..05bcdcc82 100644 --- a/lib/system/gc_ms.nim +++ b/lib/system/gc_ms.nim @@ -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) diff --git a/lib/windows/winlean.nim b/lib/windows/winlean.nim index 5f4224c2a..dcae6ffaf 100644 --- a/lib/windows/winlean.nim +++ b/lib/windows/winlean.nim @@ -718,4 +718,12 @@ proc WSASend*(s: TSocketHandle, buf: ptr TWSABuf, bufCount: DWORD, stdcall, importc: "WSASend", dynlib: "Ws2_32.dll".} proc get_osfhandle*(fd:TFileHandle): THandle {. - importc:"_get_osfhandle", header:"<io.h>".} + importc: "_get_osfhandle", header:"<io.h>".} + +proc getSystemTimes*(lpIdleTime, lpKernelTime, + lpUserTime: var TFILETIME): WINBOOL {.stdcall, + dynlib: "kernel32", importc: "GetSystemTimes".} + +proc getProcessTimes*(hProcess: THandle; lpCreationTime, lpExitTime, + lpKernelTime, lpUserTime: var TFILETIME): WINBOOL {.stdcall, + dynlib: "kernel32", importc: "GetProcessTimes".} diff --git a/tests/macros/tgentemplates.nim b/tests/macros/tgentemplates.nim new file mode 100644 index 000000000..a7727c597 --- /dev/null +++ b/tests/macros/tgentemplates.nim @@ -0,0 +1,35 @@ +# bug #1140 + +import parseutils, macros + +proc parse_until_symbol(node: PNimrodNode, value: string, index: var int): bool {.compiletime.} = + var splitValue: string + var read = value.parseUntil(splitValue, '$', index) + + # when false: + if false: + var identifier: string + read = value.parseWhile(identifier, {}, index) + node.add newCall("add", ident("result"), newCall("$", ident(identifier))) + + if splitValue.len > 0: + node.insert node.len, newCall("add", ident("result"), newStrLitNode(splitValue)) + +proc parse_template(node: PNimrodNode, value: string) {.compiletime.} = + var index = 0 + while index < value.len and + parse_until_symbol(node, value, index): discard + +macro tmpli*(body: expr): stmt = + result = newStmtList() + result.add parseExpr("result = \"\"") + result.parse_template body[1].strVal + + +proc actual: string = tmpli html""" + <p>Test!</p> + """ + +proc another: string = tmpli html""" + <p>what</p> + """ |