Iowa Basic - HP 2000 compatible Basic Interpreter
I wrote the Iowa Basic interpreter mostly to try out a method of implementation in C++. Memory has been sacrificed for fast execution and quick developement. If I were to do it all again I would not implement the interactive command line editor which is not very useful.
I was originally only going to implement HP 2000 Minicomputer Basic but I found it so limited that I ended up making it a subset of a more expanded Basic language which I have now named Iowa Basic. It required a few months of work, on and off between 2000 and 2002, to get the interpreter to where it is now.
I have only received a few emails about Basic in all the years it has been available so I have no idea how much interest there might be in future development.
Basic is a Windows console application. It includes a very simple Help command.
Download BASIC v0.94 build 154 (2024-06-23) - Includes a sample graphics demo and Star Trek game
You are invited to join the new Iowa Basic support group on Facebook. The more people that join this group, the more motivated I will be to continue with development.
The name of the manual for the HP Basic version this is based on is "2000BASIC_ReferenceManual_22687-90001_365pages_Nov77.pdf"
and is available here: HP 2000 Timershare System Documentation.
More about the 2000 Timeshare System at the HP Computer Museum.
Groups.io: HP2000 Family - HP2000 HP2100 HP2x0 HP3000 historic family
The remainder of this page contains some of my implementation notes.
== Now Working ==Basic [<fileName>] // Omit file name to start editorEditor (Working)
GETStatements (Working)SAVE LIST [<start#> [<end#>]] DEL <start#> [<end#>] RUN SCR // scratch LEN BYE <line#> // Deletes line # <line#> ; // Enter blank line <line#><statement> PRINT HELP
PRINT USING // With limitations IMAGE LINPUT [<"prompt">,]<stringVar> // "prompt" is an extension INPUT [<"prompt">,]<varList> // "prompt" is an extension ENTER MAT <numericArray> = (<numericExp>) // extension MAT <numericArray> = ZER // same as MAT <array> = (0) MAT <numericArray> = CON // same as MAT <array> = (1) MAT <numericArray> = <numericArray> MAT <stringArray> = (<stringExp>) // extension MAT <stringArray> = <stringArray> // extension CONVERT <stringExp> to <numeric>,[<line>] CONVERT <numericExp> to <string> DEF FN<name>([<parmList>]) = <numericExpression> // Multiple and String parms are extensions DEF FN<name>$([<parmList>]) = <stringExpression> // String functions are an extension READ <readList> DATA <dataList> RESTORE [<statementNumber>] RESTORE <expression> OF <statementLabelList> [ELSE <label>] // Extension IF END THEN // For DATA ON END THEN // Extension. IF END is changed to ON END OFF END // Extension. Turn off set ON END condition. LET <numeric> = [<numeric=] <Numeric Expression> LET <string> = [<string> =] <String Expression> // Multiple string assignment is an extension LET <var>[,<var>] = <exp> [; [<assignment>]] // Multiple assignments converted to this IF <expression> THEN <statementLabelList> IF <expression> THEN <statement> // Extension IF <expression> THEN // Extension ELSE // Extension ENDIF // Extension GOTO <lineLabel> GOTO <expression> OF <statementLabelList> [ELSE <label>] // Extension: ELSE ON <expression> GOTO <statementLabelList> [ELSE <label>] // Extension GOSUB <lineLabel> GOSUB <expression> OF <statementLabelList> [ELSE <label>] // Extension: ELSE ON <expression> GOSUB <statementLabelList> [ELSE <label>] // Extension RETURN FOR <numericVar> = <numericExp> TO <numericExp> [ STEP <numericExp> ] NEXT <numericVar> WHILE <exp> // Extension NEXT // Extension REPEAT // Extension UNTIL <exp> // Extension SELECT <exp> CASE exp | <relational> <exp> | exp[,<expList>] | <exp> TO <exp> CASE ELSE ENDSELECT STOP END REM PRINT <print List> // needs some work DIM array(<dim>), array(<dim>,<dim>,...<dim>) // More than two dimensions is an extension DIM string$[<size>],string$[*] // Dynamic Length "*" - Extension DIM string$(<dim>,...<dim>)[<size>] // String Arrays - Extension COM // Common For Chain/Spawn CHAIN <file> SPAWN <file> // Spawn thread. Chain arguments. Extension LIN() SPA() TAB()Expressions, Numeric (Working)
NOT AND OR XOR EQV IMP // Extensions MIN MAX < <= = >= > <<> # + - * / MOD DIV // Extensions ** ^ ( ) ABS ATN COS EXP INT LOG SGN SIN SQR TAN RND FIX // Extension TIM // with extensions TYP(0) // for Data TID(0) // Thread ID DEC(S$) // Convert decimal string to numeric VER(0) // 0:Full; 1:Version; 2:Revision; 3:Build - Extension LongVariableName // Long names are extensions LongVariableName(<subscript>) LongVariableName(<subscript>,<subscript>) FnFunctionNames(<string and/or numeric argument list> ) Constants - Example: 26 10.525E5 0x1FExpressions, String (Working)
< <= = >= > <> # + // Extension UPS$ CHR$ LEN POS NUM ASC // Extension - same as NUM DEC$ // Extension - convert number to decimal string // These never return more than the strings length (no padding) LEFT$(Str$,length) RIGHT$(Str$,length) MID$(Str$,start[,length]) A$[<start>;<len>] // Substring extension from HP3000. Substrings must use [] A$(array)[<substring>] // String array extension. String arrays subscripts must use (). // Numeric arrays may use [] but they will be changed to (). LongVariableName$ // Long names are extensions LongVariableName$(<substring>) FnFunctionNames$(<string and/or numeric argument list>) // Extension Literals - Example: "String" '34"String"'34'7Other (Working) Extensions
Bad syntax lines are kept and preceeded with a '?' Single and End-of-line comments with '!' or '//' String arrays default to undefined. Non-executing statements have zero performance penalty.Notes:
Non-executing and compound statements not allowed after THEN. EG: DIM,DEF,FOR,NEXT,REPEAT etc. Indented compound statement listing Checks for loops spanning IF ELSE ENDIF blocks Checks for loops tangled with other loops. EG: REPEAT..FOR..UNTIL..NEXT Keeps case of variable names. Variables are not case sensitive. Blank not required after line number. Statement Labels: Values are rounded when converted internally to integers. Maximum statement number is 999999== Not Completed ==
All the file I/O remains:
FILES ASSIGN READ# PRINT# ADVANCE UPDATE LOCK UNLOCK ITM() TYP() for files IF END# LINPUT# CREATE PURGE EXTEND // ExtensionOther Remaining HP Items:
SYS(), BRK() CTL() MAT <array> = <array> * <array> MAT <array> = <array> + <array> MAT <array> = <array> - <array> MAT <array> = (<expression>) * <array> MAT <array> = TRN(<array>) MAT <array> = INV(<array>) MAT <array> = IDN MAT PRINT MAT READ IF ERROR SYSTEM