literal array indices (#11424)

This commit is contained in:
Jasper Jenkins 2019-06-18 05:16:33 -07:00 • committed by Andreas Rumpf
commit 8ee0f14ab6
5 changed files with 44 additions and 4 deletions

View file

@ -527,16 +527,24 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
result = newNodeI(nkBracket, n.info)
result.typ = newTypeS(tyArray, c)
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:
rawAddSon(result.typ, newTypeS(tyEmpty, c)) # needs an empty basetype!
lastIndex = -1
else:
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:
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
lastValidIndex = lastOrd(c.config, indexType)
x = x.sons[1]
let yy = semExprWithType(c, x)
@ -544,6 +552,12 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
addSon(result, yy)
#var typ = skipTypes(result.sons[0].typ, {tyGenericInst, tyVar, tyLent, tyOrdinal})
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]
if x.kind == nkExprColonExpr and sonsLen(x) == 2:
var idx = semConstExpr(c, x.sons[0])
@ -561,7 +575,8 @@ proc semArrayConstr(c: PContext, n: PNode, flags: TExprFlags): PNode =
addSonSkipIntLit(result.typ, typ)
for i in 0 ..< result.len:
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) =
for i in 1 ..< n.len: