Skip to content

Question about how modules function #55

@jdstroy

Description

@jdstroy

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.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions