VX/BASIC

Register to Download a Free 30-day trial for Unix

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

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
PRINT 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 :
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
Translates to:
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:
DECLARE STRING MYSTRING
DECLARE LONG MYTEMP
DECLARE WORD MYTEMP%
MYSTRING = STR$(MYTEMP + MYTEMP%)
Translates to:
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 BASIC
PRINT #chan%, A$, B$; C%
Translates to:
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 BASIC

A$ = RIGHT$(LEFT$(MID$(A$, 1,2), 2), 3)

Translates to:
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 %PRINT %IDENT
%CROSS %NOCROSS %LIST %NOLIST
%INCLUDE %PAGE %REPORT %SBTTL
%TITLE %VARIANT    

Expressions and evaluations are also supported.