Without auto-allocation of variable names so a library can use variables not used in the end-user's program, local variable naming and a mechanism for code to call a library built into the Programming Editor there are going to be some difficulties in 'doing it properly' or how it would be done in other programming environments.
The PICAXE isn't stack-based and end-users have to define what variables are used where which can make it complex, and especially when one library calls another.
The primary three rules are likely to be -
* Only use Symbol defined named variables in the code so an end-user can edit variables to overcome conflicts ( use those with highest numbers first to reduce occurrences ), and never use an explicit variable name ( eg 'b0' ).
* Subroutine and label names should be chosen to be unlikely to conflict with those used by the end user.
* Make each individual library as small, specific and as standalone as possible to reduce code bloat. #IfDef can be used to only include what is needed. Unfortunately the Programming Editor doesn't support nested #IfDef/#IfNDef at present.
The Programming Editor doesn't, but is intended to, support #Include files, so it's probably best to write each library as self-contained as possible in a separate file which can be cut and pasted now, #included later. For exaple ...<code><pre><font size=2 face='Courier'>#IfNDef LIB_SQUAREROOT_DEFINED
#Define LIB_SQUAREROOT_DEFINED
Symbol Lib_SquareRoot_Arg = w5 ' b11:b10
Symbol Lib_SquareRoot_Guess = b9
Symbol Lib_SquareRoot_Temp = w6 ' b13:b12
Symbol Lib_SquareRoot_Result = b13
Lib_SquareRoot:
Lib_SquareRoot_Guess = 0
Do
Lib_SquareRoot_Guess = Lib_SquareRoot_Guess+1
Lib_SquareRoot_Temp =
Lib_SquareRoot_Guess * Lib_SquareRoot_Guess
Loop Until Lib_SquareRoot_Temp > Lib_SquareRoot_Arg
Lib_SquareRoot_Result = Lib_SquareRoot_Guess-1
Return
#EndIf </font></pre></code> Even with #include and using Symbol to define variables there's a problem if those variables need to be changed to make an end-user program work, as that change may break other code which also uses the library but needs different variable definitions.
I've looked into how to do libraries and there seems to be no easy solution. Even with an external preprocessor it's not simple and there is a lot of work required to do it properly and efficiently - Identifying variables used isn't hard, auto-allocating isn't either, but recycling variables so different libraries can use the same variables is more difficult. It is possible to poke to SFR or scratchpad to create a stack-based environment, providing the end-user program doesn't use them, but it all adds up to having to deal with multiple scenarios.
All mechanisms to add libraries simply on top of what exists run into some problem sooner or later, and the best option at present may be to provide the library as a code snippet ( as per above ) leaving the end-user to cut-paste-and-edit as appropriate.
No matter what the mechanism used, the key to producing a successful and usable library is in defining and documenting exactly what it does, what it expects as input and what it gives as output. It's also good to provide documentation on how a library works and some test program(s) to show how it should be used and to demonstrate it actually does do what it claims. It should also be obvious that a library must do what it says, have been rigorously tested, and any special restrictions, failure cases or issues are documented. All this can take far longer than writing the code.
Edited by - hippy on 26/04/2007 13:43:08