summary refs log tree commit diff stats
diff options
context:
space:
mode:
-rw-r--r--compiler/semdata.nim1
-rw-r--r--compiler/semexprs.nim11
-rw-r--r--compiler/semmagic.nim32
-rw-r--r--compiler/semtempl.nim18
-rw-r--r--lib/impure/nre.nim36
-rw-r--r--lib/pure/matchers.nim2
-rw-r--r--lib/system.nim2
-rw-r--r--tests/array/troof1.nim27
-rw-r--r--tests/array/troof2.nim10
-rw-r--r--tests/array/troof3.nim5
-rw-r--r--tests/array/troof4.nim37
-rw-r--r--tests/stdlib/nre/captures.nim6
-rw-r--r--tests/stdlib/nre/find.nim2
13 files changed, 28 insertions, 161 deletions
diff --git a/compiler/semdata.nim b/compiler/semdata.nim
index b6b5db101..3e57d1104 100644
--- a/compiler/semdata.nim
+++ b/compiler/semdata.nim
@@ -37,7 +37,6 @@ type
                               # in standalone ``except`` and ``finally``
     next*: PProcCon           # used for stacking procedure contexts
     wasForwarded*: bool       # whether the current proc has a separate header
-    bracketExpr*: PNode       # current bracket expression (for ^ support)
     mapping*: TIdTable
 
   TMatchedConcept* = object
diff --git a/compiler/semexprs.nim b/compiler/semexprs.nim
index 195625489..c3aead18e 100644
--- a/compiler/semexprs.nim
+++ b/compiler/semexprs.nim
@@ -1189,7 +1189,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
      tyCString:
     if n.len != 2: return nil
     n.sons[0] = makeDeref(n.sons[0])
-    c.p.bracketExpr = n.sons[0]
     for i in countup(1, sonsLen(n) - 1):
       n.sons[i] = semExprWithType(c, n.sons[i],
                                   flags*{efInTypeof, efDetermineType})
@@ -1210,7 +1209,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
   of tyTuple:
     if n.len != 2: return nil
     n.sons[0] = makeDeref(n.sons[0])
-    c.p.bracketExpr = n.sons[0]
     # [] operator for tuples requires constant expression:
     n.sons[1] = semConstExpr(c, n.sons[1])
     if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias}).kind in
@@ -1248,17 +1246,13 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
       of skType:
         result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
       else:
-        c.p.bracketExpr = n.sons[0]
-    else:
-      c.p.bracketExpr = n.sons[0]
+        discard
 
 proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
-  let oldBracketExpr = c.p.bracketExpr
   result = semSubscript(c, n, flags)
   if result == nil:
     # overloaded [] operator:
     result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]"))
-  c.p.bracketExpr = oldBracketExpr
 
 proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
   var id = considerQuotedIdent(a[1], a)
@@ -1330,7 +1324,6 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
   of nkBracketExpr:
     # a[i] = x
     # --> `[]=`(a, i, x)
-    let oldBracketExpr = c.p.bracketExpr
     a = semSubscript(c, a, {efLValue})
     if a == nil:
       result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=")
@@ -1340,9 +1333,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
         return n
       else:
         result = semExprNoType(c, result)
-        c.p.bracketExpr = oldBracketExpr
         return result
-    c.p.bracketExpr = oldBracketExpr
   of nkCurlyExpr:
     # a{i} = x -->  `{}=`(a, i, x)
     result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=")
diff --git a/compiler/semmagic.nim b/compiler/semmagic.nim
index ba19e0865..d721f42ab 100644
--- a/compiler/semmagic.nim
+++ b/compiler/semmagic.nim
@@ -38,9 +38,7 @@ proc skipAddr(n: PNode): PNode {.inline.} =
 proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
   result = newNodeI(nkBracketExpr, n.info)
   for i in 1..<n.len: result.add(n[i])
-  let oldBracketExpr = c.p.bracketExpr
   result = semSubscript(c, result, flags)
