1- import std/ [assertions, math]
1+ import std/ [assertions, math, tables ]
22import " ../../compiler/icnif" / [nifencoder, nifdecoder]
33import " ../../compiler" / [idents, ast, astalgo, options, pathutils, modulegraphs, modules, msgs, pipelines, syntaxes, sem, llstream, lineinfos]
44
6161 # this is used to prevent that happen.
6262 EqlContext = object
6363 nodeStack: seq [PNode ]
64- symStack: seq [PSym ]
65- typStack: seq [PType ]
64+ checkedSyms: Table [ItemId , PSym ] # used to check if each PSym has unique ItemId
65+ # and also prevents inifinite loop
66+ checkedTypes: Table [ItemId , PType ]# used like checkedSyms
6667 confX, confY: ConfigRef # used to print the line info when there is a mismatch
6768 # and get path from FileIndex
6869
@@ -134,12 +135,21 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
134135 elif x == nil or y == nil :
135136 echo " symbol is missing"
136137 result = false
137- elif x.name.s != y.name.s:
138- echo " symbol name mismatch: " , x.name.s, " /" , y.name.s
139- result = false
140138 elif not eqlItemId (x.itemId, y.itemId, c):
141139 echo " symbol itemId mismatch"
142140 result = false
141+ elif c.checkedSyms.hasKeyOrPut (y.itemId, y):
142+ if c.checkedSyms[y.itemId] == y:
143+ result = true
144+ else :
145+ echo " detected duplicated symbol ItemId:"
146+ debug (x)
147+ debug (c.checkedSyms[y.itemId])
148+ debug (y)
149+ result = false
150+ elif x.name.s != y.name.s:
151+ echo " symbol name mismatch: " , x.name.s, " /" , y.name.s
152+ result = false
143153 elif x.kind != y.kind:
144154 echo " symbol kind mismatch: " , x.kind, " /" , y.kind
145155 result = false
@@ -167,11 +177,6 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
167177 echo " symbol.loc mismatch"
168178 result = false
169179 else :
170- if c.symStack.len != 0 :
171- for i in countDown (c.symStack.len - 1 , 0 ):
172- if x == c.symStack[i]:
173- return true
174- c.symStack.add x
175180 if not eql (x.typ, y.typ, c):
176181 echo " symbol type mismatch:"
177182 result = false
@@ -195,7 +200,6 @@ proc eql(x, y: PSym; c: var EqlContext): bool =
195200 result = true
196201 else :
197202 result = true
198- discard c.symStack.pop
199203
200204proc eql (x, y: PType ; c: var EqlContext ): bool =
201205 if x == nil and y == nil :
@@ -206,19 +210,22 @@ proc eql(x, y: PType; c: var EqlContext): bool =
206210 elif not eqlItemId (x.itemId, y.itemId, c):
207211 echo " type itemId mismatch"
208212 result = false
213+ elif c.checkedTypes.hasKeyOrPut (y.itemId, y):
214+ if c.checkedTypes[y.itemId] == y:
215+ result = true
216+ else :
217+ echo " detected duplicated type ItemId:"
218+ debug (x)
219+ debug (c.checkedTypes[y.itemId])
220+ debug (y)
221+ result = false
209222 elif x.kind != y.kind:
210223 echo " type kind mismatch: " , x.kind, " /" , y.kind
211224 result = false
212225 elif x.flags != y.flags:
213226 echo " type flag mismatch: " , x.flags, " /" , y.flags
214227 result = false
215228 else :
216- if c.typStack.len != 0 :
217- for i in countDown (c.typStack.len - 1 , 0 ):
218- if x == c.typStack[i]:
219- # echo "cycle is detected in PType"
220- return true
221- c.typStack.add x
222229 if not eql (x.n, y.n, c):
223230 echo " type.n mismatch"
224231 debug (x.n)
@@ -246,7 +253,6 @@ proc eql(x, y: PType; c: var EqlContext): bool =
246253 debug (y[i])
247254 result = false
248255 break
249- discard c.typStack.pop
250256
251257proc eql (x, y: PNode ; c: var EqlContext ): bool =
252258 if x == nil and y == nil :
0 commit comments