Basic to REXX program conversion

If, like me, you've been around computers for many years you may well have plenty of old Basic programs that you still find useful. I've now translated many such programs and thought these notes on conversion (which will doutless grow as I become more familiar with Personal REXX) might be useful...

Some changes are particularly obvious: Type indicators, used to identify variable types in Basic (% integers, & long integers etc.) can be dropped. Remark lines, which in Basic are written either as Rem statements or ' delimited end-of-line remarks will need to be changed to REXX's /* .... */ style comments. Basic subroutine labels and return statements will not need changing but the actual Gosub statements used to execute subroutines will need to be changed to REXX's call scheme unless the routine is modified so that a return value is provided and used (in which case an explicit call statement is not needed).

With Basic Print commands two options are available and the easiest is just to convert them into REXX Say statements. This however can lead to difficulties if your code contains Print commands that have a terminal semicolon to suppress the generation of a linefeed at the end of printing. Say instructions ALWAYS generate a linefeed so a better alternative is to replace all Print X type commands with Charout() function calls including explicit end-of-line characters only when needed. Print formatting statements that are based on Print Using commands can incidentally be handled in much the same way - all you do is incorporate the appropriate string handling functions, eg Left(), to mimic the Print Using field lengths. Simple Basic input statements again can be written in terms of REXX's equivalent Pull, Linein() or Charin() operations.

Going Loopy

Basic's For/Next loops have to be converted to REXX do/end loops and the only thing to remember here is that if a loop step value is being used you will need to include the 'By' keyword in the corresponding REXX version. For example a loop which in Basic reads...

	FOR P%=1 to N%-1 STEP 3
	[ body of loop]
	NEXT P%

needs to become...

	do i=1 to N by 3
	[ body of loop]
	end 

While/Wend loops similarly need to be changed to REXX's do-while/end equivalents. You may incidentally need to change some of the exit expressions used in loops and in other conditional test statements. Basic's '<>' (not equal to) operator for example will need to be written as '/=' in the REXX code.

In the main these types of statement swapping translations will be very straightforward because they do not in reality affect the overall structure of the program. I always tend to make a 'first wave' translation of the areas mentioned so far rather than tackle the complete translation in one go - it helps to introduce a recognisable REXX flavour to the code and provides a preliminary stopping off point before dealing with any more difficult conversion issues.

Basic Arrays

Array variables are used extensively in Basic and the fact that REXX does not provide conventional arrays might lead you to think that this is a potential trouble spot. In actual fact it isn't because Basic array variables translate very nicely into REXX stem based compound variable expressions. For example the array A(row%,column%) becomes A.row.column and a loop such as...

	FOR I%=1 to N
		FOR J%=1 to N
			A(I%,J%)=I%*J%
		NEXT J%
	NEXT I%

translates easily into...

	do i-1 to N
		do j=1 to N
			A.i.j=i*j
		end
	end

Basic arrays of course need to be explicitly dimensioned using Dim statements, eg Dim A(20,20). With REXX this is unnecessary and so these expressions can be removed altogether. What you do need to do however is initialise to zero (or any other suitable value) the stems used to represent numeric arrays especially if there is any chance that any elements of that 'pseudo-array' are likely to be referenced before a real numeric value is assigned to them. The reason for this is because REXX autoinitialises any unused variables (including stems) to the name of the variable itself. This means that unused elements in, say a numeric array A.x.y, would by default be initialised to the letter 'A'. Needless to say this would cause an error if such elements were then used in an arithmetic expression.

Why Not Give It A Try Yourself

Listings 1 and 2 provide a typical translation example and although I won't pretend that all areas of Basic code <->REXX code translation are easy certainly programs which use only what you might call 'Microsoft flavoured core commands' are straightforward. In some cases you'll find statements that can't be duplicated by an equivalent REXX statement. There are usually ways around this and often the Personal REXX Windows extension functions may be of use. My advice at this point is simple - experiemnt. Get out your old Basic code and try a few conversions for yourself. I think you'll be pleasantly surprised at the results!


GOSUB ESTIMATE'--------------------> Get initial X estimate
PRINT PROMPT2$
X$=""
WHILE LEN(X$)=0
  GOSUB REFINE '"ITERATIVE REFINEMENT"
  GOSUB CURRENT.SOLUTION'"PRINT ITERATION VALUES"
  FOR I%=1 TO N%:X(I%)=X(I%)-DELTA.X(I%):NEXT I%'Adjust X() values
  PRINT PROMPT2$
  INPUT X$
WEND
END'.... Logical end of program

Listing 1: Some typical Basic code 


d=Estimate() /* --------------------> Get initial X estimate */
d=Lineout(stdout,PROMPT2)
x=''
do while Length(x)==0
  d=Refine()           /* ITERATIVE REFINEMENT */
  d=CurrentSolution()  /* PRINT ITERATION VALUES */
  do I=1 to N
       X.I=X.I-DELTA_X.I /* Adjust X() values */
  end 
  d=Lineout(stdout,PROMPT2)
  x=Readln(stdin)
end
exit /* Logical end of program! */

Listing 2: REXX style equivalent of listing 1


Go back toReturn to page at previous level

Go back toReturn to main index page

Page last updated 21-Nov-96