EQSTK v9.1 Equation Writer Stack Display for the HP48 (c) 1995 by Mika Heiskanen & Claude-Nicolas Fiechter 0.0 DISCLAIMER ============== EQSTK is distributed in the hope that it will be useful, but the copyright holders provide the program "as is" without warranty of any kind, either expressed or implied, including, but not limited to, the implied warranties of merchantability and fitness for a particular purpose. In no event will the copyright holders be liable to you for damages, including any general, special, incidental or consequential damages arising out of the use or inability to use the program. So there. 1.0 OVERVIEW ============ EQSTK provides an alternative to the built-in stack displayer, with the main advantages of being capable of displaying equations in similar form as the built-in Equation Writer. The display also can handle symbolic arrays in the form they are defined in most symbolic math packages, such as ALG48. 2.0 INSTALLATION ================ EQSTK library works in any port of a HP48G(X) or S(X), with no speed loss when being run from a covered GX port. To install EQSTK on your HP48 download the file 'eqstk.lib' to your calculator and store in it a port of your choice. For example to store the library to port 0, type in (or press suitable keys) 'eqstk.lib' DUP RCL SWAP PURGE 0 STO and power-cycle the calculator. The library will autoattach itself to the HOME directory. Installing a universal font library containing a small font is recommended as it makes displays using lower case characters much better. EQSTK uses the library only if it is stored in a visible port though. ********************************************** * EQSTK requires the universal font library * * with small and medium fonts to be present. * ********************************************** The package also includes a smaller version of the library named 'eqstkb.lib', which does not have the following functionality: o All features documented in section "User Functions" o Special symbols for identifiers Phi, phi etc listed in "Global name" o Dot indicates subscript as explained in "Global name" Enabling any single feature again from above is possible by editing and recompiling the source code distributed with the package. 3.0 COMMANDS ============ 3.1 AGROB --------- Stack: ( ob maxsize --> grob ) AGROB takes an object from stack, along with the desired maximum font size, and converts the object into a grob. If the object is an algebraic expression or of some other suitable type, equation writer form output is produced. The size argument should be a real number in the range 1 to 3, where 3 specifies the maximum possible starting font size. 3.2 ASTK -------- Stack: ( --> ) ASTK command starts an alternative loop to provide the full functionality of the HP48, with the exception of changed display. ASTK displays the menu as usual, but the stack no longer has any size limit. Most importantly, the status area is not shown at all unless the area is flagged as frozen, for example when a keypress generates an error. How many stack levels are shown depends only on the size of the objects being displayed in their AGROB form. When ASTK is started for the first time, it will use the medium font as the maximum font size to use when calling the agrob subroutines. Any further executions will only toggle an internal flag in the already running ASTK to toggle the maximum font between the smallest and the medium fonts. To exit ASTK simply press the CONT key (left-shift ON). Note that ASTK does not modify any other keys than CONT, thus for example the interactive stack still uses the regular display loop. 4.0 IMPLEMENTATION DETAILS ========================== 4.1 AGROB Parser ---------------- AGROB uses the internal ->STR subroutines to decompile objects, with the following exceptions: Tagged Objects -------------- The tag is ignored, and thus the test defaults to testing for the following list of exceptions. Grobs ----- Grobs already are in the required form, so nothing is done. Global name ----------- Global names are displayed without the '' delimiters. Also subscripts can be generated as follows: - By having an embedded dot character in the identifier. The first part of the name forms the actual displayed name. The second part of the name forms the subscript which is displayed in a smaller font. The second part can also have further dots to generate a subscript for the subscript itself. - By having trailing decimal digits in the name. The digits will form the subscript in a smaller font. In the following examples the decreasing font size is left to the imagination of the reader: X.Y.Z ==> X X1 ==> X Y 1 Z Due to the restricted internal font, and for easy access to some symbols the following names create special grobs: Psi, Phi, phi, Gamma, GAMMA, Planck, Nabla, Blank, Cont In addition the infinity and small omega symbols default to built-in grobs due to the bad representation they have in the UFL small font. The user should try typing above names when ASTK is active to see what the results are. Local variable names -------------------- Local variable names are displayed without the '' delimiters. Units ----- Units are shown as in the built-in Equation Writer. For example: m 1_m/s ==> 1_-- s Arrays ------ Arrays having more than two dimensions are shown using the internal ->STR. For one or two dimensions the objects in the array are decompiled using the general rules for AGROB, the results are then arranged in a grid and are surrounded with brackets. One dimensional arrays are shown as column vectors. Lists ----- An empty list is displayed using the internal ->STR. If the list contains no lists the list is shown as a column vector with surrounding parenthesis. A list of lists all of equal lenght is considered a two dimensional array, and execution is similar as for arrays with the exception of using surrounding parenthesis instead of brackets. Otherwise the list is displayed using the internal ->STR. Algebraics ---------- All objects inside the algebraic are displayed using the regular rules. The functions in the algebraic then cause the grobs to be merged as is proper for the function. By default all functions simply display the name of the function followed by the arguments in parenthesis, with the following exceptions: + Arguments displayed with + in the middle - Arguments displayed with - in the middle NEG Argument displayed with - in the front * Arguments displayed with a dot in the middle / Arguments displayed on top of each other w/ a line in between ^ Second argument displayed as exponent INV Argument displayed with "-1" exponent SQ Argument displayed with "2" exponent EXP Argument displayed as exponent for "e" ALOG Argument displayed as exponent for "10" CONJ Argument displayed with "*" exponent ABS Argument displayed with surrounding || SQRT Argument displayed with surrounding square root XROOT Arguments displayed as written on paper ! Argument displayed with following "!" MOD Arguments displayed with " MOD " in the middle NOT Argument displayed with a special NOT symbol in front AND Arguments displayed with a special AND symbol in the middle OR Arguments displayed with a special OR symbol in the middle XOR Arguments displayed with a special XOR symbol in the middle = Arguments displayed with "=" in the middle == Arguments displayed with "==" in the middle <> Arguments displayed with "<>" in the middle < Arguments displayed with "<" in the middle > Arguments displayed with ">" in the middle <= Arguments displayed with "<=" in the middle >= Arguments displayed with ">=" in the middle The following cases are a bit more complex: Derivative ---------- A series of derivatives with respect to X is causes the argument to be shown with the proper number of ticks (') as the 'exponent'. A series of derivatives with respect to mixed variables is shown as taking partial derivatives of the argument. Examples: (d denotes the derivative function) '' ' 'dX(dX(Y))+a*dX(Y)+b=0' ==> Y +aY +b=0 d 'dY(dX(F(X,Y)))=0' ==> ----(F(X,Y))=0 dYdX Integral -------- Integral function is displayed as written on paper. As a special feature '?' as an integration limit is not displayed. Examples: (S denotes the integral function, 00 infinity) 'S(0,00,EXP(-SQ(X)/2),X))=SQRT(PI/2)' 00 / 2 | -x | -- --- | 2 |PI ==> |e dX = |-- / \|2 0 'S(?,?,S(?,?,S(?,?,1/(X^2+Y^2+Z^2),X),Y),Z)' /// ||| 1 ==> |||--------dXdYdZ ||| 2 2 2 |||X +Y +Z /// Summation --------- Summation function is displayed as written on paper. Example: (Z denotes the summation function) 'Z(I=1,n,SQ(I))=1/3*n^3+1/2*n^2+1/6*n)' n -- 2 1 3 1 2 1 > (I ) = -n + -n + -n -- 3 2 6 I=1 | function ---------- | is displayed as in the built-in Equation Writer. User Functions -------------- The user can create own functions for example by typing 'F(X,Y)' directly or executing { X Y } 'F' APPLY. The AGROB parser utilizes this feature for executing various functions on the arguments as follows: 'Mul(expr1,expr2)' ==> Multiplication with no mult. mark 'Der(expr,n)' ==> nth derivative of expr (tick form) 'DER(expr,n)' ==> nth derivative of expr (d/dx form) 'der(expr,n1,n2..)' ==> nth partial derivatives of expr 'Grad(expr)' ==> Gradient 'Div(expr)' ==> Divergence 'Curl(expr)' ==> Curl 'Lap(expr)' ==> Laplacian 'LapT(expr)' ==> Laplace transform 'FouT(expr)' ==> Fourier transform 'ILapT(expr)' ==> Inverse Laplace transform 'IFouT(expr)' ==> Inverse Fourier transfrom 'Cross(expr1,expr2)' ==> expr1 x expr2 'If(expr1,expr2)' ==> expr2 ,expr1 'So(expr1,expr2)' ==> expr1 ==> expr2 'Equ(expr1,expr2)' ==> expr1 <==> expr2 'PM(expr1,expr2)' ==> expr1 plus/minus expr2 'MP(expr1,expr2)' ==> expr1 minus/plus expr2 'pm(expr)' ==> plus/minus expr 'mp(expr)' ==> minus/plus expr The following are more about formatting than actually providing some mathematical functions: 'Par(expr)' ==> Parenthesis are drawn around the argument 'Vector(expr)' ==> An arrow is drawn above the argument 'Top(expr1..exprN)' ==> The arguments are shown on top of each other, aligned to left border. 'Lt(expr1..exprN)' ==> The argument is given a left brace "{" For multiple arguments Top is called 1st 'Rt(expr1..exprN)' ==> The argument is given a right brace "}" For multiple arguments Top is called 1st 'fm(expr)' ==> Decrement font size for expr 'fp(expr)' ==> Increment font size for expt The user should note that all of above are just pseudo-functions, the only thing they do is to arrange the arguments in a convenient way. Thus for example true functions do not 'see' the pseudo-functions to have any special priorities, and thus parenthesis may not be shown when needed. The 'Par' pseudo-function is provided for use in such cases. To support the common notation for special functions the following patterns at the end of the function name are recognized: '.n' ==> First argument is shown as subindex. Remaining arguments, if any, are shown in parenthesis. '.nm' ==> First argument is shown as subindex, second as topindex. Remaining arguments, if any, are shown in parenthesis. Examples: 'J.n(n,x)' ==> J (x) (Bessel function) n m 'P.nm(n-1,m,x)' ==> P (x) (Associated Legendre function) n-1 For more examples please see the samples directory provided with the package. 4.2 ASTK Parser --------------- Calling AGROB blindly for all objects could be unbearably slow. Thus ASTK calls AGROB subroutines to decompile an object only when: - The object is one of the following: Albebraic, global name, local name, unit, array, grob - The object is a list containing less than 20 objects 5.0 COVERED PORTS ================= The internal Agrob subroutine is unsafe if evaluated from a covered port. Thus both AGROB and ASTK copy it to a variable named 'agrob' in the hidden directory for evaluation if needed, both also purge it when they exit. Should you happen to exit either program by ON-C though, the variable would remain in the hidden directory and would take 10Kb of user memory. To make sure it doesn't remain there simply start and exit ASTK. 6.0 SAMPLES =========== The package provides a BZ-compressed sample directory of objects. To have a look at them, simply download the file to your HP48, uncompress it with BZ, store it to a variable and enter the directory. Then start ASTK and press any variable name to see the object in it. Note that some of the objects are invalid in regular HP48 operation, and have been built with hacking tools just to see what AGROB can do. None of the objects will cause an error in the normal HP48 display, but you should not try to operate with them. 7.0 SOURCE CODE =============== The source code is included in the package in GNU Tools format (new opcodes and label generation are used). Programmers of various alternative stack displays may wish to extract XLIB 740 2 (AGrob in the source code) to be used in their own stack display programs. Permission to use it is hereby granted, provided the program is not commercial. For convenience some conditional flags are provided in the source code to enable easy removal of some of the 'fancier' features. 9.0 HISTORY =========== EQSTK library is largely based on the AWV48 library by Claude-Nicolas Fiechter. v1.0 ---- - Faster. - Added integral, summation, derivative - Implemented ASTK v2.0 ---- - Subscripts - A couple bug fixes. v3.0 ---- - Faster. - Implemented most of the missing internal functions. - Implemented array decompilation - Implemented unit decompilation - Implemented dotted subscripts - Allowed arrays and lists in ASTK display - Fixed a bug in ASTK display loop - Works from covered ports too (6.5K memory requirement) v4.0 ----- - Fixed MOD, XOR - Implemented XROOT - Implemented special grobs for AND, OR, NOT, XOR - Implemented special identifier names (Phi, Psi..) - Improved derivative output to be more compact when possible - Fixed the EXPLODE substitute - Fixed minus (-) to use proper priority setting for the rightmost argument - Allowed special identifiers in user function names - Allowed special identifiers in derivative variable names - Implemented special user functions - Modified samples to use new features, added more samples. v5.0 ---- - Speeded up in several places - Implemented tagged objects - Added more special identifiers v5.21 ----- - Fixed size 3 representation for NEG - Validated DA1 always so that ON-key aborts editline properly. - Fixed grob! substitute to work properly when called to bang a grob of width 57 at the last pixel of a nibble. v5.3 ---- - Use "1; " or similar for displaying equations that do not fit on the line. - Fixed matrix dimension tests to be absolutely valid v5.4 ---- - Implemented special grob for 'GAMMA' - Allowed romptr function names to be special user functions (GAMMA etc) - Implemented .n and .nm type function name formatting - Implemented pm and mp user functions to complement PM and MP - Implemented DER, Der and der user functions - Allowed multiple arguments for Lt and Rt user functions, in which case the Top user function is called first. - Implemented user functions fm and fp for font size control v5.5 ---- - Fixed NOT priority (relative to AND and XOR) v5.6 ---- - Implemented array size checks to reduce hopeless tasks (out of memory) - Added new samples, removed ALG48 tests as too trivial examples - Compiled 2 versions: eqstk.lib - Full version eqstkb.lib - Small version (all compiler flags cleared) v5.7 ---- - Added parenthesis if left argument of * is a unit object v5.8 ---- - Fixed WHERE function for multiple equates v6.0 ---- - Fixed { {} { A B } } not to crash AGROB v6.1 ---- - Fixed problem with the priority of negative real numbers - Made the configuration object to automatically purge 'agrob' from hidden dir v6.2 ---- - Uses UFL small font instead of Jazz small font v7.0 ---- - Requires UFL with FNT1 and FNT2 to be present v8.0 ---- - Fixed integration variable to be parsed as a general identifier to allow for example intergration with respect to phi - Added stack decompile speedups. Whenever stack decompile is requested and the topmost function is one of + - * = <= >= etc the left hand side is decompiled first. If the result is wider than the display the right hand side is ignored. v9.0 ---- - Cache implemented for ASTK to provide great speedup for stack display when the stack doesn't change much. v9.1 ---- - Implemented checks on changes in system flags affecting display modes to force a cache clear and thus a redraw. - Fixed exit from EQSTK to be as valid as possible for all possible stack save modes.