Proposal for a 'listlib' library

Discussions related to the code libraries supplied with BB4W & BBCSDL
User avatar
hellomike
Posts: 205
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Proposal for a 'listlib' library

Post by hellomike »

Very useful Richard.
Will you include this new library in future BBCSDL and BB4W releases?
Richard Russell
Posts: 719
Joined: Tue 18 Jun 2024, 09:32

Re: Proposal for a 'listlib' library

Post by Richard Russell »

hellomike wrote: ↑Sun 27 Jul 2025, 13:22 Will you include this new library in future BBCSDL and BB4W releases?
Currently the listlib library is BBCSDL only (it's not compatible with BB4W because of calling SDL2 memory-management functions). In principle a BB4W version could be produced, but that's not something I've given any serious thought to.

In any case, new releases of BB4W are so infrequent - it's entirely possible that there won't be any more - that should a BB4W version of the library be developed it would probably best be made available another way (e.g. by direct download).

There's also the complication of the Console Mode editions of BBC BASIC (BBCTTY) because they would need yet another version of the library, for the same reason (memory management functions).

One approach would be to develop a 'universal' library which detects which version of BBC BASIC it is running on and uses the appropriate functions for that platform. But that could add a run-time overhead because of the version-testing code, and hit performance.

Another approach would be to adopt the technique I used in the classlib library, which is not to call OS memory-management functions at all but to leverage BBC BASIC's built-in string-management functions. But that would limit the size of list to what fits in BBC BASIC's heap.

I'm open to suggestions. Perhaps the most practical approach is to be led by demand: if nobody expresses any interest in using the library - and they haven't so far - it's all moot! :)
Richard Russell
Posts: 719
Joined: Tue 18 Jun 2024, 09:32

Re: Proposal for a 'listlib' library

Post by Richard Russell »

Richard Russell wrote: ↑Sun 27 Jul 2025, 14:57 Another approach would be to adopt the technique I used in the classlib library, which is not to call OS memory-management functions at all but to leverage BBC BASIC's built-in string-management functions. But that would limit the size of list to what fits in BBC BASIC's heap.
Yet another approach would be to adopt the technique I used in gpiolib.bbc which is to point a function at a different function, so that thereafter that alternative function is called instead. Here's how it's used in gpiolib:

Code: Select all

        PTR(PROC_gpio_inp()) = PTR(PROC_gpio_inp_5())
The potential advantage is that the overhead of testing the current platform happens only on the first call; thereafter no further tests are required and it's as fast as a dedicated library for the current platform would be.
Richard Russell
Posts: 719
Joined: Tue 18 Jun 2024, 09:32

Re: Proposal for a 'listlib' library

Post by Richard Russell »

Richard Russell wrote: ↑Sun 27 Jul 2025, 20:12 Yet another approach would be to adopt the technique I used in gpiolib.bbc which is to point a function at a different function, so that thereafter that alternative function is called instead.
This is what that looks like in practice, when applied to listlib:

Code: Select all

 1890 DEF PROC_listredim(RETURN l%%,D%)
 1900 CASE TRUE OF
 1910   WHEN INKEY(-256)=&57:   PTR(PROC_listredim()) = PTR(PROC_listredim_win())
 1920   WHEN (@platform%>>8)=0: PTR(PROC_listredim()) = PTR(PROC_listredim_tty())
 1930   OTHERWISE:              PTR(PROC_listredim()) = PTR(PROC_listredim_sdl())
 1940 ENDCASE
 1950 PROC_listredim(l%%,D%)
 1960 ENDPROC
Superficially this looks like an example of a recursive doom-loop, with the procedure forever calling itself in line 1950 until it eventually runs out of memory. But that's not what happens, because before it reaches line 1950 it has modified the procedure's pointer so the PROC_listredim is not a recursive call after all!
User avatar
hellomike
Posts: 205
Joined: Sat 09 Jun 2018, 09:47
Location: Amsterdam

Re: Proposal for a 'listlib' library

Post by hellomike »

I fully understand your reasoning about BB4W and therefor I'm fine with a direct download.
Also, I wouldn't mind in having a go converting the BBCSDL one myself into using Windows memory-management functions.
tpegc
Posts: 9
Joined: Tue 24 Apr 2018, 16:28

Re: Proposal for a 'listlib' library

Post by tpegc »

Hi, I have just been playing with listlib, and found some behavior I did not expect when adding a sublist, that included a sub-sublist, to a list.
I modified listdemo.bbc so that the section 1. Append became the following:

Code: Select all

      REM 1b. Append
      DIM subsublist(1) : subsublist() = -1, -2
      DIM sublist(2) : sublist() = 1, 2, FN_lv(subsublist())
      PRINT "1b. Append sublist ";FN_listprint(sublist());":"
      PROC_listappend(myStuff(), FN_lv(sublist()))
      COLOUR 4 : PROC_listprint(myStuff()) : COLOUR 0
When run this gave error "Bad use of array in module..." listlib

Without fully understanding, I think there's a clash in listlib between the PRIVATE c() of PROC_listpush and the RETURNed parameter c() of PROC_listcopy, as I can make the error go away by modifying either procedure such that array c() is not named the same in both procedures.

E.g. PROC_listpush becomes

Code: Select all

      DEF PROC_listpush(RETURN v) : LOCAL l() : PRIVATE c_listpush(),s$
      CASE FN_listtype(v) OF
        WHEN "str": s$ = FN_vs(v) : v = FN_sv(s$) : ]^s$ = 0
        WHEN "list": PTR(l()) = FN_vl(v) : PROC_listcopy(c_listpush(),l()) : v = FN_lv(c_listpush()) : PTR(c_listpush()) = 0
      ENDCASE
      ENDPROC
Richard Russell
Posts: 719
Joined: Tue 18 Jun 2024, 09:32

Re: Proposal for a 'listlib' library

Post by Richard Russell »

tpegc wrote: ↑Sun 04 Oct 2026, 15:49 When run this gave error "Bad use of array in module..."
Well spotted.

Your analysis of the cause and suggested solution are way off the mark, but there's no shame in that: listlib is a complicated library.

The correct fix is to change (just) the DEF PROC_listpush line as follows:

Code: Select all

      DEF PROC_listpush(RETURN v) : LOCAL l(),c(),s$ : PTR(c()) = 0
tpegc
Posts: 9
Joined: Tue 24 Apr 2018, 16:28

Re: Proposal for a 'listlib' library

Post by tpegc »

Me: "My 3A fuse kept blowing, so without fully understanding I made the problem go away by putting in a 13A fuse!" :lol:

Presumably the last part of

Code: Select all

WHEN "list": PTR(l()) = FN_vl(v) : PROC_listcopy(c(),l()) : v = FN_lv(c()) : PTR(c()) = 0
is now redundant, or am I missing something yet again?
Richard Russell
Posts: 719
Joined: Tue 18 Jun 2024, 09:32

Re: Proposal for a 'listlib' library

Post by Richard Russell »

tpegc wrote: ↑Mon 05 Oct 2026, 08:44 Presumably the last part is now redundant, or am I missing something yet again?
If you're suggesting that the PTR(c()) = 0 has no effect, that's implementation-specific and may or may not be the case; it might even vary between different BASIC versions. It's definitely not something that you should rely on.

The equivalent code for a string item ]^s$ = 0 definitely is essential, so if only for reasons of symmetry I would want to restore the pointer for a sub-list item as well.

If you wanted to code very 'defensively' you should, in both cases, restore the string or list pointer not to zero but to the value it had initially:

Code: Select all

      DEF PROC_listpush(RETURN v) : LOCAL l(),c(),s$,p%%
      CASE FN_listtype(v) OF
        WHEN "str": p%% = ]^s$ : s$ = FN_vs(v) : v = FN_sv(s$) : ]^s$ = p%%
        WHEN "list": p%% = PTR(c()) : PTR(c()) = 0 : PTR(l()) = FN_vl(v) : PROC_listcopy(c(),l()) : v = FN_lv(c()) : PTR(c()) = p%%
      ENDCASE
      ENDPROC
I've not bothered to do that in listlib, since libraries are allowed to take liberties that user programs ought not to, but strictly it would be the safest way to code it.
tpegc
Posts: 9
Joined: Tue 24 Apr 2018, 16:28

Re: Proposal for a 'listlib' library

Post by tpegc »

My thought was "c() is no longer PRIVATE so will be lost at the end of the procedure even if modified within PROC_listcopy" - which will indicate my low level of understanding :oops:
I will spend some time working through the pertinent bits of listlib (and the on-line manual!) to see what each step does to c() and associated memory etc.
Thanks for the responses! :)