Hi Aurel,
This is very close to what I use in Oxygen. It supports scoped and local names.
You can associate any non-zero token with a name, and use the token to index your variables attributes.
It uses a stretchable buffer so the size of the hash table is unrestricted.
function hashcode(string s) as long
'==================================
xor eax,eax
mov edx, [s] ' name pointer
mov ecx, [edx-4] ' length
(
cmp ecx,0
jnz exit
return 0 'EMPTY WORD WILL TRIGGER HASHCODE ERROR LATER
)
mov ah, cl ' assume max length 255
(
xor al, [edx]
xor eax,0x3a575a73
rol eax,18
inc edx
dec ecx
jnz repeat
)
return eax
'
end function
type hashrec
'===========
string name
sys hash
sys next
sys token
end type
'GLOBAL
'======
hashrec* ht
string hashbuf
sys lenbuf
sys maxr,maxri,maxrs[64]
function stretchbuf()
'====================
if maxr*sizeof hashrec>lenbuf
hashbuf+=nuls(1024*sizeof hashrec)
lenbuf=len hashbuf
@ht=strptr hashbuf
end if
end function
function storename(string name, sys token)
'=========================================
sys h,b,c,i,le
h=hashcode name
b=h and 511
c=b
do
b=ht[b].next
if b=0 or b>maxr
maxr++
b=maxr
stretchbuf()
ht[c].next=b
ht[b]<=name,h,0,token
exit do
end if
c=b
end do
end function
function findname(string name) as sys
'====================================
sys h,b,c,f
h=hashcode name
b=h and 511
c=b
b=ht[b].next
do
if b=0
exit do
elseif b>maxr
if c
ht[c].next=0
end if
exit do
end if
if h=ht[b].hash
if name=ht[b].name
f=b
end if
end if
c=b
b=ht[b].next
end do
if f
return ht[f].token 'LAST MATCH
end if
end function
function pushmaxr()
'==================
maxri++
maxrs[maxri]=maxr
end function
function popmaxr()
'==================
maxr=maxrs[maxri]
maxri--
end function
'INITIAL
'=======
'
maxr=511
stretchbuf()
'TEST STORAGE
'============
storename "aardvard",41
storename "aardvark",42
storename "aardvarc",43
pushmaxr 'FENCE FOR LOCAL SCOPE
storename "aardvark",142
print " 41>>" findname "aardvard"
print "142>>" findname "aardvark"
print " 43>>" findname "aardvarc"
popmaxr 'RELEASE LOCAL SCOPE
print " 42>>" findname "aardvark"
'TEST HASHCODER
'==============
function falsematchtest(sys e) 'CHECKING FOR FALSE MATCHES
'=============================
'e 0x40000 'takes a while!
'e 0x4000
type htest
string s
sys h
end type
string buf=nuls((e+1)*sizeof htest)
htest *t
@t=strptr buf
sys a,c,i,j,p
for i=1 to e
t[i].s="aaaa"
p=strptr t[i].s
*p+=i
t[i].h=hashcode t[i].s
next
string pr,cr
cr=chr(13)+chr(10)
pr=""
for i=1 to e-1
a=t[i].h
for j=i+1 to e
if a=t[j].h then
pr+= hex(i,8) " " hex(j,8) " " hex(t[i].h,8) cr
c++
if c>20 then goto fin 'LIMIT LIST
end if
next
next
fin:
====
if pr
print "false coincidences: "+cr+pr
else
print "no false coincidences in " e
end if
end function
'falsematchtest 0x4000
Charles