Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

int128 on firstOrd, lastOrd and lengthOrd #11701

Merged
merged 17 commits into from Aug 7, 2019
Merged
78 changes: 60 additions & 18 deletions compiler/ast.nim
Expand Up @@ -10,7 +10,9 @@
# abstract syntax tree + symbol table

import
lineinfos, hashes, options, ropes, idents, idgen
lineinfos, hashes, options, ropes, idents, idgen, int128

export int128

type
TCallingConvention* = enum
Expand Down Expand Up @@ -1055,7 +1057,7 @@ template `[]`*(n: Indexable, i: BackwardsIndex): Indexable = n[n.len - i.int]
template `[]=`*(n: Indexable, i: BackwardsIndex; x: Indexable) = n[n.len - i.int] = x

when defined(useNodeIds):
const nodeIdToDebug* = -1 # 299750 # 300761 #300863 # 300879
const nodeIdToDebug* = 2322967# 2322968
var gNodeId: int

proc newNode*(kind: TNodeKind): PNode =
Expand Down Expand Up @@ -1233,10 +1235,48 @@ proc newIntNode*(kind: TNodeKind, intVal: BiggestInt): PNode =
result = newNode(kind)
result.intVal = intVal

proc newIntTypeNode*(kind: TNodeKind, intVal: BiggestInt, typ: PType): PNode =
result = newIntNode(kind, intVal)
proc newIntNode*(kind: TNodeKind, intVal: Int128): PNode =
result = newNode(kind)
result.intVal = castToInt64(intVal)

proc lastSon*(n: PType): PType = n.sons[^1]

proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
## Used throughout the compiler code to test whether a type tree contains or
## doesn't contain a specific type/types - it is often the case that only the
## last child nodes of a type tree need to be searched. This is a really hot
## path within the compiler!
result = t
while result.kind in kinds: result = lastSon(result)

proc newIntTypeNode*(intVal: BiggestInt, typ: PType): PNode =

# this is dirty. abstractVarRange isn't defined yet and therefor it
# is duplicated here.
const abstractVarRange = {tyGenericInst, tyRange, tyVar, tyDistinct, tyOrdinal,
tyTypeDesc, tyAlias, tyInferred, tySink, tyOwned}
case skipTypes(typ, abstractVarRange).kind
of tyInt: result = newNode(nkIntLit)
of tyInt8: result = newNode(nkInt8Lit)
of tyInt16: result = newNode(nkInt16Lit)
of tyInt32: result = newNode(nkInt32Lit)
of tyInt64: result = newNode(nkInt64Lit)
of tyChar: result = newNode(nkCharLit)
of tyUInt: result = newNode(nkUIntLit)
of tyUInt8: result = newNode(nkUInt8Lit)
of tyUInt16: result = newNode(nkUInt16Lit)
of tyUInt32: result = newNode(nkUInt32Lit)
of tyUInt64: result = newNode(nkUInt64Lit)
else: # tyBool, tyEnum
# XXX: does this really need to be the kind nkIntLit?
result = newNode(nkIntLit)
result.intVal = intVal
result.typ = typ

proc newIntTypeNode*(intVal: Int128, typ: PType): PNode =
# XXX: introduce range check
newIntTypeNode(castToInt64(intVal), typ)

proc newFloatNode*(kind: TNodeKind, floatVal: BiggestFloat): PNode =
result = newNode(kind)
result.floatVal = floatVal
Expand Down Expand Up @@ -1325,7 +1365,6 @@ proc sonsLen*(n: PType): int = n.sons.len
proc len*(n: PType): int = n.sons.len
proc sonsLen*(n: PNode): int = n.sons.len
proc lastSon*(n: PNode): PNode = n.sons[^1]
proc lastSon*(n: PType): PType = n.sons[^1]

proc assignType*(dest, src: PType) =
dest.kind = src.kind
Expand Down Expand Up @@ -1421,14 +1460,6 @@ proc initNodeTable*(x: var TNodeTable) =
x.counter = 0
newSeq(x.data, StartSize)

