mirror of
https://github.com/nim-lang/Nim.git
synced 2025-12-28 17:04:41 +00:00
@@ -815,6 +815,7 @@ type
|
||||
# nodes are compared by structure!
|
||||
counter*: int
|
||||
data*: TNodePairSeq
|
||||
ignoreTypes*: bool
|
||||
|
||||
TObjectSeq* = seq[RootRef]
|
||||
TObjectSet* = object
|
||||
@@ -1637,8 +1638,8 @@ proc initObjectSet*(): TObjectSet =
|
||||
result = TObjectSet(counter: 0)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc initNodeTable*(): TNodeTable =
|
||||
result = TNodeTable(counter: 0)
|
||||
proc initNodeTable*(ignoreTypes=false): TNodeTable =
|
||||
result = TNodeTable(counter: 0, ignoreTypes: ignoreTypes)
|
||||
newSeq(result.data, StartSize)
|
||||
|
||||
proc skipTypes*(t: PType, kinds: TTypeKinds; maxIters: int): PType =
|
||||
|
||||
@@ -42,32 +42,37 @@ proc hashTree*(n: PNode): Hash =
|
||||
#echo "hashTree ", result
|
||||
#echo n
|
||||
|
||||
proc treesEquivalent(a, b: PNode): bool =
|
||||
proc treesEquivalent(a, b: PNode; ignoreTypes: bool): bool =
|
||||
if a == b:
|
||||
result = true
|
||||
elif (a != nil) and (b != nil) and (a.kind == b.kind):
|
||||
case a.kind
|
||||
of nkEmpty, nkNilLit, nkType: result = true
|
||||
of nkEmpty: result = true
|
||||
of nkSym: result = a.sym.id == b.sym.id
|
||||
of nkIdent: result = a.ident.id == b.ident.id
|
||||
of nkCharLit..nkUInt64Lit: result = a.intVal == b.intVal
|
||||
of nkFloatLit..nkFloat64Lit: result = a.floatVal == b.floatVal
|
||||
of nkFloatLit..nkFloat64Lit:
|
||||
result = cast[uint64](a.floatVal) == cast[uint64](b.floatVal)
|
||||
#result = a.floatVal == b.floatVal
|
||||
of nkStrLit..nkTripleStrLit: result = a.strVal == b.strVal
|
||||
of nkType, nkNilLit:
|
||||
result = a.typ == b.typ
|
||||
else:
|
||||
if a.len == b.len:
|
||||
for i in 0..<a.len:
|
||||
if not treesEquivalent(a[i], b[i]): return
|
||||
if not treesEquivalent(a[i], b[i], ignoreTypes): return
|
||||
result = true
|
||||
else:
|
||||
result = false
|
||||
if result: result = sameTypeOrNil(a.typ, b.typ)
|
||||
if result and not ignoreTypes:
|
||||
result = sameTypeOrNil(a.typ, b.typ)
|
||||
else:
|
||||
result = false
|
||||
|
||||
proc nodeTableRawGet(t: TNodeTable, k: Hash, key: PNode): int =
|
||||
var h: Hash = k and high(t.data)
|
||||
while t.data[h].key != nil:
|
||||
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key):
|
||||
if (t.data[h].h == k) and treesEquivalent(t.data[h].key, key, t.ignoreTypes):
|
||||
return h
|
||||
h = nextTry(h, high(t.data))
|
||||
result = -1
|
||||
|
||||
@@ -249,6 +249,7 @@ type
|
||||
# to not slow down interpretation
|
||||
globals*: PNode #
|
||||
constants*: PNode # constant data
|
||||
contstantTab*: TNodeTable
|
||||
types*: seq[PType] # some instructions reference types (e.g. 'except')
|
||||
currentExceptionA*, currentExceptionB*: PNode
|
||||
exceptionInstr*: int # index of instruction that raised the exception
|
||||
@@ -298,7 +299,8 @@ proc newCtx*(module: PSym; cache: IdentCache; g: ModuleGraph; idgen: IdGenerator
|
||||
prc: PProc(blocks: @[]), module: module, loopIterations: g.config.maxLoopIterationsVM,
|
||||
callDepth: g.config.maxCallDepthVM,
|
||||
comesFromHeuristic: unknownLineInfo, callbacks: @[], callbackIndex: initTable[string, int](), errorFlag: "",
|
||||
cache: cache, config: g.config, graph: g, idgen: idgen)
|
||||
cache: cache, config: g.config, graph: g, idgen: idgen,
|
||||
contstantTab: initNodeTable(true))
|
||||
|
||||
proc refresh*(c: PCtx, module: PSym; idgen: IdGenerator) =
|
||||
c.module = module
|
||||
|
||||
@@ -33,7 +33,8 @@ when defined(nimPreviewSlimSystem):
|
||||
|
||||
import
|
||||
ast, types, msgs, renderer, vmdef, trees,
|
||||
magicsys, options, lowerings, lineinfos, transf, astmsgs
|
||||
magicsys, options, lowerings, lineinfos, transf, astmsgs,
|
||||
treetab
|
||||
|
||||
from modulegraphs import getBody
|
||||
|
||||
@@ -478,10 +479,16 @@ proc sameConstant*(a, b: PNode): bool =
|
||||
result = true
|
||||
|
||||
proc genLiteral(c: PCtx; n: PNode): int =
|
||||
# types do not matter here:
|
||||
for i in 0..<c.constants.len:
|
||||
if sameConstant(c.constants[i], n): return i
|
||||
result = rawGenLiteral(c, n)
|
||||
result = nodeTableTestOrSet(c.contstantTab, n, c.constants.len)
|
||||
if result == c.constants.len:
|
||||
let lit = rawGenLiteral(c, n)
|
||||
assert lit == result
|
||||
|
||||
when false:
|
||||
# types do not matter here:
|
||||
for i in 0..<c.constants.len:
|
||||
if sameConstant(c.constants[i], n): return i
|
||||
result = rawGenLiteral(c, n)
|
||||
|
||||
proc unused(c: PCtx; n: PNode; x: TDest) {.inline.} =
|
||||
if x >= 0:
|
||||
@@ -1549,8 +1556,7 @@ template cannotEval(c: PCtx; n: PNode) =
|
||||
if c.config.cmd == cmdCheck and c.config.m.errorOutputs != {}:
|
||||
# nim check command with no error outputs doesn't need to cascade here,
|
||||
# includes `tryConstExpr` case which should not continue generating code
|
||||
localError(c.config, n.info, "cannot evaluate at compile time: " &
|
||||
n.renderTree)
|
||||
localError(c.config, n.info, "cannot evaluate at compile time: " & n.renderTree)
|
||||
c.cannotEval = true
|
||||
return
|
||||
globalError(c.config, n.info, "cannot evaluate at compile time: " &
|
||||
@@ -1888,7 +1894,7 @@ proc genCheckedObjAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
c.freeTemp(objR)
|
||||
|
||||
proc genArrAccess(c: PCtx; n: PNode; dest: var TDest; flags: TGenFlags) =
|
||||
if n[0].typ == nil:
|
||||
if n[0].typ == nil:
|
||||
globalError(c.config, n.info, "cannot access array with nil type")
|
||||
return
|
||||
|
||||
|
||||
Reference in New Issue
Block a user