-  c.p.bracketExpr = oldBracketExpr
   if result.isNil:
     let x = copyTree(n)
     x.sons[0] = newIdentNode(getIdent"[]", n.info)
@@ -274,35 +272,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
   of mDotDot:
     result = n
   of mRoof:
-    let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr
-    if bracketExpr.isNil:
-      localError(n.info, "no surrounding array access context for '^'")
-      result = n.sons[1]
-    elif bracketExpr.checkForSideEffects != seNoSideEffect:
-      localError(n.info, "invalid context for '^' as '$#' has side effects" %
-        renderTree(bracketExpr))
-      result = n.sons[1]
-    elif bracketExpr.typ.isStrangeArray:
-      localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" %
-        renderTree(bracketExpr))
-      result = n.sons[1]
-    else:
-      # ^x  is rewritten to: len(a)-x
-      let lenExpr = newNodeI(nkCall, n.info)
-      lenExpr.add newIdentNode(getIdent"len", n.info)
-      lenExpr.add bracketExpr
-      let lenExprB = semExprWithType(c, lenExpr)
-      if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ):
-        localError(n.info, "'$#' has to be of an ordinal type for '^'" %
-          renderTree(lenExpr))
-        result = n.sons[1]
-      else:
-        result = newNodeIT(nkCall, n.info, getSysType(tyInt))
-        let subi = getSysMagic("-", mSubI)
-        #echo "got ", typeToString(subi.typ)
-        result.add newSymNode(subi, n.info)
-        result.add lenExprB
-        result.add n.sons[1]
+    localError(n.info, "builtin roof operator is not supported anymore")
   of mPlugin:
     let plugin = getPlugin(n[0].sym)
     if plugin.isNil:
diff --git a/compiler/semtempl.nim b/compiler/semtempl.nim
index b6278dc66..426290c78 100644
--- a/compiler/semtempl.nim
+++ b/compiler/semtempl.nim
@@ -113,13 +113,9 @@ type
     owner: PSym
     cursorInBody: bool # only for nimsuggest
     scopeN: int
-    bracketExpr: PNode
 
 template withBracketExpr(ctx, x, body: untyped) =
-  let old = ctx.bracketExpr
-  ctx.bracketExpr = x
   body
-  ctx.bracketExpr = old
 
 proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
   case n.kind
@@ -304,18 +300,6 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
   for i in 0 ..< n.len:
     result.sons[i] = semTemplBody(c, n.sons[i])
 
-proc oprIsRoof(n: PNode): bool =
-  const roof = "^"
-  case n.kind
-  of nkIdent: result = n.ident.s == roof
-  of nkSym: result = n.sym.name.s == roof
-  of nkAccQuoted:
-    if n.len == 1:
-      result = oprIsRoof(n.sons[0])
-  of nkOpenSymChoice, nkClosedSymChoice:
-    result = oprIsRoof(n.sons[0])
-  else: discard
-
 proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
   result = n
   semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
@@ -506,8 +490,6 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
       result = semTemplBodySons(c, n)
   of nkCallKinds-{nkPostfix}:
     result = semTemplBodySons(c, n)
-    if c.bracketExpr != nil and n.len == 2 and oprIsRoof(n.sons[0]):
-      result.add c.bracketExpr
   of nkDotExpr, nkAccQuoted:
     # dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
     # so we use the generic code for nkDotExpr too
diff --git a/lib/impure/nre.nim b/lib/impure/nre.nim
index 4013182af..7df62f3b3 100644
--- a/lib/impure/nre.nim
+++ b/lib/impure/nre.nim
@@ -155,7 +155,7 @@ type
     ##     -  ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"``
     ##     -  ``"abc".match(re"(\w)\w").captures[-1] == "ab"``
     ##
-    ## ``captureBounds[]: Option[Slice[int]]``
+    ## ``captureBounds[]: Option[Slice[int, int]]``
     ##     gets the bounds of the given capture according to the same rules as
     ##     the above. If the capture is not filled, then ``None`` is returned.
     ##     The bounds are both inclusive.
@@ -167,7 +167,7 @@ type
     ## ``match: string``
     ##     the full text of the match.
     ##
-    ## ``matchBounds: Slice[int]``
+    ## ``matchBounds: Slice[int, int]``
     ##     the bounds of the match, as in ``captureBounds[]``
     ##
     ## ``(captureBounds|captures).toTable``
@@ -182,9 +182,9 @@ type
                      ## Not nil.
     str*: string  ## The string that was matched against.
                   ## Not nil.
-    pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match
-                                      ## Other items are the captures
-                                      ## `a` is inclusive start, `b` is exclusive end
+    pcreMatchBounds: seq[Slice[cint, cint]] ## First item is the bounds of the match
+                                            ## Other items are the captures
+                                            ## `a` is inclusive start, `b` is exclusive end
 
   Captures* = distinct RegexMatch
   CaptureBounds* = distinct RegexMatch
@@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p
 
 proc captures*(pattern: RegexMatch): Captures = return Captures(pattern)
 
-proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int]] =
+proc `[]`*(pattern: CaptureBounds, i: int): Option[Slice[int, int]] =
   let pattern = RegexMatch(pattern)
   if pattern.pcreMatchBounds[i + 1].a != -1:
     let bounds = pattern.pcreMatchBounds[i + 1]
     return some(int(bounds.a) .. int(bounds.b-1))
   else:
-    return none(Slice[int])
+    return none(Slice[int, int])
 
 proc `[]`*(pattern: Captures, i: int): string =
   let pattern = RegexMatch(pattern)
@@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string =
 proc match*(pattern: RegexMatch): string =
   return pattern.captures[-1]
 
-proc matchBounds*(pattern: RegexMatch): Slice[int] =
+proc matchBounds*(pattern: RegexMatch): Slice[int, int] =
   return pattern.captureBounds[-1].get
 
-proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int]] =
+proc `[]`*(pattern: CaptureBounds, name: string): Option[Slice[int, int]] =
   let pattern = RegexMatch(pattern)
   return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)]
 
@@ -295,13 +295,13 @@ proc toTable*(pattern: Captures, default: string = nil): Table[string, string] =
   result = initTable[string, string]()
   toTableImpl(nextVal == nil)
 
-proc toTable*(pattern: CaptureBounds, default = none(Slice[int])):
-    Table[string, Option[Slice[int]]] =
-  result = initTable[string, Option[Slice[int]]]()
+proc toTable*(pattern: CaptureBounds, default = none(Slice[int, int])):
+    Table[string, Option[Slice[int, int]]] =
+  result = initTable[string, Option[Slice[int, int]]]()
   toTableImpl(nextVal.isNone)
 
 template itemsImpl(cond: untyped) {.dirty.} =
-  for i in 0 .. <RegexMatch(pattern).pattern.captureCount:
+  for i in 0 ..< RegexMatch(pattern).pattern.captureCount:
     let nextVal = pattern[i]
     # done in this roundabout way to avoid multiple yields (potential code
     # bloat)
@@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} =
     yield nextYieldVal
 
 
-iterator items*(pattern: CaptureBounds, default = none(Slice[int])): Option[Slice[int]] =
+iterator items*(pattern: CaptureBounds, default = none(Slice[int, int])): Option[Slice[int, int]] =
   itemsImpl(nextVal.isNone)
 
 iterator items*(pattern: Captures, default: string = nil): string =
   itemsImpl(nextVal == nil)
 
-proc toSeq*(pattern: CaptureBounds, default = none(Slice[int])): seq[Option[Slice[int]]] =
+proc toSeq*(pattern: CaptureBounds, default = none(Slice[int, int])): seq[Option[Slice[int, int]]] =
   accumulateResult(pattern.items(default))
 
 proc toSeq*(pattern: Captures, default: string = nil): seq[string] =
