Better Late Than Never--VAL() in HP-71B BASIC « Next Oldest | Next Newest »

 ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-06-2011, 11:15 AM I was looking at the HP-71B Math Solutions book. I discovered, to my surprise and delight, that the HP-71B function VAL goes way beyond the typical VAL implementations found in other BASIC interpreters. The HP-71B runs the argument of VAL through the BASIC interpreter engine allow you to evaluate strings as functions. For example, if I have already assigned the value of 1 to variable X, then VAL("X^2-3*x+6") yields 4!! Using this feature you can define the function: DEF FNX(E\$,X) = VAL(E\$) To evaluate functions dynamically as long as the expression in parameter E\$ is a string that represents a valid expression of X. Of course the arguments for parameter X in FNX() can be any variable or expression, since VAL(E\$) evaluates E\$ using the argument for parameter X (and not a variable named X defined in the program). I was delighted to discover this feature of VAL() .... Oh well .... better late than never!! Namir ▼ Marcus von Cube, Germany Posting Freak Posts: 3,283 Threads: 104 Joined: Jul 2005 05-06-2011, 11:56 AM For those who want more info about the different BASIC variants: I've prepared a spreadsheet which compares many BASIC dialects. The VAL() functionality Namir has found should be in the sheet as the 71B is one of the systems discussed. Here you are: http://www.mvcsys.de/doc/basic_compare.html. ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-06-2011, 12:13 PM Impressive comparison table!!! As I suspected, the HP-71B and HP-75 implement the VAL() function that goes beyond simply converting a string image of a number into a number. Using a function like VAL() (and EVAULATE() in Excel VBA) allows you to write programs that handle functions dynamically. Of course, the price to pay for this flexibility is speed. Namir Edited: 6 May 2011, 12:20 p.m. ▼ Bill Wiese Senior Member Posts: 308 Threads: 26 Joined: Jul 2007 05-06-2011, 02:20 PM This was always an irritant to me in other BASICs of the era - most if not all of those MS BASICs (Commodore, Apple, etc.) just implemented an "atof()" function. I recall I was able to take C64 BASIC's "USR(x)" function and hotwire it to pull a string instead of numeric argument - and then call the FRMEVL routine at \$AD9E to do 'formula evaluation'. I think I had to also tokenize the string before calling FRMEVL. Bill Wiese San Jose CA Edited: 6 May 2011, 2:20 p.m. ▼ Mark Storkamp Member Posts: 83 Threads: 5 Joined: Oct 2007 05-06-2011, 02:30 PM You could do something similar as well on the Apple ][. Another form of synthetic programming. Your program always started at the same location in memory, so if you made your first line: 10 ::::::::::::::::::::::::::::::::: RETURN Then you could use POKE to enter your tokenized string in place of the : CALL 10 would execute your line. And the manuals in those days were so thorough that they gave you all of the addresses and token values needed to pull off things like that. Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-06-2011, 02:52 PM While GW-BASIC implemented a simple VAL() function, I resorted to another trick to support dynamic functions at run time. I used this kind of trick in regression programs that allowed the user to enter transformations for data at run time. My program would convert the user's input into a short/small line-numbered BASIC program that's written out to disk and then use the CHAIN MERGE command to chain/merge the current program with that small programs. This approach turned the dynamic functions and expressions into BASIC statements that are then handled by the interpreter. When I moved from GW-BASIC to Turbo-Pascal (a compiler) I sure missed that trick! Namir Edited: 6 May 2011, 2:53 p.m. ▼ Eric Smith Posting Freak Posts: 2,309 Threads: 116 Joined: Jun 2005 05-06-2011, 04:05 PM Nowdays in C++, one can use LLVM to generate object code on the fly. It doesn't parse expressions from a human-readable string representation, though. Oliver Unter Ecker Member Posts: 239 Threads: 9 Joined: Dec 2010 05-06-2011, 04:32 PM How does Val() deal with "2^8" (two power eight), or "5!" (five factorial)? ;-) As other dynamic languages these days, JavaScript has an eval() function that allows you not only to evaluate constant expressions, but any JavaScript code. Also, functions are data and can be constructed on-the-fly. If you want to write a calculator, though, you still need an expression parser to deal with cases like above (and types other than Reals). One of the reasons why MorphEngine is called MorphEngine, is because it takes expressions and "morphs" them into dynamically-created functions (written via a LALR parser, fed by a BNR grammar). I understand, (RPL) HPs have a compiler/decompiler to accomplish making expressions executable, and vice versa. ▼ Marcus von Cube, Germany Posting Freak Posts: 3,283 Threads: 104 Joined: Jul 2005 05-06-2011, 04:39 PM As implemented on the 71b, VAL() parses the string as BASIC text, so any functions known to the interpreter can be used. The string must represent a valid expression as defined for the language. ▼ Paul Guertin Member Posts: 79 Threads: 5 Joined: Jun 2007 05-07-2011, 01:01 AM Quote: As implemented on the 71b, VAL() parses the string as BASIC text, so any functions known to the interpreter can be used. The string must represent a valid expression as defined for the language. What happens when you call VAL(E\$) and E\$ contains the string "VAL(E\$)"? ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-07-2011, 03:24 AM You get an "Invalid Arg" error. ▼ J-F Garnier Senior Member Posts: 412 Threads: 40 Joined: Mar 2006 05-07-2011, 04:01 AM No, the HP71B goes into infinite recursive calls!! ```>endall >destroyall >mem 9135 >e\$="val(e\$)" >val(e\$) ERR:Insufficient Memory >mem 2810 >endall >mem 9128 ``` (tested on Emu71. On a real HP-71B, you may have to break the long recursion time with INIT 1] J-F ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-07-2011, 06:48 AM Interesting! The first time I tried: ```E\$="VAL(E\$)" VAL(E\$) ``` I got the invalid arg error using the EMU71. When I do: ```ENDALL DESTROY ALL E\$="VAL(E\$)" VAL(E\$) ``` I get "insufficient memory" with the EMU71. Namir Edited: 7 May 2011, 6:49 a.m. Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-07-2011, 06:53 AM Do you have any plans to re-implement the EMU71 so that it can run under Windows 7 64 Bit? To run the EMU71 I have to run "VMLite XP Mode" which runs as 32 Bit OS. Namir Edited: 7 May 2011, 6:53 a.m. ▼ Marcus von Cube, Germany Posting Freak Posts: 3,283 Threads: 104 Joined: Jul 2005 05-07-2011, 07:07 AM As far as I understand, EMU71 is written in x86 16 Bit assembly. Porting will be a huge task! Have you tried DOSBOX or, as an alternative, plain DOS in any virtual machine like Virtual PC? Edited: 7 May 2011, 7:08 a.m. ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-07-2011, 01:18 PM I am using the regular DOS box in VMlite Windows XP. I will try to locate DOSBOX. Thanks for the tip. Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-07-2011, 01:42 PM Marcus, I found DOSBOX and it works fine with EMU71. The only feature not supported from the plain DOS box is the ability to pasted source code into the emulator (J-F Garnier had suggested this tip on the site a few months ago). Garnier's tip works when I use the DOS box under VMlite Windows XP. Namir Edited: 7 May 2011, 2:02 p.m. Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 05-06-2011, 06:35 PM On my Commodore PET (8K original one) I used to do something similar. You could print an expression (or statement) on the screen followed by a RUN or GOTO command; then stuff the keystroke buffer with cursor moments and RETURN characters and end the program. The keystroke buffer would be read out by the "operating system" and execute your commands then start up the program again. It, made for great self modifying code not just dynamic expression evaluation. -Katie ▼ Namir Posting Freak Posts: 2,247 Threads: 200 Joined: Jun 2005 05-06-2011, 06:46 PM That cool ... sounds similar to using CHAIN MERGE in GW-BASIC. I doubled checked the HP-85 owner's manual to see how the VAL() function works. I was hoping that it matched the VAL() function in the HP-71B. My hopes were dashed :-( Namir Edited: 6 May 2011, 6:47 p.m. Thomas Radtke Posting Freak Posts: 1,089 Threads: 32 Joined: Dec 2005 05-07-2011, 03:34 AM Quote:I discovered, to my surprise and delight, that the HP-71B function VAL goes way beyond the typical VAL implementations found in other BASIC interpreters. The HP-71B runs the argument of VAL through the BASIC interpreter engine allow you to evaluate strings as functions. For example, if I have already assigned the value of 1 to variable X, then VAL("X^2-3*x+6") yields 4!! The Sinclair ZX Spectrum had this feature, too. BTW, I'm using a similar function in php to have the user define some conditions inside a semiautomatic risk analysis software. Very useful. ▼ Howard Owen Posting Freak Posts: 1,830 Threads: 113 Joined: Aug 2005 05-07-2011, 02:26 PM I have been playing with Rocky Mountain BASIC again the last couple of days. At least in version 2.1, there's no string evaluation routine. At least I can't find it in the reference manual. It seems like the people in Fort Collins could have taken a hint from the guys in Corvallis in this regard. You can do recursion in RMB though. ▼ Garth Wilson Posting Freak Posts: 887 Threads: 9 Joined: Jul 2007 05-07-2011, 08:51 PM You can say that again! After having been quite familiar with my 71's BASIC (along with a lot of extensions from the user groups), I started working with HP Rocky Mountain BASIC 5.1 and was extremely disappointed. The HP-71 was far better. ▼ Katie Wasserman Posting Freak Posts: 1,477 Threads: 71 Joined: Jan 2005 05-07-2011, 09:38 PM I think that the finest version of Basic that HP ever created was Business BASIC for the HP 3000 series computers. The statement called COMMAND could dynamically execute almost any command in Basic, not just evaluate an expression. It was also pretty fast because it had a compiler in addition to the interpreter. I wrote a ton of code in this language including a complete email system (before the internet was common place). One of my favorite languages, ever. The original 3000 series was equally awesome with it's stack-based architecture and (sort of) high-level systems programming language instead of assembly. The good old days....... Howard Owen Posting Freak Posts: 1,830 Threads: 113 Joined: Aug 2005 05-08-2011, 01:21 AM There are things in RMB that the 71B lacks, however. Long variable names, COM blocks (ala FORTRAN) , REPEAT/UNTIL, WHILE, SELECT/CASE are all nice. The integrated code editor/execution environment was my first introduction to such things. It topped my list for productivity until I figured out how to use EMACS with gcc/gdb a couple of years later. I used the 9816 professionally, and it was a capable little beast for the era. It had an 8Mhz MC68000, which was fast enough to do a whole lot of simultaneous I/O. That CPU had 16MB of addressable memory. I believe the 9816 could only use half that for user memory, but it was still huge by contemporary standards. It was actually practical to have 1MB loaded into the 9816, plus an RS232 card, which together with HPIB made for an extremely capable and portable little computing package. I used these in offshore environments in the mid-1980s. Nonetheless, I'm very fond of my 71B. The BASIC on that machine has a lot of very nice features. The LEX file concept is very cool, allowing a user to extend the BASIC, but RMB had a similar mechanism. ▼ Garth Wilson Posting Freak Posts: 887 Threads: 9 Joined: Jul 2007 05-08-2011, 03:45 AM One of the 71 modules available had the program structures like CASE and so on, but I never got that one. For longer variable names and vertical alignment and white space for readability and so on, what I did sometimes was write the program in text with my full-featured text editor (waaaaay better than what came in the Forth module for example) and then use another program to take out the blank lines and formatting lines, combine things that had to be on the same line which I had separated for readability, give it line numbers, replace the variable names with HP71-legal ones, remove comments, and TRANSFORM it to BASIC (while keeping a copy of the original file). One thing I remember from RMB 5.1 running on the HP9000-series 68000 computer was that I couldn't just take lines I had already written and copy them somewhere else outside the structure or subprogram or something like that to reduce the amount of typing where I wanted a near-duplicate somewhere else. It would say that wasn't allowed. One program could not also refer to another program or subprogram in another file like the 71 can. It all had to be written into the same one. My memory of it is pretty foggy now, but I do remember that I kept running up against walls. Edited: 8 May 2011, 3:47 a.m. ▼ Howard Owen Posting Freak Posts: 1,830 Threads: 113 Joined: Aug 2005 05-08-2011, 11:50 AM Quote: One of the 71 modules available had the program structures like CASE and so on .. The JPCROM has that and more. I have that in EEPROM on m 71, and I love it. I've set myself up to do editing of 71B programs on my Mac (in Aquamacs. Some habits die hard.) using the PIL-Box to transfer the programs back and forth as text. That's fine as far as it goes, but it doesn't get me an editing/execution environment like RMB's EDIT mode. The 71B itself provides a pretty nifty editor, but it's limited by the one line display. Quote: One thing I remember from RMB 5.1 running on the HP9000-series 68000 computer was that I couldn't just take lines I had already written and copy them somewhere else outside the structure or subprogram or something like that to reduce the amount of typing where I wanted a near-duplicate somewhere else. You can do that with individual lines, by manually editing the line number, for example. But you can't delete or modify the FN or SUB definition or end markers once you've entered them. You have to delete the "entire context" meaning the whole sub or function. Also, you can't use REN to move lines relative to other lines. So if your renumber would cause the new lines to overlap other lines, or to move after or before preexisting lines, the renumber will fail. That's annoying, but I have to say, quirks like that are one of the reasons I feel good about getting anything done on any of these old machines. :) Regards,Howard

 Possibly Related Threads... Thread Author Replies Views Last Post HP PRIME - Need help for basic program svp. dg1969 4 1,282 10-08-2013, 04:06 PM Last Post: dg1969 Easter Sunday Basic Trigs (HP-12C) Gerson W. Barbosa 29 6,478 04-04-2013, 02:19 PM Last Post: Gerson W. Barbosa "The Basic HP-71" Jeff Davis 3 1,207 08-30-2012, 12:20 AM Last Post: Howard Owen EMU41: A Little Late to The Party, but Loving It! Les Wright 3 1,094 05-09-2012, 03:28 PM Last Post: Christoph Klug HP's Tired Basic Calculator Line Jeff 4 1,206 02-10-2012, 01:33 PM Last Post: Dirk Mehldau Day Late, Dollar short. William L. Drylie 13 2,441 09-20-2011, 02:13 PM Last Post: Namir After the 15c LE, better chance of a basic RPN calc from HP now? nick lidakis 80 10,736 09-18-2011, 08:15 AM Last Post: snaggs BASIC BEEP Howard Owen 5 1,152 05-12-2011, 05:03 PM Last Post: Garth Wilson Mardi Gras Basic Trigs (HP-12C) Gerson W. Barbosa 10 2,262 03-09-2011, 09:49 PM Last Post: Gerson W. Barbosa OT: Sharp PC-1270 BASIC Compiler V3.3 XYZT 1 902 12-18-2010, 05:02 PM Last Post: Thomas Okken

Forum Jump: