fixes the most pressing regressions introduced by the new handling of a[i] in the compiler
This commit is contained in:
parent
c9a2fa54c7
commit
29a9166966
3 changed files with 45 additions and 15 deletions
|
|
@ -30,6 +30,13 @@ type
|
||||||
GenericCtx = object
|
GenericCtx = object
|
||||||
toMixin: IntSet
|
toMixin: IntSet
|
||||||
cursorInBody: bool # only for nimsuggest
|
cursorInBody: bool # only for nimsuggest
|
||||||
|
bracketExpr: PNode
|
||||||
|
|
||||||
|
template withBracketExpr(x, body: untyped) =
|
||||||
|
let old = ctx.bracketExpr
|
||||||
|
ctx.bracketExpr = x
|
||||||
|
body
|
||||||
|
ctx.bracketExpr = old
|
||||||
|
|
||||||
type
|
type
|
||||||
TSemGenericFlag = enum
|
TSemGenericFlag = enum
|
||||||
|
|
@ -227,6 +234,10 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
discard
|
discard
|
||||||
of skProc, skMethod, skIterators, skConverter, skModule:
|
of skProc, skMethod, skIterators, skConverter, skModule:
|
||||||
result.sons[0] = symChoice(c, fn, s, scOption)
|
result.sons[0] = symChoice(c, fn, s, scOption)
|
||||||
|
# do check of 's.magic==mRoof' here because it might be some
|
||||||
|
# other '^' but after overload resolution the proper one:
|
||||||
|
if ctx.bracketExpr != nil and n.len == 2 and s.name.s == "^":
|
||||||
|
result.add ctx.bracketExpr
|
||||||
first = 1
|
first = 1
|
||||||
of skGenericParam:
|
of skGenericParam:
|
||||||
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
|
result.sons[0] = newSymNodeTypeDesc(s, fn.info)
|
||||||
|
|
@ -251,12 +262,17 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
let flags = if mixinContext: flags+{withinMixin} else: flags
|
let flags = if mixinContext: flags+{withinMixin} else: flags
|
||||||
for i in countup(first, sonsLen(result) - 1):
|
for i in countup(first, sonsLen(result) - 1):
|
||||||
result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx)
|
result.sons[i] = semGenericStmt(c, result.sons[i], flags, ctx)
|
||||||
of nkBracketExpr, nkCurlyExpr:
|
of nkCurlyExpr:
|
||||||
result = newNodeI(nkCall, n.info)
|
result = newNodeI(nkCall, n.info)
|
||||||
result.add newIdentNode(getIdent(if n.kind == nkBracketExpr:"[]" else:"{}"),
|
result.add newIdentNode(getIdent("{}"), n.info)
|
||||||
n.info)
|
|
||||||
for i in 0 ..< n.len: result.add(n[i])
|
for i in 0 ..< n.len: result.add(n[i])
|
||||||
result = semGenericStmt(c, result, flags, ctx)
|
result = semGenericStmt(c, result, flags, ctx)
|
||||||
|
of nkBracketExpr:
|
||||||
|
result = newNodeI(nkCall, n.info)
|
||||||
|
result.add newIdentNode(getIdent("[]"), n.info)
|
||||||
|
for i in 0 ..< n.len: result.add(n[i])
|
||||||
|
withBracketExpr n.sons[0]:
|
||||||
|
result = semGenericStmt(c, result, flags, ctx)
|
||||||
of nkAsgn, nkFastAsgn:
|
of nkAsgn, nkFastAsgn:
|
||||||
checkSonsLen(n, 2)
|
checkSonsLen(n, 2)
|
||||||
let a = n.sons[0]
|
let a = n.sons[0]
|
||||||
|
|
@ -264,13 +280,19 @@ proc semGenericStmt(c: PContext, n: PNode,
|
||||||
|
|
||||||
let k = a.kind
|
let k = a.kind
|
||||||
case k
|
case k
|
||||||
of nkBracketExpr, nkCurlyExpr:
|
of nkCurlyExpr:
|
||||||
result = newNodeI(nkCall, n.info)
|
result = newNodeI(nkCall, n.info)
|
||||||
result.add newIdentNode(getIdent(if k == nkBracketExpr:"[]=" else:"{}="),
|
result.add newIdentNode(getIdent("{}="), n.info)
|
||||||
n.info)
|
|
||||||
for i in 0 ..< a.len: result.add(a[i])
|
for i in 0 ..< a.len: result.add(a[i])
|
||||||
result.add(b)
|
result.add(b)
|
||||||
result = semGenericStmt(c, result, flags, ctx)
|
result = semGenericStmt(c, result, flags, ctx)
|
||||||
|
of nkBracketExpr:
|
||||||
|
result = newNodeI(nkCall, n.info)
|
||||||
|
result.add newIdentNode(getIdent("[]="), n.info)
|
||||||
|
for i in 0 ..< a.len: result.add(a[i])
|
||||||
|
result.add(b)
|
||||||
|
withBracketExpr a.sons[0]:
|
||||||
|
result = semGenericStmt(c, result, flags, ctx)
|
||||||
else:
|
else:
|
||||||
for i in countup(0, sonsLen(n) - 1):
|
for i in countup(0, sonsLen(n) - 1):
|
||||||
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
|
result.sons[i] = semGenericStmt(c, n.sons[i], flags, ctx)
|
||||||
|
|
|
||||||
|
|
@ -32,6 +32,9 @@ type
|
||||||
proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode
|
proc semAsgn(c: PContext, n: PNode; mode=asgnNormal): PNode
|
||||||
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode
|
proc semSubscript(c: PContext, n: PNode, flags: TExprFlags): PNode
|
||||||
|
|
||||||
|
proc skipAddr(n: PNode): PNode {.inline.} =
|
||||||
|
(if n.kind == nkHiddenAddr: n.sons[0] else: n)
|
||||||
|
|
||||||
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])
|
||||||
|
|
@ -45,7 +48,8 @@ proc semArrGet(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
||||||
proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
proc semArrPut(c: PContext; n: PNode; flags: TExprFlags): PNode =
|
||||||
# rewrite `[]=`(a, i, x) back to ``a[i] = x``.
|
# rewrite `[]=`(a, i, x) back to ``a[i] = x``.
|
||||||
let b = newNodeI(nkBracketExpr, n.info)
|
let b = newNodeI(nkBracketExpr, n.info)
|
||||||
for i in 1..n.len-2: b.add(n[i])
|
b.add(n[1].skipAddr)
|
||||||
|
for i in 2..n.len-2: b.add(n[i])
|
||||||
result = newNodeI(nkAsgn, n.info, 2)
|
result = newNodeI(nkAsgn, n.info, 2)
|
||||||
result.sons[0] = b
|
result.sons[0] = b
|
||||||
result.sons[1] = n.lastSon
|
result.sons[1] = n.lastSon
|
||||||
|
|
@ -179,25 +183,28 @@ proc magicsAfterOverloadResolution(c: PContext, n: PNode,
|
||||||
if isNegative(n.sons[1]) or (n.len > 2 and isNegative(n.sons[2])):
|
if isNegative(n.sons[1]) or (n.len > 2 and isNegative(n.sons[2])):
|
||||||
localError(n.info, "use '^' instead of '-'; negative indexing is obsolete")
|
localError(n.info, "use '^' instead of '-'; negative indexing is obsolete")
|
||||||
of mRoof:
|
of mRoof:
|
||||||
# error correction:
|
let bracketExpr = if n.len == 3: n.sons[2] else: c.p.bracketExpr
|
||||||
result = n.sons[1]
|
if bracketExpr.isNil:
|
||||||
if c.p.bracketExpr.isNil:
|
|
||||||
localError(n.info, "no surrounding array access context for '^'")
|
localError(n.info, "no surrounding array access context for '^'")
|
||||||
elif c.p.bracketExpr.checkForSideEffects != seNoSideEffect:
|
result = n.sons[1]
|
||||||
|
elif bracketExpr.checkForSideEffects != seNoSideEffect:
|
||||||
localError(n.info, "invalid context for '^' as '$#' has side effects" %
|
localError(n.info, "invalid context for '^' as '$#' has side effects" %
|
||||||
renderTree(c.p.bracketExpr))
|
renderTree(bracketExpr))
|
||||||
elif c.p.bracketExpr.typ.isStrangeArray:
|
result = n.sons[1]
|
||||||
|
elif bracketExpr.typ.isStrangeArray:
|
||||||
localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" %
|
localError(n.info, "invalid context for '^' as len!=high+1 for '$#'" %
|
||||||
renderTree(c.p.bracketExpr))
|
renderTree(bracketExpr))
|
||||||
|
result = n.sons[1]
|
||||||
else:
|
else:
|
||||||
# ^x is rewritten to: len(a)-x
|
# ^x is rewritten to: len(a)-x
|
||||||
let lenExpr = newNodeI(nkCall, n.info)
|
let lenExpr = newNodeI(nkCall, n.info)
|
||||||
lenExpr.add newIdentNode(getIdent"len", n.info)
|
lenExpr.add newIdentNode(getIdent"len", n.info)
|
||||||
lenExpr.add c.p.bracketExpr
|
lenExpr.add bracketExpr
|
||||||
let lenExprB = semExprWithType(c, lenExpr)
|
let lenExprB = semExprWithType(c, lenExpr)
|
||||||
if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ):
|
if lenExprB.typ.isNil or not isOrdinalType(lenExprB.typ):
|
||||||
localError(n.info, "'$#' has to be of an ordinal type for '^'" %
|
localError(n.info, "'$#' has to be of an ordinal type for '^'" %
|
||||||
renderTree(lenExpr))
|
renderTree(lenExpr))
|
||||||
|
result = n.sons[1]
|
||||||
else:
|
else:
|
||||||
result = newNodeIT(nkCall, n.info, getSysType(tyInt))
|
result = newNodeIT(nkCall, n.info, getSysType(tyInt))
|
||||||
result.add newSymNode(createMagic("-", mSubI), n.info)
|
result.add newSymNode(createMagic("-", mSubI), n.info)
|
||||||
|
|
|
||||||
|
|
@ -3465,6 +3465,7 @@ proc procCall*(x: expr) {.magic: "ProcCall", compileTime.} =
|
||||||
## procCall someMethod(a, b)
|
## procCall someMethod(a, b)
|
||||||
discard
|
discard
|
||||||
|
|
||||||
|
proc `^`*[T](x: int; y: openArray[T]): int {.noSideEffect, magic: "Roof".}
|
||||||
proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
|
proc `^`*(x: int): int {.noSideEffect, magic: "Roof".} =
|
||||||
## builtin `roof`:idx: operator that can be used for convenient array access.
|
## builtin `roof`:idx: operator that can be used for convenient array access.
|
||||||
## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``
|
## ``a[^x]`` is rewritten to ``a[a.len-x]``. However currently the ``a``
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue