Post Reply 
Accessing data in linked array on HP-50g
07-19-2021, 12:44 AM
Post: #8
RE: Accessing data in linked array on HP-50g
I thought I might give this a try, as it seemed like a nice exercise.

Playing around with this, I ran into a couple of wrinkles pertaining to which built-in commands support the various array object types. As an example: you pretty much have to use GETATELN to obtain a specific linked array element. However, GETATELN doesn't work with type 29 matrices. So there's no one-size-fits-all command that performs that function for all array types. Likewise, ^XEQARRY> works well for type 3|4|29 arrays, but not for linked arrays.

This is one approach among many -- probably not the best or worst, but it should at least give some ideas for bits and pieces that might be useful for your implementation. It does use two undocumented built-ins that are accurate for a v2.15 firmware (I haven't checked other firmware versions for validity):

- SysPR1 (PTR 2F127) is the internal version of the UserRPL PR1 command
- DupArryType (PTR 2F2C4) is the code run by the UserRPL TYPE command to determine the type of a regular array object (3|4|29)

This implementation uses a "decode the sequential index" approach for determining the labels for each element's indices. It essentially takes the index number of the current element and iteratively divides by the dimensions identified for the object to determine the current element's position label (the indices are converted to 1-based in the process). This is similar to how you might convert a number to a different base, but it uses a list of the dimensions instead of a constant base as the divisor.

There's a couple of non-standard techniques used in this implementation which might benefit from further explanation:

1) Placing the main code object onto the return stack allows it to run for both of the overloaded dispatch types identified as part of the CK&DISPATCH1 structure. If the code had been part of library, this would not have been the best approach. In this case, I wanted the program to be fully encapsulated into one code object, and this approach is an efficient way to implement a single code base for multiple object types.

2) The dimensions list is processed using the return stack processing technique. This is an efficient (and fast) way to process each element of a list in sequence. Might be a bit heavy-handed for this situation, but it does show an example of how to do that if you are interested in using that approach with SysRPL programs.

Here's the commented code:
Code:
!NO CODE
!ASM
   DC SysPR1         2F127
   DC DupArryType    2F2C4
!RPL
::
   ( needs 1 argument )
   CK1NoBlame
   
   ( this routine is placed on the return stack for execution after object validation )
   ' ::
      COERCE                              ( convert array type to BINT )
            
      ( print the object type description )
      "Type " OVER #>$ &$ APPEND_SPACE    ( "Type <n> " )
      BINT23 3PICK #= IT :: "Linked " &$ ; ( insert "Linked " if appropriate )
      OVER BINT29 EQITE "Matrix" "Array" &$ ( "Matrix" or "Array" as appropriate )
      SysPR1 DROP                         ( print and DROP the object type )
   
      BINT23 EQ                           ( linked array = TRUE, otherwise FALSE )

      ( setup lams )
      SWAPDUP FPTR2 ^DIMLIMITS            ( obtain a list of dimensions )
      INNERCOMP reversym {}N              ( reverse the dimensions list )
      OVERARSIZE                          ( obtain the count of array elements )
      {{ count dims array }}              ( bind locals )

      ( explode all array elements onto the stack )
      ITE ::                              ( TRUE - array is a Linked Array )
         count #1+_ONE_DO                 ( loop for each element position )
            INDEX@ array GETATELN         ( get current element )
            NOT_IT "<undefined>"          ( string if position has no defined element )
         LOOP
      ;
      ::                                  ( FALSE - array is type 3, 4, or 29 )
         array FPTR2 ^XEQARRY>            ( explode array elements onto stack )
         DROP                             ( drop the unneeded dimensions list )
      ;
      
      ( print each element with a positional label )
      count reversym                      ( reverse the elements )
         ZERO_DO                          ( loop for each element )
         NULL$                            ( initial element label )
         INDEX@                           ( current element number [0-based] )
         
         ( determine the position label indices )
         ::
            dims >R                       ( place dimensions list on return stack )
            BEGIN
               RSWAP                      ( move list data into topmost return stack position )
               ticR NOTcase :: RDROP ;    ( get next divisor or exit )
               RSWAP                      ( restore return stack order )
               #/ SWAP                    ( determine quotient & remainder )
               #1+ #>$ tok- SWAP&$        ( determine current index [1-based] )
               ROT &$SWAP                 ( add current index to index string )
            AGAIN
         ;
         DROP                             ( drop the final quotient )

         BINT2 LAST$                      ( drop leading dash )
         "  #" SWAP&$                     ( prepend "  #" to label )
         ": " &$                          ( append ": " to label )
         
         SWAP DO>STR &$                   ( append current element as string )         
         SysPR1 DROP                      ( print and DROP the object )       
      LOOP

      ABND                                ( abandon locals )
   ;
   >R                                     ( place the above routine on the return
                                            stack for later execution )
   
   ( must be either array type or linked array )
   ( any other object type raises "Bad Argument Type" error )
   CK&DISPATCH1
   arry DupArryType     ( type %3 [real], %4 [complex], %29 [matrix] )
   BINT95 %23           ( type %23 [linked array] )
;
@
Find all posts by this user
Quote this message in a reply
Post Reply 


Messages In This Thread
RE: Accessing data in linked array on HP-50g - DavidM - 07-19-2021 12:44 AM



User(s) browsing this thread: 1 Guest(s)