proc skipTypes*(t: PType, kinds: TTypeKinds): PType =
## Used throughout the compiler code to test whether a type tree contains or
## doesn't contain a specific type/types - it is often the case that only the
## last child nodes of a type tree need to be searched. This is a really hot
## path within the compiler!
result = t
while result.kind in kinds: result = lastSon(result)

proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
result = t
var i = maxIters
Expand Down Expand Up @@ -1604,14 +1635,25 @@ proc hasSubnodeWith*(n: PNode, kind: TNodeKind): bool =
return true
result = false

proc getInt*(a: PNode): BiggestInt =
proc getInt*(a: PNode): Int128 =
case a.kind
of nkCharLit, nkUIntLit..nkUInt64Lit:
result = toInt128(cast[uint64](a.intVal))
of nkInt8Lit..nkInt64Lit:
result = toInt128(a.intVal)
of nkIntLit:
# XXX: enable this assert
# assert a.typ.kind notin {tyChar, tyUint..tyUInt64}
result = toInt128(a.intVal)
else:
raiseRecoverableError("cannot extract number from invalid AST node")

proc getInt64*(a: PNode): int64 {.deprecated: "use getInt".} =
case a.kind
of nkCharLit..nkUInt64Lit: result = a.intVal
of nkCharLit, nkUIntLit..nkUInt64Lit, nkIntLit..nkInt64Lit:
result = a.intVal
else:
raiseRecoverableError("cannot extract number from invalid AST node")
#internalError(a.info, "getInt")
#doAssert false, "getInt"
#result = 0

proc getFloat*(a: PNode): BiggestFloat =
case a.kind
Expand Down
2 changes: 1 addition & 1 deletion compiler/ccgcalls.nim
Expand Up @@ -92,7 +92,7 @@ proc openArrayLoc(p: BProc, n: PNode): Rope =
let ty = skipTypes(a.t, abstractVar+{tyPtr})
case ty.kind
of tyArray:
let first = firstOrd(p.config, ty)
let first = toInt64(firstOrd(p.config, ty))
if first == 0:
result = "($1)+($2), ($3)-($2)+1" % [rdLoc(a), rdLoc(b), rdLoc(c)]
else:
Expand Down
5 changes: 4 additions & 1 deletion compiler/ccgexprs.nim
Expand Up @@ -30,6 +30,9 @@ proc intLiteral(i: BiggestInt): Rope =
else:
result = ~"(IL64(-9223372036854775807) - IL64(1))"

proc intLiteral(i: Int128): Rope =
intLiteral(toInt64(i))

proc genLiteral(p: BProc, n: PNode, ty: PType): Rope =
case n.kind
of nkCharLit..nkUInt64Lit:
Expand Down Expand Up @@ -1436,7 +1439,7 @@ proc genArrToSeq(p: BProc, n: PNode, d: var TLoc) =
if d.k == locNone:
getTemp(p, n.typ, d)
# generate call to newSeq before adding the elements per hand:
let L = int(lengthOrd(p.config, n.sons[1].typ))
let L = toInt(lengthOrd(p.config, n.sons[1].typ))
if p.config.selectedGC == gcDestructors:
let seqtype = n.typ
linefmt(p, cpsStmts, "$1.len = $2; $1.p = ($4*) #newSeqPayload($2, sizeof($3));$n",
Expand Down
4 changes: 3 additions & 1 deletion compiler/ccgliterals.nim
Expand Up @@ -7,6 +7,8 @@
# distribution, for details about the copyright.
#

# included from cgen.nim

## This include file contains the logic to produce constant string
## and seq literals. The code here is responsible that
## ``const x = ["a", "b"]`` works without hidden runtime creation code.
Expand All @@ -19,7 +21,7 @@ template detectVersion(field, corename) =
if core == nil or core.kind != skConst:
m.g.field = 1
else:
m.g.field = int ast.getInt(core.ast)
m.g.field = toInt(ast.getInt(core.ast))
result = m.g.field

proc detectStrVersion(m: BModule): int =
Expand Down
10 changes: 5 additions & 5 deletions compiler/ccgstmts.nim
Expand Up @@ -246,10 +246,10 @@ proc genGotoState(p: BProc, n: PNode) =
lineF(p, cpsStmts, " goto BeforeRet_;$n", [])
var statesCounter = lastOrd(p.config, n.sons[0].typ)
if n.len >= 2 and n[1].kind == nkIntLit:
statesCounter = n[1].intVal
statesCounter = getInt(n[1])
let prefix = if n.len == 3 and n[2].kind == nkStrLit: n[2].strVal.rope
else: rope"STATE"
for i in 0i64 .. statesCounter:
for i in 0i64 .. toInt64(statesCounter):
lineF(p, cpsStmts, "case $2: goto $1$2;$n", [prefix, rope(i)])
lineF(p, cpsStmts, "}$n", [])

Expand Down Expand Up @@ -494,7 +494,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
if aSize > 10_000:
localError(p.config, it.info,
"case statement has too many cases for computed goto"); return
arraySize = aSize.int
arraySize = toInt(aSize)
if firstOrd(p.config, it.sons[0].typ) != 0:
localError(p.config, it.info,
"case statement has to start at 0 for computed goto"); return
Expand Down Expand Up @@ -527,7 +527,7 @@ proc genComputedGoto(p: BProc; n: PNode) =
return

let val = getOrdValue(it.sons[j])
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(val+id+1)])
lineF(p, cpsStmts, "TMP$#_:$n", [intLiteral(toInt64(val)+id+1)])

genStmts(p, it.lastSon)

Expand Down Expand Up @@ -1211,7 +1211,7 @@ proc genDiscriminantCheck(p: BProc, a, tmp: TLoc, objtype: PType,
var t = skipTypes(objtype, abstractVar)
assert t.kind == tyObject
discard genTypeInfo(p.module, t, a.lode.info)
var L = lengthOrd(p.config, field.typ)
var L = toInt64(lengthOrd(p.config, field.typ))
if not containsOrIncl(p.module.declaredThings, field.id):
appcg(p.module, cfsVars, "extern $1",
[discriminatorTableDecl(p.module, t, field)])
Expand Down
8 changes: 5 additions & 3 deletions compiler/ccgtypes.nim
Expand Up @@ -805,7 +805,7 @@ proc getTypeDescAux(m: BModule, origTyp: PType, check: var IntSet): Rope =
let foo = getTypeDescAux(m, t.sons[0], check)
addf(m.s[cfsTypes], "typedef $1 $2[1];$n", [foo, result])
of tyArray:
var n: BiggestInt = lengthOrd(m.config, t)
var n: BiggestInt = toInt64(lengthOrd(m.config, t))
if n <= 0: n = 1 # make an array of at least one element
result = getTypeName(m, origTyp, sig)
m.typeCache[sig] = result
Expand Down Expand Up @@ -1047,6 +1047,8 @@ proc discriminatorTableName(m: BModule, objtype: PType, d: PSym): Rope =
internalError(m.config, d.info, "anonymous obj with discriminator")
result = "NimDT_$1_$2" % [rope($hashType(objtype)), rope(d.name.s.mangle)]

proc rope(arg: Int128): Rope = rope($arg)

proc discriminatorTableDecl(m: BModule, objtype: PType, d: PSym): Rope =
discard cgsym(m, "TNimNode")
var tmp = discriminatorTableName(m, objtype, d)
Expand Down Expand Up @@ -1105,8 +1107,8 @@ proc genObjectFields(m: BModule, typ, origType: PType, n: PNode, expr: Rope;
internalError(m.config, b.info, "genObjectFields; nkOfBranch broken")
for j in 0 .. sonsLen(b) - 2:
if b.sons[j].kind == nkRange:
var x = int(getOrdValue(b.sons[j].sons[0]))
var y = int(getOrdValue(b.sons[j].sons[1]))
var x = toInt(getOrdValue(b.sons[j].sons[0]))
var y = toInt(getOrdValue(b.sons[j].sons[1]))
while x <= y:
addf(m.s[cfsTypeInit3], "$1[$2] = &$3;$n", [tmp, rope(x), tmp2])
inc(x)
Expand Down
3 changes: 3 additions & 0 deletions compiler/cgen.nim
Expand Up @@ -113,6 +113,9 @@ proc cgFormatValue(result: var string; value: string): void =
proc cgFormatValue(result: var string; value: BiggestInt): void =
result.addInt value

proc cgFormatValue(result: var string; value: Int128): void =
result.addInt128 value

# TODO: please document
macro ropecg(m: BModule, frmt: static[FormatStr], args: untyped): Rope =
args.expectKind nnkBracket
Expand Down
12 changes: 6 additions & 6 deletions compiler/closureiters.nim
Expand Up @@ -174,7 +174,7 @@ proc newStateAssgn(ctx: var Ctx, toValue: PNode): PNode =
proc newStateAssgn(ctx: var Ctx, stateNo: int = -2): PNode =
# Creates state assignment:
# :state = stateNo
ctx.newStateAssgn(newIntTypeNode(nkIntLit, stateNo, ctx.g.getSysType(TLineInfo(), tyInt)))
ctx.newStateAssgn(newIntTypeNode(stateNo, ctx.g.getSysType(TLineInfo(), tyInt)))

proc newEnvVar(ctx: var Ctx, name: string, typ: PType): PSym =
result = newSym(skVar, getIdent(ctx.g.cache, name), ctx.fn, ctx.fn.info)
Expand Down Expand Up @@ -359,7 +359,7 @@ proc addElseToExcept(ctx: var Ctx, n: PNode) =
block: # :unrollFinally = true
branchBody.add(newTree(nkAsgn,
ctx.newUnrollFinallyAccess(n.info),
newIntTypeNode(nkIntLit, 1, ctx.g.getSysType(n.info, tyBool))))
newIntTypeNode(1, ctx.g.getSysType(n.info, tyBool))))

