summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/ast.nim2
-rw-r--r--compiler/ccgcalls.nim44
-rw-r--r--compiler/parampatterns.nim5
-rw-r--r--compiler/vm.nim3
-rw-r--r--compiler/vmdef.nim2
-rw-r--r--compiler/vmgen.nim3
-rw-r--r--lib/system.nim4
-rw-r--r--lib/system/gc_ms.nim1
-rw-r--r--lib/windows/winlean.nim10
-rw-r--r--tests/macros/tgentemplates.nim35
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>
+    """