[comp.sys.handhelds] some prgs

horlache@sun1.ruf.uni-freiburg.de (Ullrich Horlacher) (01/18/90)

Hello "real -calculator"-users,

I read this group not from the beginning, therefor I don't know if some of
my prg-ideas has been posted in the past. I have sent them already to the
bitnet-listserver-group . If you have it allready just ignore them.

Happy computinmg   Ulli


#---------------------------------------------------------------------#
# this mail came from Framstag!   (sometimes known as Ulli Horlacher) #
# framstag@dtupev5a.bitnet  ullrich.horlacher@ruf.uni-freiburg.dbp.de #
#                    "Murphy was an optimist"                         #
#---------------------------------------------------------------------#

horlache@sun1.ruf.uni-freiburg.de (Ullrich Horlacher) (01/18/90)

LOAD:  to copy objects from your RAM-Disk ( := the dir ZZZ in HOME )

SAVE:  to copy objects to your RAM-Disk 

COPY:  to copy objects from your current directory to another dir 
       (the selected objects remain in your current dir)

MOVE:  to replace objects from your current directory to another dir 
       (the selected objects are deleted in your current dir)

OBSI:  shows the size of objects in Bytes. You can determin the size of any 
       object, but not of system objects and directories.

REPL:  replace a substring with another substring in an object (the object
       can als be a none-string: a program etc) 

INS:   Insert a program in another program

Z:     jump one directory up


--------------------------------------------------------------------------


LOAD
<< 8 CF                      ! indicates copy_objects
   PATH -> p                 ! current dir
<< ZZZ                       ! jump to RAM-Disk
   ->CML                     ! subprg load_objects_into_stack 
   p ->DIR                   ! recall dir
   ->CMS  >>                 ! subprg store_objects_from_stack 
>>



SAVE
<< 8 CF                      ! indicates copy_objects
   PATH -> p                 ! current dir
<< ->CML                     ! subprg load_objects_into_stack 
   ZZZ                       ! jump to RAM-Disk
   ->CMS                     ! subprg store_objects_from_stack 
   p ->DIR >>                ! recall dir
>>


usage:
======

[ First, make the RAM-Disk-directory ZZZ:       HOME 'ZZZ' CRDIR        ]


      <global name> LOAD         
      <list of global names> LOAD                
      <global name> SAVE
      <list of global names> SAVE
      

eg:   'TEST' SAVE
      { 'TEST1' 'NEXT' 'ANOTHER' } SAVE

      'TEST' LOAD
      { 'TEST1' 'NEXT' 'ANOTHER' } LOAD


You can also load/save whole subdir-trees!


--------------------------------------------------------------------------


COPY
<< 8 CF                      ! indicates copy_objects
   ->CML                     ! subprg load_objects_into_stack 
   HALT                      ! HALT for changing the dir
   ->CMS                     ! subprg store_objects_from_stack 
>>



MOVE
<< 8 SF                      ! indicates move_objects
   ->CML                     ! subprg load_objects_into_stack 
   HALT                      ! HALT for changing the dir
   ->CMS                     ! subprg store_objects_from_stack 
>>



usage:       <global name> COPY
======       [now travel to the destination directory]
             CONT   [:= SHIFT 1]

             <list of global names> COPY
             [now travel to the destination directory]
             CONT   [:= SHIFT 1]


             <list of global names> MOVE
             [now travel to the destination directory]
             CONT   [:= SHIFT 1]


             <list of global names> MOVE
             [now travel to the destination directory]
             CONT   [:= SHIFT 1]

      

eg:   { 'TEST1' 'NEXT' 'SUBDIR1' } COPY
      HOME
      CONT
      
      VARS MOVE
      Z 
      CONT



You can also copy/move whole subdir-trees!


--------------------------------------------------------------------------

The subprgs to LOAD/SAVE/COPY/MOVE :


->CML                        ! subprg load_objects_into_stack 
<< ->O->L                    ! make a list
   1 ol SIZE FOR i           ! loop from 1 to # of objects to load
     ol i GET DUP            ! get object name
     IFERR RCL               ! and contence
       IF 8 FS?              ! MOVE?
       THEN OVER PURGE END   ! then delete object in the source dir
     SWAP                    !
     THEN                    ! 
       IF ERRN #12Ah == THEN ! if the object was a dir then
         EVAL -> dir         ! jump to subdir and store the name of the subdir
         << VARS DUP         ! all objects in that subdir
            IF { } <>        ! if the subdir is not empty
            THEN ->CML       ! then call subprg ->CML (rekursion)
            ELSE DROP END    ! else do nothing
            dir DUP          ! put name of subdir onto stack
            << CRDIR >>      ! preparing for making a dir 
            Z                ! one dir up
            IF 8 FS? THEN    ! MOVE?
            OVER PURGE END   ! then delete the object in the source-dir
          >>
       ELSE KILL END         ! stop program
     END
   NEXT
   1 ol SIZE                 ! from 1 to # of objects; loop-# for ->CMS subprg
   'ol' PURGE                ! delete no more longer needed object-list
>>



->CMS                        ! store_objects_to_stack 
<< IFERR                     ! Error-tracking if an directory occurs
     START                   ! Loop from 1 to # of ojects in the subdir
       IFERR                 ! Error-tracking if an directory occurs
         STO                 ! store the object
       THEN EVAL EVAL        ! if it was an dir-object then create the dir 
         ->CMS               ! call the prg again (recursion)
         Z                   ! jump up one dir
       END
     NEXT
   THEN END
>>



->O->L
<< IFERR LIST-> THEN 1 END   ! out of the list
   ->LIST 'ol' STO           ! into a list and store it
>>



->DIR                        ! evaluate a dir-path
<< DUP SIZE 1 1 ROT START GETI EVAL NEXT DROP2 >>



Z                            ! jump up one dir
<< PATH DUP SIZE 1 - 1 MAX GET EVAL >>


--------------------------------------------------------------------------


OBSI                            ! object-sizes
<< ->O->L                       ! subroutine to make a list
   1 DROP                       ! set the LAST-buffer to a constant value
   MEM 'm0' STO                 ! store mem-size 
   ol LIST->                    ! put the list on the stack
   1 SWAP                       ! from 1 to list-size (# of specified objects)
   FOR i                        ! loop 
     IFERR                      ! error-trapping for the case of an directory
       RCL                      ! dir is speciefied in the object-list
       "'m" i ->STR + STR->     ! create name of the next dummy-object
       STO                      ! and store it
     THEN DROP END              ! is the object a dir then next
   NEXT
   1 DROP                       ! set the LAST-buffer to a constant value
   MEM m0 - NEG                 ! difference in memory before/after doubling
   0 ol SIZE FOR i              ! loop from 0 to # of objects
     "'m" i ->STR + STR->       ! name of the dummy-object
     PURGE                      ! delete it
   NEXT
   ol ->STR SIZE +              ! add mem-size of the name of the objects
   ol SIZE 3 * - 20 -           ! and subtract the mem-size of the dummy-names 
   'ol' PURGE                   ! delete no more needed list
>>
!How it works:
!  The prg doubles the objects: they are stored in dummy objects. The difference
!  in MEM before and after that doubling is the memory-size of the objects.
 


->O->L
<< IFERR LIST-> THEN 1 END   ! out of the list
   ->LIST 'ol' STO           ! into a list and store it
>>



usage:      <global name> OBSI 
======      <list of global names> OBSI

 
eg:     1: 'OBSI'  
        OBSI

        VARS OBSI
 

--------------------------------------------------------------------------

 
REPL                            ! replace a string with another one
<< IF DUP TYPE 6 <> THEN        ! is it not a (global) name?
     'rep' SWAP OVER STO        ! then store it
      DUP 4 ROLLD ->REPL        ! call subprg
      RCL LAST PURGE            ! delete the dummy-object 'repl'
   ELSE ->REPL END              ! else call subprg
>>



->REPL                          ! subprg replace a string with another one
<< 0 -> a b p z                 ! make local variables
  << p RCL ->STR                ! recall the object and change it to a string
     WHILE                      ! loop 
       DUP DUP a POS DUP 'z' STO! the string to change and his size
     REPEAT
       1 z 1 - SUB              ! from start to occurence of the string
       b +                      ! add new string
       SWAP z a SIZE +          ! new size
       OVER SIZE SUB +          ! add the rest of old string
     END
     p RCL                      ! recall the object 
     IF TYPE 2 <> THEN STR-> END! out of string (if it was originally no one)
     p STO DROP                 ! store it
  >>
>>



Usage:    3:   <string1> 
======    2:   <string2>
          1:   <any object>
               REPL 


eg:      "^" 33 CHR "That's it^^" REPL

         "DUP OVER +"
         "SWAP -"
         'doit'
          REPL



INS                             ! Insert programs
<< RCL ->STR                    ! recall the 1st prg and make a string
   "@" SWAP ROT                 ! prepare for REPL
    RCL REPL                    ! recall 2nd prg and replace "@" with prg #2
>>



[ <> is the not-equal-sign ]
[ @  is the micro-sign (shift-x) ] 
 


Usage:       First mark the place, where the 2nd prg should be inserted
======       with a @.

            2: <prg1>
            1: <prg2>
            INS


eg:         2: << "this is a test" @ HOME >>
            1: <<  1 DISP >>
            INS

            'MAIN' 'SUB' INS

#---------------------------------------------------------------------#
# this mail came from Framstag!   (sometimes known as Ulli Horlacher) #
# framstag@dtupev5a.bitnet  ullrich.horlacher@ruf.uni-freiburg.dbp.de #
#                    "Murphy was an optimist"                         #
#---------------------------------------------------------------------#

horlache@sun1.ruf.uni-freiburg.de (Ullrich Horlacher) (01/18/90)

Hi Systemprogrammers   :-)


Most HP28-users have a sub-routine "wait_for_key", I suppose, which holds a prg
until a key is pressed.
 
It looks like:

<< "Press any key to cont" 4 DISP DO UNTIL KEY END DROP >>


My improvement is to use the SHIFT-indicator instead of "Press any key to cont" 

<< #<SHIFT_ON> SYSEVAL DO UNTIL KEY END DROP #<SHIFT_OFF> SYSEVAL >>


(set your HP to HEX-mode)

                   1BB        1CC         2BB
--------------+----------+----------+-----------
#<SHIFT_ON>   !   #9C96  !   #9C61  !   #1F8A7     
#<SHIFT_OFF>  !   #9CA3  !   #9C6E  !   #1F8B4      


(with #A SYSEVAL you can get your version-number)



+------------------------------------------------------------------+
! true name: Ulli Horlacher *     e-mail: framstag@dtupev5a.bitnet !
! nick name: Framstag       *             s_horlac@dulruu51.bitnet !
!      or    Fraturday      *             50177::s_horlacher       !
!                           * snail-mail: Ulli Horlacher           !
!                           *             Landfriedbuehl 5         !
! Universitaet Ulm          *             D-7900 Ulm               !
! West-Germany              *             West-Germany             !
!******************************************************************!
!                 "Murphy was an optimist"                         !
+------------------------------------------------------------------+

horlache@sun1.ruf.uni-freiburg.de (Ullrich Horlacher) (01/18/90)

IN is a programm for interactive input, like INPUT in BASIC or readln in 
Pascal. It gives back the input-string to the stack. If you press the INS-key,
you can do other things, like visit variables, and then continue the programm.
Insert the special characters ":" and "_" with my programm REPL (or with other
methods).


IN                                     ! remarks
<< -> s p
  << s "" <> s ":" + s IFTE 's' STO    ! If prompt-string then add a ":"
    WHILE 
      IFERR DO                         ! loop with pseudo-interrupt-handling
        s OVER +                       ! Add prompt-string
        "_" + p ->IN                   ! get char (cursor on)
        s OVER +                       ! Add prompt-string
        p ->IN                         ! get char (cursor off)
      UNTIL 0 END THEN END             ! end interrupt-loop
      DUP "ENTER" <>                   ! do not terminate IN ?
    REPEAT
      DUP "INS" ==                     ! if key INS is pressed
      << DROP2 LCD-> 'lcd' STO         ! save current screen
         HALT                          ! spawn 2nd process
         "" "" lcd ->LCD lcd PURGE >>  ! refresh screen
      IFT
      DUP "BACK" ==                    ! if the <- key is pressed
      << DROP 1 OVER SIZE 1 - SUB      ! delete last char
         "" >> IFT
      +                                ! add char
    END
    DROP DUP s SWAP + p DISP           ! display input-string without cursor
  >>
>>

->IN                                   ! sub-programm for blinking cursor
<< DISP                                ! display input-string
   1 40 START KEY                      ! loop for getting key to
     '->IN' IFT                        ! create an error for pseudo-interrupt-
   NEXT                                ! handling and resuming main-programm IN 
>>  


use:   2:        <prompt-string>
       1:  <display-line-number>
       IN


e.g.:  2:                "Value"
       1:                      3
       IN

or    << CLLCD "Value" 3 IN 'VALUE' STO >>

==>    +----------------------+
       |                      |
       |Value:_               |
       |                      |
       |                      |
       +----------------------+


#---------------------------------------------------------------------#
# this mail came from Framstag!   (sometimes known as Ulli Horlacher) #
# framstag@dtupev5a.bitnet  ullrich.horlacher@ruf.uni-freiburg.dbp.de #
#                    "Murphy was an optimist"                         #
#---------------------------------------------------------------------#

horlache@sun1.ruf.uni-freiburg.de (Ullrich Horlacher) (01/18/90)

Revised 'MOP' (Matrix OPeration): A function, which executes any algebraic 
operation or program on every element of an 1 or 2 dimensional array.
The improvement is a better error-trapping. My last mail had an error in 
the examples: I used the name PMEM instead of MOP. I hope, this will be the 
last correction :-)

By the way: I want to know how usefull is this programm to others. If you
            use this prg, please send me a short "I use MOP"-mail (Also 
            every kind of improvements, questions etc).
 

MOP                         ! LENGTH = 365 bytes
<< -> a o <<                ! store array and operation in local variables
  DEPTH DUPN                ! double stack
  DEPTH 2 / ->LIST          ! copy stack into a list
  a IFERR RCL               ! if array is a name (stored in an object)
  SWAP OVER a 3 ->LIST      ! then add name and contence of object to the list
  THEN + a a ROT END        ! else add array to the list
  -> b <<                   ! store list (backup in case of an error)
  1 SWAP SIZE LIST->        ! size of array
  IF 1 - THEN * END         ! if it is a 2-dim array then multiply size of
                            ! row and column
  IFERR                     ! start errortrapping for forbidden operation
    FOR i                   ! loop for do the operation on every element
      IF a TYPE 6 ==        ! if array is a name (stored in an object)
      THEN a END            ! put array-name in stack
      i OVER i GET          ! get next array-element
      'X' STO               ! store it
      o EVAL                ! do the operation on that element
      IFERR                 ! if result is a complex number and array
        PUT THEN            ! contains only real numbers (==>error)
        ROT (1,0) *         ! convert array into a complex array
        ROT ROT PUT         ! and store the modified element once again
      END
    NEXT
  THEN                      ! if there was a forbidden operation (like INV(0))
    CLEAR                   ! delete data-garbage (from the error)
    b LIST-> DROP           ! recall backup
    IF a TYPE 6 == THEN STO ! if array was a name then restore it
    LIST-> DROP END         ! and recall old stack
    "MOP Error:             ! text for error-display
"                           ! important line feed !!
    ERRM + 1 DISP           ! add error-message and show it
  END
  'X' PURGE                 ! delete no more longer used variable
  >> >>
>>
 
 
usage:
======
 
2:                <array>
1:   <algebraic function>  or  <program>
MOP
 
 
2:        <name of array>
1:   <algebraic function>  or  <program>
MOP
 
 
1: 'MOP(<name of array>,<algebraic function>)'
EVAL
 
 
 
e.g.:
=====
 
2:         [[  1  2.3 ]
            [ -3  4.4
            [  1 -1.1 ]]
1:       'LOG(SQR(X))-3'
MOP


2:         [[  1  2.3 ]
            [ -3  4.4
            [  1 -1.1 ]]
1: << IF X 1 < THEN X DUP R->C ELSE X END >>
MOP
 
 
2:               '&DAT'
1:             'INV(X)'
MOP
 

2:               '&DAT'
1:          << X INV >>
MOP
 
 
1: 'MOP(MA,X^INV(3))'
EVAL
 
 
! The algebraic operation must have X as argument. I know, this sucks, but
! calling by reference like  'MOP(INV(<array>)*3-2)'  is not possible (or
! does anybody know a way ??)
! & := the Sigma-sign (SHIFT V)
 
//////////////////////////////////////////////////////////////////////////// 

A second, tiny version of MOP, in which the array must be directly in the
stack; only call by value is possible (like in example 1 above):
 

MOP                         ! LENGTH = 260.5 bytes
<< -> a o <<                ! store array and operation in local variables
  DEPTH DUPN                ! double stack
  DEPTH 2 / ->LIST          ! copy stack into a list
  a +                       ! add array to the list
  -> b <<                   ! store list (backup in case of an error)
  a 1 SWAP SIZE LIST->      ! size of array
  IF 1 - THEN * END         ! if it is a 2-dim array then multiply size of
                            ! row and column
  IFERR                     ! start errortrapping for forbidden operation
    FOR i                   ! loop for do the operation on every element
      IF a TYPE 6 ==        ! if array is a name (stored in an object)
      THEN a END            ! put array-name in stack
      i OVER i GET          ! get next array-element
      'X' STO               ! store it
      o EVAL                ! do the operation on that element
      IFERR                 ! if result is a complex number and array
        PUT THEN            ! contains only real numbers (==>error)
        ROT (1,0) *         ! convert array into a complex array
        ROT ROT PUT         ! and store the modified element once again
      END
    NEXT
  THEN                      ! if there was a forbidden operation (like INV(0))
    CLEAR                   ! delete data-garbage (from the error)
    b LIST-> DROP           ! recall backup
    "MOP Error:             ! text for error-display
"                           ! important line feed !!
    ERRM + 1 DISP           ! add error-message and show it
  END
  'X' PURGE                 ! delete no more longer used variable
  >> >>
>>
 
 
 
The name 'MOP' was created by Schrulli B.  thanx ;-)
 

Addendum to MOP:

'MOP' (Matrix OPeration) is : A function, which executes any algebraic 
operation OR PROGRAM on every element of an 1 or 2 dimensional array.
 
 
usage:
======
 
2:                <array>
1:   <algebraic function>  or  <program>
MOP
 
 
2:        <name of array>
1:   <algebraic function>  or  <program>
MOP
 
 
1: 'MOP(<name of array>,<algebraic function>)'
EVAL
 
 
 
e.g.:
=====
 
2:         [[  1  2.3 ]
            [ -3  4.4
            [  1 -1.1 ]]
1:       'LOG(SQR(X))-3'
MOP


2:         [[  1  2.3 ]
            [ -3  4.4
            [  1 -1.1 ]]
1: << IF X 1 < THEN X DUP R->C ELSE X END >>
MOP
 
 
2:               '&DAT'
1:             'INV(X)'
MOP
 

2:               '&DAT'
1:          << X INV >>
MOP
 
 
1: 'MOP(MA,X^INV(3))'
EVAL