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