HP 2000 Time Share System

HP 2000 compatible Basic Interpreter

I wrote this 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. It required a few months of work, on and off between 2000 and 2002, to get the interpreter to where it is now. When I got tired of working on it I stopped which was right in the middle of implementing file I/O statements.

I have only received a couple of emails about Basic in the years it has been available so I have no idea how much interest there might be in future development. If you have any comments, suggestions or questions feel free to contact me.

Basic is a Windows console application. It includes a very simple Help command.
Download BASIC v0.93 build 131 (2022-Jul-21) - Includes a sample graphics demo and Star Trek game

The name of the manual for the HP Basic version this is based on is "2000 Basic ReferenceManual 22687-90001. Nov 77"
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 editor
Editor (Working)
    GET 
    SAVE 
    LIST [<start#> [<end#>]]
    DEL   <start#> [<end#>]
    RUN
    SCR                // scratch
    LEN
    BYE
    <line#>            // Deletes line #
    <line#> ;          // Enter blank line
    <line#><statement>
    PRINT
    HELP
Statements (Working)
 
    PRINT USING                                       // With limitations
    IMAGE
    LINPUT [<"prompt">,]<stringVar>                   // "prompt" is an extension
    INPUT [<"prompt">,]<varList>                      // "prompt" is an extension
    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   0x1F
Expressions, 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'7
Other (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         // Extension
Other Remaining HP Items:
    ENTER 
    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