literal array indices (#11424)
This commit is contained in:
parent
c99ce5051e
commit
8ee0f14ab6
5 changed files with 44 additions and 4 deletions
|
|
@ -527,16 +527,24 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
result = newNodeI(nkBracket, n.info)
|
result = newNodeI(nkBracket, n.info)
|
||||||
result.typ = newTypeS(tyArray, c)
|
result.typ = newTypeS(tyArray, c)
|
||||||
rawAddSon(result.typ, nil) # index type
|
rawAddSon(result.typ, nil) # index type
|
||||||
|
var
|
||||||
|
firstIndex, lastIndex: BiggestInt = 0
|
||||||
|
indexType = getSysType(c.graph, n.info, tyInt)
|
||||||
|
lastValidIndex = lastOrd(c.config, indexType)
|
||||||
if sonsLen(n) == 0:
|
if sonsLen(n) == 0:
|
||||||
rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
|
rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
|
||||||
|
lastIndex = -1
|
||||||
else:
|
else:
|
||||||
var x = n.sons[0]
|
var x = n.sons[0]
|
||||||
var lastIndex: BiggestInt = 0
|
|
||||||
var indexType = getSysType(c.graph, n.info, tyInt)
|
|
||||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||||
var idx = semConstExpr(c, x.sons[0])
|
var idx = semConstExpr(c, x.sons[0])
|
||||||
lastIndex = getOrdValue(idx)
|
if not isOrdinalType(idx.typ):
|
||||||
|
localError(c.config, idx.info, "expected ordinal value for array " &
|
||||||
|
"index, got '$1'" % renderTree(idx))
|
||||||
|
firstIndex = getOrdValue(idx)
|
||||||
|
lastIndex = firstIndex
|
||||||
indexType = idx.typ
|
indexType = idx.typ
|
||||||
|
lastValidIndex = lastOrd(c.config, indexType)
|
||||||
x = x.sons[1]
|
x = x.sons[1]
|
||||||
|
|
||||||
let yy = semExprWithType(c, x)
|
let yy = semExprWithType(c, x)
|
||||||
|
|
@ -544,6 +552,12 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
addSon(result, yy)
|
addSon(result, yy)
|
||||||
#var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
|
#var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
|
||||||
for i in 1 ..< sonsLen(n):
|
for i in 1 ..< sonsLen(n):
|
||||||
|
if lastIndex == lastValidIndex:
|
||||||
|
let validIndex = makeRangeType(c, firstIndex, lastValidIndex, n.info,
|
||||||
|
indexType)
|
||||||
|
localError(c.config, n.info, "size of array exceeds range of index " &
|
||||||
|
"type '$1' by $2 elements" % [typeToString(validIndex), $(n.len-i)])
|
||||||
|
|
||||||
x = n.sons[i]
|
x = n.sons[i]
|
||||||
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
|
||||||
var idx = semConstExpr(c, x.sons[0])
|
var idx = semConstExpr(c, x.sons[0])
|
||||||
|
|
@ -561,7 +575,8 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
|
||||||
addSonSkipIntLit(result.typ, typ)
|
addSonSkipIntLit(result.typ, typ)
|
||||||
for i in 0 ..< result.len:
|
for i in 0 ..< result.len:
|
||||||
result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info)
|
result.sons[i] = fitNode(c, typ, result.sons[i], result.sons[i].info)
|
||||||
result.typ.sons[0] = makeRangeType(c, 0, sonsLen(result) - 1, n.info)
|
result.typ.sons[0] = makeRangeType(c, firstIndex, lastIndex, n.info,
|
||||||
|
indexType)
|
||||||
|
|
||||||
proc fixAbstractType(c: PContext, n: PNode) =
|
proc fixAbstractType(c: PContext, n: PNode) =
|
||||||
for i in 1 ..< n.len:
|
for i in 1 ..< n.len:
|
||||||
|
|
|
||||||
|
|
@ -548,3 +548,12 @@ block t3899:
|
||||||
x.a[i]
|
x.a[i]
|
||||||
const c = O(a: [1.0,2.0])
|
const c = O(a: [1.0,2.0])
|
||||||
echo c[2]
|
echo c[2]
|
||||||
|
|
||||||
|
block arrayLiterals:
|
||||||
|
type ABC = enum A, B, C
|
||||||
|
template Idx[IdxT, ElemT](arr: array[IdxT, ElemT]): untyped = IdxT
|
||||||
|
doAssert [A: 0, B: 1].Idx is range[A..B]
|
||||||
|
doAssert [A: 0, 1, 3].Idx is ABC
|
||||||
|
doAssert [1: 2][1] == 2
|
||||||
|
doAssert [-1'i8: 2][-1] == 2
|
||||||
|
doAssert [-1'i8: 2, 3, 4, 5].Idx is range[-1'i8..2'i8]
|
||||||
|
|
|
||||||
6
tests/array/tidx_lit_err1.nim
Normal file
6
tests/array/tidx_lit_err1.nim
Normal file
|
|
@ -0,0 +1,6 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "size of array exceeds range of index type 'range 1..2(Color)' by 3 elements"
|
||||||
|
line: 6
|
||||||
|
"""
|
||||||
|
type Color = enum Red, Green, Blue
|
||||||
|
let y = [Green: 0, 1, 2, 3, 4]
|
||||||
5
tests/array/tidx_lit_err2.nim
Normal file
5
tests/array/tidx_lit_err2.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "expected ordinal value for array index, got '\"string\"'"
|
||||||
|
line: 5
|
||||||
|
"""
|
||||||
|
let x = ["string": 0, "index": 1]
|
||||||
5
tests/array/tidx_lit_err3.nim
Normal file
5
tests/array/tidx_lit_err3.nim
Normal file
|
|
@ -0,0 +1,5 @@
|
||||||
|
discard """
|
||||||
|
errormsg: "size of array exceeds range of index type 'range 2147483646..2147483647(int32)' by 1 elements"
|
||||||
|
line: 5
|
||||||
|
"""
|
||||||
|
echo [high(int32)-1: 1, 2, 3]
|
||||||
Loading…
Add table
Add a link
Reference in a new issue