remove old implementation of the roof operator; make tests green again; close #6292
This commit is contained in:
parent
d52a1061b3
commit
f1dab39086
13 changed files with 28 additions and 161 deletions
|
|
@ -37,7 +37,6 @@ type
|
||||||
# in standalone ``except`` and ``finally``
|
# in standalone ``except`` and ``finally``
|
||||||
next*: PProcCon # used for stacking procedure contexts
|
next*: PProcCon # used for stacking procedure contexts
|
||||||
wasForwarded*: bool # whether the current proc has a separate header
|
wasForwarded*: bool # whether the current proc has a separate header
|
||||||
bracketExpr*: PNode # current bracket expression (for ^ support)
|
|
||||||
mapping*: TIdTable
|
mapping*: TIdTable
|
||||||
|
|
||||||
TMatchedConcept* = object
|
TMatchedConcept* = object
|
||||||
|
|
|
||||||
|
|
@ -1189,7 +1189,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
tyCString:
|
tyCString:
|
||||||
if n.len != 2: return nil
|
if n.len != 2: return nil
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
c.p.bracketExpr = n.sons[0]
|
|
||||||
for i in countup(1, sonsLen(n) - 1):
|
for i in countup(1, sonsLen(n) - 1):
|
||||||
n.sons[i] = semExprWithType(c, n.sons[i],
|
n.sons[i] = semExprWithType(c, n.sons[i],
|
||||||
flags*{efInTypeof, efDetermineType})
|
flags*{efInTypeof, efDetermineType})
|
||||||
|
|
@ -1210,7 +1209,6 @@ proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
of tyTuple:
|
of tyTuple:
|
||||||
if n.len != 2: return nil
|
if n.len != 2: return nil
|
||||||
n.sons[0] = makeDeref(n.sons[0])
|
n.sons[0] = makeDeref(n.sons[0])
|
||||||
c.p.bracketExpr = n.sons[0]
|
|
||||||
# [] operator for tuples requires constant expression:
|
# [] operator for tuples requires constant expression:
|
||||||
n.sons[1] = semConstExpr(c, n.sons[1])
|
n.sons[1] = semConstExpr(c, n.sons[1])
|
||||||
if skipTypes(n.sons[1].typ, {tyGenericInst, tyRange, tyOrdinal, tyAlias}).kind in
|
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:
|
of skType:
|
||||||
result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
|
result = symNodeFromType(c, semTypeNode(c, n, nil), n.info)
|
||||||
else:
|
else:
|
||||||
c.p.bracketExpr = n.sons[0]
|
discard
|
||||||
else:
|
|
||||||
c.p.bracketExpr = n.sons[0]
|
|
||||||
|
|
||||||
proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
proc semArrayAccess(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
let oldBracketExpr = c.p.bracketExpr
|
|
||||||
result = semSubscript(c, n, flags)
|
result = semSubscript(c, n, flags)
|
||||||
if result == nil:
|
if result == nil:
|
||||||
# overloaded [] operator:
|
# overloaded [] operator:
|
||||||
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]"))
|
result = semExpr(c, buildOverloadedSubscripts(n, getIdent"[]"))
|
||||||
c.p.bracketExpr = oldBracketExpr
|
|
||||||
|
|
||||||
proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
proc propertyWriteAccess(c: PContext, n, nOrig, a: PNode): PNode =
|
||||||
var id = considerQuotedIdent(a[1], a)
|
var id = considerQuotedIdent(a[1], a)
|
||||||
|
|
@ -1330,7 +1324,6 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
of nkBracketExpr:
|
of nkBracketExpr:
|
||||||
# a[i] = x
|
# a[i] = x
|
||||||
# --> `[]=`(a, i, x)
|
# --> `[]=`(a, i, x)
|
||||||
let oldBracketExpr = c.p.bracketExpr
|
|
||||||
a = semSubscript(c, a, {efLValue})
|
a = semSubscript(c, a, {efLValue})
|
||||||
if a == nil:
|
if a == nil:
|
||||||
result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=")
|
result = buildOverloadedSubscripts(n.sons[0], getIdent"[]=")
|
||||||
|
|
@ -1340,9 +1333,7 @@ proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode =
|
||||||
return n
|
return n
|
||||||
else:
|
else:
|
||||||
result = semExprNoType(c, result)
|
result = semExprNoType(c, result)
|
||||||
c.p.bracketExpr = oldBracketExpr
|
|
||||||
return result
|
return result
|
||||||
c.p.bracketExpr = oldBracketExpr
|
|
||||||
of nkCurlyExpr:
|
of nkCurlyExpr:
|
||||||
# a{i} = x --> `{}=`(a, i, x)
|
# a{i} = x --> `{}=`(a, i, x)
|
||||||
result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=")
|
result = buildOverloadedSubscripts(n.sons[0], getIdent"{}=")
|
||||||
|
|
|
||||||
|
|
@ -38,9 +38,7 @@ proc skipAddr(n: PNode): PNode {.inline.} =
|
||||||
proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
||||||
result = newNodeI(nkBracketExpr, n.info)
|
result = newNodeI(nkBracketExpr, n.info)
|
||||||
for i in 1..<n.len: result.add(n[i])
|
for i in 1..<n.len: result.add(n[i])
|
||||||
let oldBracketExpr = c.p.bracketExpr
|
|
||||||
result = semSubscript(c, result, flags)
|
result = semSubscript(c, result, flags)
|
||||||
c.p.bracketExpr = oldBracketExpr
|
|
||||||
if result.isNil:
|
if result.isNil:
|
||||||
let x = copyTree(n)
|
let x = copyTree(n)
|
||||||
x.sons[0] = newIdentNode(getIdent"[]", n.info)
|
x.sons[0] = newIdentNode(getIdent"[]", n.info)
|
||||||
|
|
@ -274,35 +272,7 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
of mDotDot:
|
of mDotDot:
|
||||||
result = n
|
result = n
|
||||||
of mRoof:
|
of mRoof:
|
||||||
let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr
|
localError(n.info, "builtin roof operator is not supported anymore")
|
||||||
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]
|
|
||||||
of mPlugin:
|
of mPlugin:
|
||||||
let plugin = getPlugin(n[0].sym)
|
let plugin = getPlugin(n[0].sym)
|
||||||
if plugin.isNil:
|
if plugin.isNil:
|
||||||
|
|
|
||||||
|
|
@ -113,13 +113,9 @@ type
|
||||||
owner: PSym
|
owner: PSym
|
||||||
cursorInBody: bool # only for nimsuggest
|
cursorInBody: bool # only for nimsuggest
|
||||||
scopeN: int
|
scopeN: int
|
||||||
bracketExpr: PNode
|
|
||||||
|
|
||||||
template withBracketExpr(ctx, x, body: untyped) =
|
template withBracketExpr(ctx, x, body: untyped) =
|
||||||
let old = ctx.bracketExpr
|
|
||||||
ctx.bracketExpr = x
|
|
||||||
body
|
body
|
||||||
ctx.bracketExpr = old
|
|
||||||
|
|
||||||
proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
|
proc getIdentNode(c: var TemplCtx, n: PNode): PNode =
|
||||||
case n.kind
|
case n.kind
|
||||||
|
|
@ -304,18 +300,6 @@ proc semTemplBodySons(c: var TemplCtx, n: PNode): PNode =
|
||||||
for i in 0 ..< n.len:
|
for i in 0 ..< n.len:
|
||||||
result.sons[i] = semTemplBody(c, n.sons[i])
|
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 =
|
proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = n
|
result = n
|
||||||
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
semIdeForTemplateOrGenericCheck(n, c.cursorInBody)
|
||||||
|
|
@ -506,8 +490,6 @@ proc semTemplBody(c: var TemplCtx, n: PNode): PNode =
|
||||||
result = semTemplBodySons(c, n)
|
result = semTemplBodySons(c, n)
|
||||||
of nkCallKinds-{nkPostfix}:
|
of nkCallKinds-{nkPostfix}:
|
||||||
result = semTemplBodySons(c, n)
|
result = semTemplBodySons(c, n)
|
||||||
if c.bracketExpr != nil and n.len == 2 and oprIsRoof(n.sons[0]):
|
|
||||||
result.add c.bracketExpr
|
|
||||||
of nkDotExpr, nkAccQuoted:
|
of nkDotExpr, nkAccQuoted:
|
||||||
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
|
# dotExpr is ambiguous: note that we explicitly allow 'x.TemplateParam',
|
||||||
# so we use the generic code for nkDotExpr too
|
# so we use the generic code for nkDotExpr too
|
||||||
|
|
|
||||||
|
|
@ -155,7 +155,7 @@ type
|
||||||
## - ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"``
|
## - ``"abc".match(re"(?<letter>\w)").captures["letter"] == "a"``
|
||||||
## - ``"abc".match(re"(\w)\w").captures[-1] == "ab"``
|
## - ``"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
|
## 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 above. If the capture is not filled, then ``None`` is returned.
|
||||||
## The bounds are both inclusive.
|
## The bounds are both inclusive.
|
||||||
|
|
@ -167,7 +167,7 @@ type
|
||||||
## ``match: string``
|
## ``match: string``
|
||||||
## the full text of the match.
|
## the full text of the match.
|
||||||
##
|
##
|
||||||
## ``matchBounds: Slice[int]``
|
## ``matchBounds: Slice[int, int]``
|
||||||
## the bounds of the match, as in ``captureBounds[]``
|
## the bounds of the match, as in ``captureBounds[]``
|
||||||
##
|
##
|
||||||
## ``(captureBounds|captures).toTable``
|
## ``(captureBounds|captures).toTable``
|
||||||
|
|
@ -182,7 +182,7 @@ type
|
||||||
## Not nil.
|
## Not nil.
|
||||||
str*: string ## The string that was matched against.
|
str*: string ## The string that was matched against.
|
||||||
## Not nil.
|
## Not nil.
|
||||||
pcreMatchBounds: seq[Slice[cint]] ## First item is the bounds of the match
|
pcreMatchBounds: seq[Slice[cint, cint]] ## First item is the bounds of the match
|
||||||
## Other items are the captures
|
## Other items are the captures
|
||||||
## `a` is inclusive start, `b` is exclusive end
|
## `a` is inclusive start, `b` is exclusive end
|
||||||
|
|
||||||
|
|
@ -251,13 +251,13 @@ proc captureBounds*(pattern: RegexMatch): CaptureBounds = return CaptureBounds(p
|
||||||
|
|
||||||
proc captures*(pattern: RegexMatch): Captures = return Captures(pattern)
|
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)
|
let pattern = RegexMatch(pattern)
|
||||||
if pattern.pcreMatchBounds[i + 1].a != -1:
|
if pattern.pcreMatchBounds[i + 1].a != -1:
|
||||||
let bounds = pattern.pcreMatchBounds[i + 1]
|
let bounds = pattern.pcreMatchBounds[i + 1]
|
||||||
return some(int(bounds.a) .. int(bounds.b-1))
|
return some(int(bounds.a) .. int(bounds.b-1))
|
||||||
else:
|
else:
|
||||||
return none(Slice[int])
|
return none(Slice[int, int])
|
||||||
|
|
||||||
proc `[]`*(pattern: Captures, i: int): string =
|
proc `[]`*(pattern: Captures, i: int): string =
|
||||||
let pattern = RegexMatch(pattern)
|
let pattern = RegexMatch(pattern)
|
||||||
|
|
@ -272,10 +272,10 @@ proc `[]`*(pattern: Captures, i: int): string =
|
||||||
proc match*(pattern: RegexMatch): string =
|
proc match*(pattern: RegexMatch): string =
|
||||||
return pattern.captures[-1]
|
return pattern.captures[-1]
|
||||||
|
|
||||||
proc matchBounds*(pattern: RegexMatch): Slice[int] =
|
proc matchBounds*(pattern: RegexMatch): Slice[int, int] =
|
||||||
return pattern.captureBounds[-1].get
|
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)
|
let pattern = RegexMatch(pattern)
|
||||||
return pattern.captureBounds[pattern.pattern.captureNameToId.fget(name)]
|
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]()
|
result = initTable[string, string]()
|
||||||
toTableImpl(nextVal == nil)
|
toTableImpl(nextVal == nil)
|
||||||
|
|
||||||
proc toTable*(pattern: CaptureBounds, default = none(Slice[int])):
|
proc toTable*(pattern: CaptureBounds, default = none(Slice[int, int])):
|
||||||
Table[string, Option[Slice[int]]] =
|
Table[string, Option[Slice[int, int]]] =
|
||||||
result = initTable[string, Option[Slice[int]]]()
|
result = initTable[string, Option[Slice[int, int]]]()
|
||||||
toTableImpl(nextVal.isNone)
|
toTableImpl(nextVal.isNone)
|
||||||
|
|
||||||
template itemsImpl(cond: untyped) {.dirty.} =
|
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]
|
let nextVal = pattern[i]
|
||||||
# done in this roundabout way to avoid multiple yields (potential code
|
# done in this roundabout way to avoid multiple yields (potential code
|
||||||
# bloat)
|
# bloat)
|
||||||
|
|
@ -309,13 +309,13 @@ template itemsImpl(cond: untyped) {.dirty.} =
|
||||||
yield nextYieldVal
|
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)
|
itemsImpl(nextVal.isNone)
|
||||||
|
|
||||||
iterator items*(pattern: Captures, default: string = nil): string =
|
iterator items*(pattern: Captures, default: string = nil): string =
|
||||||
itemsImpl(nextVal == nil)
|
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))
|
accumulateResult(pattern.items(default))
|
||||||
|
|
||||||
proc toSeq*(pattern: Captures, default: string = nil): seq[string] =
|
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) =
|
proc destroyRegex(pattern: Regex) =
|
||||||
pcre.free_substring(cast[cstring](pattern.pcreObj))
|
pcre.free_substring(cast[cstring](pattern.pcreObj))
|
||||||
pattern.pcreObj = nil
|
pattern.pcreObj = nil
|
||||||
|
|
@ -412,7 +410,7 @@ proc getNameToNumberTable(pattern: Regex): Table[string, int] =
|
||||||
|
|
||||||
result = initTable[string, int]()
|
result = initTable[string, int]()
|
||||||
|
|
||||||
for i in 0 .. <entryCount:
|
for i in 0 ..< entryCount:
|
||||||
let pos = i * entrySize
|
let pos = i * entrySize
|
||||||
let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
|
let num = (int(table[pos]) shl 8) or int(table[pos + 1]) - 1
|
||||||
var name = ""
|
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
|
# 1x capture count as slack space for PCRE
|
||||||
let vecsize = (pattern.captureCount() + 1) * 3
|
let vecsize = (pattern.captureCount() + 1) * 3
|
||||||
# div 2 because each element is 2 cints long
|
# 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)
|
myResult.pcreMatchBounds.setLen(vecsize div 3)
|
||||||
|
|
||||||
let strlen = if endpos == int.high: str.len else: endpos+1
|
let strlen = if endpos == int.high: str.len else: endpos+1
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ proc validEmailAddress*(s: string): bool {.noSideEffect,
|
||||||
"aero", "jobs", "museum": return true
|
"aero", "jobs", "museum": return true
|
||||||
else: return false
|
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".} =
|
noSideEffect, rtl, extern: "nmatchParseInt".} =
|
||||||
## parses `s` into an integer in the range `validRange`. If successful,
|
## parses `s` into an integer in the range `validRange`. If successful,
|
||||||
## `value` is modified to contain the result. Otherwise no exception is
|
## `value` is modified to contain the result. Otherwise no exception is
|
||||||
|
|
|
||||||
|
|
@ -323,7 +323,7 @@ proc `..`*[T, U](a: T, b: U): Slice[T, U] {.noSideEffect, inline, magic: "DotDot
|
||||||
result.a = a
|
result.a = a
|
||||||
result.b = b
|
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]``
|
## `slice`:idx: operator that constructs an interval ``[default(T), b]``
|
||||||
result.b = b
|
result.b = b
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,7 +1,6 @@
|
||||||
discard """
|
discard """
|
||||||
output: '''@[2, 3, 4]321
|
output: '''@[2, 3, 4]321
|
||||||
9.0 4.0
|
9.0 4.0'''
|
||||||
(a: 1.0, b: 2.0, c: 8.0)2.0'''
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
proc foo[T](x, y: T): T = x
|
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]]
|
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 a[1.. ^1], a[^2], a[^3], a[^4]
|
||||||
echo b[^1][^1], " ", (b[^2]).foo(b[^1])[^1]
|
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]
|
|
||||||
|
|
|
||||||
|
|
@ -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]
|
|
||||||
|
|
||||||
|
|
@ -1,8 +1,7 @@
|
||||||
discard """
|
discard """
|
||||||
errormsg: "invalid context for '^' as len!=high+1 for 'a'"
|
output: '''c'''
|
||||||
line: "8"
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
var a: array[1..3, string]
|
var a: array['a'..'c', string] = ["a", "b", "c"]
|
||||||
|
|
||||||
echo a[^1]
|
echo a[^1]
|
||||||
|
|
|
||||||
|
|
@ -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)
|
|
||||||
|
|
@ -32,7 +32,7 @@ suite "captures":
|
||||||
test "named capture bounds":
|
test "named capture bounds":
|
||||||
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
||||||
check(ex1.captureBounds["foo"] == some(0..2))
|
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":
|
test "capture count":
|
||||||
let ex1 = re("(?<foo>foo)(?<bar>bar)?")
|
let ex1 = re("(?<foo>foo)(?<bar>bar)?")
|
||||||
|
|
@ -42,7 +42,7 @@ suite "captures":
|
||||||
test "named capture table":
|
test "named capture table":
|
||||||
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
||||||
check(ex1.captures.toTable == {"foo" : "foo", "bar" : nil}.toTable())
|
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())
|
check(ex1.captures.toTable("") == {"foo" : "foo", "bar" : ""}.toTable())
|
||||||
|
|
||||||
let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
|
let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
|
||||||
|
|
@ -51,7 +51,7 @@ suite "captures":
|
||||||
test "capture sequence":
|
test "capture sequence":
|
||||||
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
let ex1 = "foo".find(re("(?<foo>foo)(?<bar>bar)?"))
|
||||||
check(ex1.captures.toSeq == @["foo", nil])
|
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", ""])
|
check(ex1.captures.toSeq("") == @["foo", ""])
|
||||||
|
|
||||||
let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
|
let ex2 = "foobar".find(re("(?<foo>foo)(?<bar>bar)?"))
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ suite "find":
|
||||||
|
|
||||||
test "find bounds":
|
test "find bounds":
|
||||||
check(toSeq(findIter("1 2 3 4 5 ", re" ")).map(
|
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])
|
) == @[1..1, 3..3, 5..5, 7..7, 9..9])
|
||||||
|
|
||||||
test "overlapping find":
|
test "overlapping find":
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue