-
Notifications
You must be signed in to change notification settings - Fork 28
Description
Hi Onitama,
I hope this is the right place for this question; if it is not, I apologize.
I have successfully created a library/module in HSP implementing a dynamically-sized array (e.g. similar to vector in C++ or ArrayList<T> in Java).
I am trying to make the module more useful and reusable by implementing functionality such as binary search, but for the module/library to be more useful, it would be good to have user callbacks within the library/module code (for example, a comparison function provided by the caller of the dynamic array module).
I tried making the callback a module, too, but it appears that symbol resolution happens at compilation, and not at runtime dispatch, so this code can only work with one implementation of the compare function, regardless of what module is passed as comparator to bSearch@VArrayListSSCCE:
#module math
#defcfunc min int x, int y
if (x < y) {
return x
}
return y
#defcfunc max int x, int y
if (x > y) {
return x
}
return y
#defcfunc sign int k
if (k > 0) {
return 1
}
if (k < 0) {
return -1
}
return 0
#global
#module VArrayListSSCCE contents, _size, capacity
#modinit int maxSize
_size = 6
capacity = 10
dim contents, capacity
contents.0 = -20
contents.1 = 81
contents.2 = 82
contents.3 = 83
contents.4 = 84
contents.5 = 184
return
#modcfunc size
return _size
#modfunc get int index, var output
assert (index >= 0)
assert (index < size(thismod))
output = contents(index)
return
#modcfunc toString local output, local idx, local value
output = strf("{ 'size': %d, 'capacity': %d, 'contents' : [", size(thismod), capacity )
for idx, 0, size(thismod), 1
get thismod, idx, value
output = strf("%s %s,", output, value )
next
return strf("%s ]}", output)
#modcfunc bSearch var value, var comparator, local lowIdx, local midIdx, local hiIdx, local tmpVal
lowIdx = 0
hiIdx = size(thismod)
while 1
midIdx = (hiIdx + lowIdx) / 2
get thismod, midIdx, tmpVal
switch (sign(compare(comparator,tmpVal,value)))
case 0:
return midIdx
swbreak
case 1:
if (lowIdx == midIdx) {
return -1
}
lowIdx = midIdx
swbreak
case -1:
if (hiIdx == midIdx){
return -1
}
hiIdx = midIdx
swbreak
swend
wend
return
#global
#module SubtractionComp notused
#modinit
notused = 0
return
#modcfunc compare var x, var y
return sign(y - x)
#global
newmod comparator, SubtractionComp
newmod demo, VArrayListSSCCE, 0
mes toString(demo)
m = 84
mes strf("bSearch(list, %d, comparator) = 4: %s", m, bSearch(demo, m, comparator))
m = 81
mes strf("bSearch(list, %d, comparator) = 1: %s", m, bSearch(demo, m, comparator))
m = 75
mes strf("bSearch(list, %d, comparator) = -1: %s", m, bSearch(demo, m, comparator))
That is to say, in the above example, compare is resolved to compare@SubtractionComp; and I can completely remove SubtractionComp from a project, and replace it with this:
#module BadComp notused
#modinit
notused = 0
return
#modcfunc compare var x, var y
return x ^ y
#global
newmod comparator, BadComp
But both cannot exist in the same project at the same time. Is there a way for someone using this module to provide such a callback function for bSearch@VArrayListSSCCE?
Many thanks in advance.