@@ -396,8 +396,6 @@ proc extractOptions(pattern: string): tuple[pattern: string, flags: int, study:
 
 # }}}
 
-type UncheckedArray {.unchecked.}[T] = array[0 .. 0, T]
-
 proc destroyRegex(pattern: Regex) =
   pcre.free_substring(cast[cstring](pattern.pcreObj))
   pattern.pcreObj = nil
@@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] =
 
   result = initTable[string, int]()
 
-  for i in 0 .. <entryCount:
+  for i in 0 ..< entryCount:
     let pos = i * entrySize
     let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
     var name = ""
@@ -464,7 +462,7 @@ proc matchImpl(str: string, pattern: Regex, start, endpos: int, flags: int): Opt
   # 1x capture count as slack space for PCRE
   let vecsize = (pattern.captureCount() + 1) * 3
   # div 2 because each element is 2 cints long
-  myResult.pcreMatchBounds = newSeq[Slice[cint]](ceil(vecsize / 2).int)
+  myResult.pcreMatchBounds = newSeq[Slice[cint, cint]](ceil(vecsize / 2).int)
   myResult.pcreMatchBounds.setLen(vecsize div 3)
 
   let strlen = if endpos == int.high: str.len else: endpos+1
diff --git a/lib/pure/matchers.nim b/lib/pure/matchers.nim
index 7022c21d9..36daef8d1 100644
--- a/lib/pure/matchers.nim
+++ b/lib/pure/matchers.nim
@@ -48,7 +48,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect,
      "aero", "jobs", "museum": return true
   else: return false
 
-proc parseInt*(s: string, value: var int, validRange: Slice[int]) {.
+proc parseInt*(s: string, value: var int, validRange: Slice[int, int]) {.
   noSideEffect, rtl, extern: "nmatchParseInt".} =
   ## parses `s` into an integer in the range `validRange`. If successful,
   ## `value` is modified to contain the result. Otherwise no exception is
diff --git a/lib/system.nim b/lib/system.nim
index 3ea2d8ef8..b15cb16f0 100644
--- a/lib/system.nim
+++ b/lib/system.nim
@@ -323,7 +323,7 @@ proc `..`*[T, U](a: T, b: U): Slice[T, U] {.noSideEffect, inline, magic: "DotDot
   result.a = a
   result.b = b
 
-proc `..`*[T](b: T): Slice[T, T] {.noSideEffect, inline, magic: "DotDot".} =
+proc `..`*[T](b: T): Slice[int, T] {.noSideEffect, inline, magic: "DotDot".} =
   ## `slice`:idx: operator that constructs an interval ``[default(T), b]``
   result.b = b
 
diff --git a/tests/array/troof1.nim b/tests/array/troof1.nim
index 96669a121..9df012e6a 100644
--- a/tests/array/troof1.nim
+++ b/tests/array/troof1.nim
@@ -1,7 +1,6 @@
 discard """
   output: '''@[2, 3, 4]321
-9.0 4.0
-(a: 1.0, b: 2.0, c: 8.0)2.0'''
+9.0 4.0'''
 """
 
 proc foo[T](x, y: T): T = x
@@ -10,27 +9,3 @@ var a = @[1, 2, 3, 4]
 var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]]
 echo a[1.. ^1], a[^2], a[^3], a[^4]
 echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1]
-
-type
-  MyArray = object
-    a, b, c: float
-
-var
-  ma = MyArray(a: 1.0, b: 2.0, c: 3.0)
-
-proc len(x: MyArray): int = 3
-
-proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) =
-  case idx
-  of 0: x.a = val
-  of 1: x.b = val
-  of 2: x.c = val
-
-proc `[]`(x: var MyArray; idx: range[0..2]): float =
-  case idx
-  of 0: result = x.a
-  of 1: result = x.b
-  of 2: result = x.c
-
-ma[^1] = 8.0
-echo ma, ma[^2]
diff --git a/tests/array/troof2.nim b/tests/array/troof2.nim
deleted file mode 100644
index e4b4f4b3c..000000000
--- a/tests/array/troof2.nim
+++ /dev/null
@@ -1,10 +0,0 @@
-discard """
-  errormsg: "invalid context for '^' as 'foo()' has side effects"
-  line: "9"
-"""
-# XXX This needs to be fixed properly!
-proc foo(): seq[int] {.sideEffect.} =
-  echo "ha"
-
-let f = foo()[^1]
-
diff --git a/tests/array/troof3.nim b/tests/array/troof3.nim
index 4b6e22223..efe0eafb8 100644
--- a/tests/array/troof3.nim
+++ b/tests/array/troof3.nim
@@ -1,8 +1,7 @@
 discard """
-  errormsg: "invalid context for '^' as len!=high+1 for 'a'"
-  line: "8"
+  output: '''c'''
 """
 
-var a: array[1..3, string]
+var a: array['a'..'c', string] = ["a", "b", "c"]
 
 echo a[^1]
diff --git a/tests/array/troof4.nim b/tests/array/troof4.nim
deleted file mode 100644
index 7a262d9de..000000000
--- a/tests/array/troof4.nim
+++ /dev/null
@@ -1,37 +0,0 @@
-discard """
-  errormsg: "no surrounding array access context for '^'"
-  line: "37"
-"""
-
-proc foo[T](x, y: T): T = x
-
-var a = @[1, 2, 3, 4]
-var b: array[3, array[2, float]] = [[1.0,2], [3.0,4], [8.0,9]]
-echo a[1.. ^1], a[^2], a[^3], a[^4]
-echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1]
-
-type
-  MyArray = object
-    a, b, c: float
-
-var
-  ma = MyArray(a: 1.0, b: 2.0, c: 3.0)
-
-proc len(x: MyArray): int = 3
-
-proc `[]=`(x: var MyArray; idx: range[0..2]; val: float) =
-  case idx
-  of 0: x.a = val
-  of 1: x.b = val
-  of 2: x.c = val
-
-proc `[]`(x: var MyArray; idx: range[0..2]): float =
-  case idx
-  of 0: result = x.a
-  of 1: result = x.b
-  of 2: result = x.c
-
-ma[^1] = 8.0
-echo ma, ma[^2]
-
-echo(^1)
diff --git a/tests/stdlib/nre/captures.nim b/tests/stdlib/nre/captures.nim
index 19c344a8d..fa01a2000 100644
--- a/tests/stdlib/nre/captures.nim
+++ b/tests/stdlib/nre/captures.nim
@@ -32,7 +32,7 @@ suite "captures":
   test "named capture bounds":
     let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
     check(ex1.captureBounds["foo"] == some(0..2))
-    check(ex1.captureBounds["bar"] == none(Slice[int]))
+    check(ex1.captureBounds["bar"] == none(Slice[int, int]))
 
   test "capture count":
     let ex1 = re("(?<foo>foo)(?<bar>bar)?")
@@ -42,7 +42,7 @@ suite "captures":
   test "named capture table":
     let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
     check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable())
-    check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int])}.toTable())
+    check(ex1.captureBounds.toTable == {"foo" : some(0..2), "bar" : none(Slice[int, int])}.toTable())
     check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable())
 
     let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
@@ -51,7 +51,7 @@ suite "captures":
   test "capture sequence":
     let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
     check(ex1.captures.toSeq == @["foo", nil])
-    check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int])])
+    check(ex1.captureBounds.toSeq == @[some(0..2), none(Slice[int, int])])
     check(ex1.captures.toSeq("") == @["foo", ""])
 
     let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
diff --git a/tests/stdlib/nre/find.nim b/tests/stdlib/nre/find.nim
index caa953ff4..c37ac56ba 100644
--- a/tests/stdlib/nre/find.nim
+++ b/tests/stdlib/nre/find.nim
@@ -12,7 +12,7 @@ suite "find":
 
   test "find bounds":
     check(toSeq(findIter("1 2 3 4 5 ", re" ")).map(
-      proc (a: RegexMatch): Slice[int] = a.matchBounds
+      proc (a: RegexMatch): Slice[int, int] = a.matchBounds
     ) == @[1..1, 3..3, 5..5, 7..7, 9..9])
 
   test "overlapping find":