VX/BASIC
VX/BASIC is a full-featured VMS/BASIC to ANSI C Compiler/Transpiler®. VX/BASIC allows VMS/BASIC source code to be compiled on multiple host machines. The application can be maintained in the original BASIC language or converted into C code.
Features
Introduction
BASIC statements and functions
Maps and Records
Data Types
Variable Naming
Basic Statements
Basic Functions
Run-time Errors and Error Trapping
Preprocessor
Features
- Allows VMS/BASIC programs to be compiled without change on Linux/UNIX
- Enables developers to work in VMS/BASIC or C
- Retains the original structure, comments and variable names
- Support for MAP, COMMON and RECORDS
- Support for System Services
- Support for RMS (KEYED, RELATIVE, VIRTUAL & SEQUENTIAL)
Introduction
VX/BASIC allows developers to maintain their code in VMS/BASIC on a VMS or ALPHA, and transpile the code for Linux/UNIX. Using C as the intermediate language, VX/BASIC takes advantage of all the elements of C compilers and object code optimizers. By generating ANSI C, users of VX/BASIC are assured that no matter how chip technology changes, the transpiled code can be compiled.
VX/BASIC retains the original structure, variable names and comments, thus, developers can choose any time to move to C and maintain the source code in C, or retain all the investment in VMS/BASIC and transpile for the target hardware platform. For VMS/BASIC developers, compiling the VMS/BASIC is only half the story. Most VMS/BASIC programs use VMS system service calls (implicitly for RMS or explicitly). Sector7 has developed more than 400 VMS system service calls for Linux/UNIX. Included with the base VX/BASIC product is VX/Tools.
BASIC Statements and Functions
The following BASIC statements and functions are supported by VX/BASIC
| ABS | ABS% | AND | ASC |
| ASCII | ATN | BUFSIZ | CALL |
| CASE | CAUSE | CCPOS | CHAIN |
| CHANGE | CHR$ | CLOSE | COM |
| COMMON | COMP% | CONTINUE | COS |
| COT | CTRLC | CVT$$ | CVT$% |
| CVT$F | CVT%$ | CVTF$ | *CVTIE$F |
| *CVTIEF$ | DATA | DATE$ | DECIMAL |
| DECLARE | DEF | DEF* | DELETE |
| DET | DIF$ | DIM | DIMENSION |
| ECHO | EDIT$ | ELSE | |
| END | ENDIF | EQV | ERL |
| ERN$ | ERR | ERT$ | EXIT |
| EXP | EXTEND | EXTERNAL | FIELD |
| FIND | FIX | FNEND | FNEXIT |
| FOR | FORMAT$ | FREE | FSP$ |
| FSS$ | FUNCTION | FUNCTIONEND | FUNCTIONEXIT |
| GET | GETRFA | GO | GOSUB |
| GOTO | HANDLER | IF | IFEND |
| IMP | INKEY$ | INPUT | INSTR |
| INT | INTEGER | INV | ITERATE |
| KILL | LBOUND | LEFT | LEFT$ |
| LEN | LEN | LET | LINE |
| LINPUT | LOC | LOG | LOG10 |
| LSET | MAG | MAGTAPE | MAGTAPE |
| MAP | MAR | MAR% | MARGIN |
| MAT | MAX | MID | MID$ |
| MIN | MOD | MOVE | NAME |
| NEXT | NO | NOECHO | NOEXTEND |
| NOMARGIN | NOT | NUM | NUM$ |
| NUM1$ | NUM2 | ON | ONECHR |
| ONERROR | OPEN | OPTION | OR |
| PEEK | PICTURE | PLACE$ | POS |
| PROD$ | PROGRAM | PUT | |
| QUO$ | RAD$ | RANDOM | RANDOMIZE |
| RCTRLC | RCTRLO | READ | REAL |
| RECORD | RECOUNT | REM | REMAP |
| RESET | RESTORE | RESUME | RETRY |
| RETURN | RIGHT | RIGHT$ | RMSSTATUS |
| RND | RSET | RUN | SCRATCH |
| SEG$ | SELECT | SET | SGN |
| SIN | SLEEP | SPACE$ | SPEC |
| SPEC% | SQR | SQRT | STATUS |
| STOP | STR$ | STRING$ | SUB |
| SUBEND | SUBEXIT | SUM$ | SWAP |
| SWAP% | SYS | TAB | TAN |
| TIME | TIME$ | TRM$ | TRN |
| UBOUND | UNLOCK | UNTIL | UPDATE |
| USE | VAL | VAL% | VMSSTATUS |
| WAIT | WHEN | WHILE | XLATE |
| XLATE$ | XOR |
* = Sector7 Extended BASIC functions
Maps and Records
Maps and records are converted into C structures. VX/BASIC supports two conversion types. For processors that allow numeric data types to align on any boundary, the BASIC data types are converted in standard C data types, and regular C structure accessing code is generated. Most UNIX processors and C compilers will force numeric data types to be aligned on even byte boundaries. They do this by automatically inserting "slack" bytes to pad the structures. This can cause serious problems for BASIC users who would expect overlaid MAPS to align. For these processors VX/BASIC has an option to treat all numeric data types as arrays of bytes (long words are typedef'd to char[4], doubles to char[8]).
VX/BASIC then generates code that will access this data without causing processor bus errors. This access method does add some overhead to the execution time and users are strongly urged to re-organize MAPs and RECORDs for even byte alignment. For details on your target machine please contact Sector7.
MAPs of the same name are overlaid identically to VMS. VX/BASIC supports GLOBAL (SHARE) MAPs. Unlike VMS, all MAPs are linked by default NOSHARE.
Example BASIC :Translates to:
- RECORD MYREC
- WORD W2 STRING
- S2 = 20
- END RECORD
- MYREC MAP (TEST) STRING S1 = 13, &
- DOUBLE D1,
- LONG L1, &
- WORD W1, &
- MYREC R1
- D1 = L1 * R1::W2
- typedef {
- short W2;
- char S2[20];
- } MYREC;
- struct {
- char S1[13];
- double D1;
- long L1;
- short W1
- MYREC R1;
- } *test;
- test->D1 = test->L1 * test->R1.W2;
As Multiple map definitions may be present for the same map name, VX/BASIC initializes the MAP structure pointer to the data space allocated for the largest map declared in the program. As the map data space is global, the UNIX linker will overlay all linked modules, declared map space (of the same name) to the same address space and allocate enough space for the largest found map.
If the MAP has been installed as a shareable image, shared memory will be allocated from the UNIX kernel and all maps declared SHARE will point to the same system-wide shared memory. As the library name is included in the SHARE definition, multiple maps of the same name___but different libraries___are supported.
Datatypes
VX/BASIC supports all VMS/BASIC data types except GFLOAT and HFLOAT. If these are declared in a program VX/BASIC will convert them to DOUBLE. Note that DOUBLE on Linux/UNIX has a similar range and precision to GFLOAT on the VMS.
DECIMAL data types are supported, but have a maximum range of (15,8). Both DYNAMIC and STATIC strings are implemented. VX/BASIC uses the same descriptor structure as VMS/BASIC. All VMS/BASIC string operations are fully implemented.
Variable Naming
VX/BASIC retains the original variable names. If "$" or "%" symbols have been used to declare the variable an "s" or "p"' is prepended to the variable name. This allows the same name variable to be declared as two different data types (TEMP% and TEMP$). All arrays have an "a" prepended.
Example BASIC:Translates to:
- DECLARE STRING MYSTRING
- DECLARE LONG MYTEMP
- DECLARE WORD MYTEMP%
- MYSTRING = STR$(MYTEMP + MYTEMP%)
- struct {
- STRING MYSTRING;
- short pMYTEMP;
- long MYTEMP;
- } *Subv2;
- Vxb_strcpy(&Subv2->MYSTRING,
- Vxb_Str(Subv2->MYTEMP + Subv2->pMYTEMP));
Basic Statements
All VMS/BASIC commands have been implemented except graphics. Generally the VMS/BASIC commands translate to the same name, lowercased except the first character with "'Vxb_" prepended. Some commands (such as PRINT, READ, INPUT) take format strings that define the data types to be acted upon and the line formatting to be applied.
Example BASICTranslates to:
- PRINT #chan%, A$, B$; C%
- Vxb_Print(Subv2->pCHAN, "s,s;wR",
- Subv2->sA, Subv2->sB, Subv2->pC);
In the above case, a format string is generated to tell the print function what variables are being passed. "s,s;wR" is a STRING, a COMMA separator (field TAB), a STRING, a semi-colon telling PRINT not to field tab, and a "w" defining a WORD value. The "R" instructs PRINT to output a CR/LF sequence after the line has been printed.
One of the most commonly asked questions is "Do you use the C printf function for I/O". As can be seen above the answer is "No". "printf" does not perform the output formatting that is consistent with VMS/ BASIC. It also would not generate an error if any problem occurred (IO CHANNEL NOT OPEN, ILLEGAL IO CHANNEL). Also, with regard to maps and records, VMS strings are not NULL terminated, and the print function knows the length of the string to print from the descriptor.
All VX/BASIC commands perform identically to their VMS counterparts, including generating ERROR traps and setting the ERR, ERL, ERN$, ERT$ variables. See section on "Run-time errors and Trapping."
Basic Functions
Much like statements, VX/BASIC retains the original VMS/BASIC function name as a base for the VX/BASIC function name. All VX/BASIC functions take the same arguments as the original VMS/BASIC function and produce the same data type result. Numeric functions return their values on the stack and STRING and DECIMAL functions return values as pointers to temporary descriptors. This allows functions to be "stacked" and translated in a single line.
Example BASICTranslates to:A$ = RIGHT$(LEFT$(MID$(A$, 1,2), 2), 3)
- Vxb_strcpy (&Subv2->sA,
- Vxb_Right (Vxb_Left(Vxb_Mid(Subv2->sA,1,2),2),3)
All VX/BASIC functions perform identically to their VMS/BASIC equivalents. In the case above all three string functions would check the length of the input string and apply the same rules as VMS/BASIC.
Some VX/BASIC functions will also generate ERROR traps in certain conditions (VAL("HH") will generate ERROR 52). Others like BUFSIZ() on an unopened channel simply return 0 (As VMS/BASIC).
A few VX/BASIC functions are generated with different designators, depending on the input data type. For optimization, VX/BASIC recognizes that VAL has been passed an INTEGER quantity and generates Vxb_Vali() rather than Vxb_Val().
Run-time Errors and Trapping
VX/BASIC supports the full range of VMS/BASIC error numbers and error handling.
- ON ERROR GOTO,
- WHEN ERROR IN
- ON ERROR GO BACK
- ON ERROR GOTO 0
- RESUME
- CONTINUE
- CONTINUE line number
- RESUME
- RESUME line number
Whenever an error is generated, the current error handler is evoked and the error processing executed. VX/BASIC returns the same error codes as VMS/BASIC (52 = ILLEGAL VALUE, 15 = WAIT EXHAUSTED etc).
If your program calls the VMS service routines directly, and checks the return value, it will still perform in the identical manner using the VX/RT libraries. Each VX/RT system service call returns the same codes as VMS (SYS$OPEN returns 98962, RMS$_FNF, if the file does not exist).
The BASIC error functions ERR, ERL, ERT$, ERN$ are set in the identical manner. If another error occurs in an error processing routine before the error has been cleared a BASIC stack dump is issued.
Preprocessor
VX/BASIC includes a pre-processor that handles all "%"meta commands. VX/BASIC supports VMS/BASIC % commands and allows conditional compilation on %VARIANT. The following keywords are supported:
| %DECLARED | %DEPENDENCY | %IF | %ELSE |
| %THEN | %END | %FROM | %LIBRARY |
| %LET | %ABORT | %IDENT | |
| %CROSS | %NOCROSS | %LIST | %NOLIST |
| %INCLUDE | %PAGE | %REPORT | %SBTTL |
| %TITLE | %VARIANT |
Expressions and evaluations are also supported.