block: # :curExc = getCurrentException()
branchBody.add(newTree(nkAsgn,
Expand Down Expand Up @@ -832,7 +832,7 @@ proc transformReturnsInTry(ctx: var Ctx, n: PNode): PNode =
block: # :unrollFinally = true
let asgn = newNodeI(nkAsgn, n.info)
asgn.add(ctx.newUnrollFinallyAccess(n.info))
asgn.add(newIntTypeNode(nkIntLit, 1, ctx.g.getSysType(n.info, tyBool)))
asgn.add(newIntTypeNode(1, ctx.g.getSysType(n.info, tyBool)))
result.add(asgn)

if n[0].kind != nkEmpty:
Expand Down Expand Up @@ -1162,7 +1162,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "==", mEqI).newSymNode(),
ctx.newStateAccess(),
newIntTypeNode(nkIntLit, 0, intTyp))
newIntTypeNode(0, intTyp))
cond.typ = boolTyp

let raiseStmt = newTree(nkRaiseStmt, ctx.g.emptyNode)
Expand All @@ -1174,7 +1174,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
block:
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "<", mLtI).newSymNode,
newIntTypeNode(nkIntLit, 0, intTyp),
newIntTypeNode(0, intTyp),
ctx.newStateAccess())
cond.typ = boolTyp

Expand All @@ -1186,7 +1186,7 @@ proc newCatchBody(ctx: var Ctx, info: TLineInfo): PNode {.inline.} =
let cond = newTree(nkCall,
ctx.g.getSysMagic(info, "<", mLtI).newSymNode,
ctx.newStateAccess(),
newIntTypeNode(nkIntLit, 0, intTyp))
newIntTypeNode(0, intTyp))
cond.typ = boolTyp

let negateState = newTree(nkCall,
Expand Down
4 changes: 2 additions & 2 deletions compiler/guards.nim
Expand Up @@ -10,7 +10,7 @@
## This module implements the 'implies' relation for guards.

import ast, astalgo, msgs, magicsys, nimsets, trees, types, renderer, idents,
saturate, modulegraphs, options, lineinfos
saturate, modulegraphs, options, lineinfos, int128

const
someEq = {mEqI, mEqF64, mEqEnum, mEqCh, mEqB, mEqRef, mEqProc,
Expand Down Expand Up @@ -522,7 +522,7 @@ proc geImpliesIn(x, c, aSet: PNode): TImplication =
var value = newIntNode(c.kind, c.intVal)
let max = lastOrd(nil, x.typ)
# don't iterate too often:
if max - value.intVal < 1000:
if max - getInt(value) < toInt128(1000):
var i, pos, neg: int
while value.intVal <= max:
if inSet(aSet, value): inc pos
Expand Down