# SDS BASIC

SDS BASIC, also known as CP-V BASIC, Batch BASIC or Sigma BASIC depending on the version, is a BASIC programming language compiler for Scientific Data Systems's (SDS) Sigma series mainframe computers, originally released in 1967. Xerox purchased SDS in 1969 and began rebranding it as Xerox Data Systems, and finally just Xerox, at which time the language became known as Xerox BASIC.
The original versions did not include support for string variables, although this was added for the version running under the CP-V operating system when it was released in 1971. The string library allowed manipulation of strings using array slicing syntax, similar to the system found in HP Time-Shared BASIC and a number of microcomputer BASICs like Integer BASIC and Atari BASIC.
This style of string manipulation differs from the model introduced in DEC's BASIC-PLUS, which used string functions. Altair BASIC was patterned on BASIC-PLUS, and this style became the de facto standard after the cross-platform version, Microsoft BASIC, became almost universal during the home computer era. This makes conversion from SDS to modern dialects somewhat difficult.
SDS BASIC is historically notable as the platform on which the original Star Trek computer game was written in the summer of 1971.

## Syntax

In keeping with the original Dartmouth BASIC model, and in common with most mainframe-based BASICs, SDS BASIC was a compiler, not an interpreter, and used separate but tightly integrated tools for editing and running. The editor was dedicated to BASIC; as lines are entered they are analyzed for correct syntax and then stored in tokenized form. If a line is entered with a number at the start, it is placed into the appropriate location in the program based on the number, lines without numbers were immediately processed and then forgotten. SDS allowed line numbers in the range 1 to 99999. A simple example is:
Like many versions of BASIC, SDS allowed a single line of code to contain multiple statements. In most dialects this is indicated using the colon, but SDS used either the backslash, \ or ampersand, &. An equivalent line in SDS would be:
Because SDS was a compiler, and the user's source code was stored separately, it preserved leading spaces in the code. They suggested using this to more clearly indicate the structure of loops:
This example also includes the ability to set multiple values in a single LET statement, as seen in lines 10 and 40. This feature was also found in HP BASIC. As in most versions of BASIC, the keyword LET is optional, and is left out of line 40. Line 40 also illustrates the alternate form of assignment seen in a number of early BASICs, where multiple assignments can be separated with commas.
Common mathematical operations included +, -, * and /, using ^ or ** for exponents. Logical comparisons, like HP, could be written in any order, so <= was equivalent to =<, and >< was the same as <>. Most dialects only allow the later syntax in both cases. Unlike HP BASIC, SDS did not include the ability to use the hash, #, as an alternate form of <>.
SDS supported computed GOTO using ON, but also allowed the alternate syntax with the ON at the end of the line instead of the front:
An alternate form of REM was a leading star, *, similar in purpose to the short-form found in MS-derived BASICs, the single quote, '.

## String handling

The early versions of SDS BASIC, sometimes known as Batch BASIC or BTM BASIC, did not support string variables. However, string values could be assigned to numeric variables which could store six characters as their EBCDIC numeric values. The later CP-V BASIC added true string variables containing up to 132 characters that could be indicated with a trailing dollar sign, $, or uncommonly, a leading $ — A$ and $A are equivalent. The manual notes that the latter format was added for compatibility with A00 BASIC.
Internally, CP-V used a fixed-length string layout consisting of an array of bytes that could not be changed in size at runtime. This was similar to the other BASICs that used slicing notation, like HP and Atari. It contrasts with the DEC/Microsoft style, where strings were dynamically allocated on a heap. Unlike the other fixed-length BASIC dialects, string variables did not have to be DIMmed prior to use, instead, all strings defaulted to a maximum length of 72 characters. This was a global setting that could be changed to better manage memory by setting it to a smaller value, or allow longer strings up to a maximum of 132 characters. This was accomplished using SET $=132. Confusingly, SET was also used for the entirely unrelated task of allowing variables to be used in DIM statements.
Because strings in CP-V did not present themselves publicly as arrays of characters, the slicing syntax was not based on array syntax. This meant CP-V also allowed the construction of arrays of strings, something dialects like HP and Atari lacked because they used array notation for slicing. One could thus make a matrix of strings using DIM:
would define a matrix containing a total of 50 72-character strings in a 5 by 10 matrix. Because the system supported arrays, slicing syntax was somewhat more complex than the system found in other versions. Examples include:
selects the first string in an array of strings, while:
selects a string from location 1,5 in a 2D array (matrix). Slicing was handled by adding a colon within the parens:
returned everything from the 4th character on:
selects five characters starting with the 4th character, while:
selects five characters starting with the 4th character of the string in locations 1,5 in a 2D array.
String constants could be delimited with either single or double quotes, making it easier to enclose quotes within lines. Valid examples include:
CP-V also includes the CHANGE command from Dartmouth BASIC, which converts a string into a series of EBCDIC numeric values and places them into a numeric array:
B will now contain a series of numbers corresponding to the EBCDIC values for each character.

## Input/output

SDS included a robust system for input/output based on "stream" numbers that could be specified in PRINT and INPUT statements. For instance, data could be read from a file using:
The first line opens a disk file with the name "FILE1", assigns it to stream 1, and indicates it will be used for input. The second line reads the next data from stream 1, in this case the first value, and assigns the resulting data to variable A. The system also included a unique "key" system that allowed data to be numbered and then accessed randomly. This was accomplished by adding the key number after a semicolon:
will attempt to read record 9999. Valid keys were in the range .001 to 9999.999, and if no keys were assigned in the files, lines were assigned numbers 1.000, 2.000, etc. The highest-valued key in a file could read using:
where the 1 is the stream number. Unstructured binary data could be read and written byte-at-a-time using GET and PUT.

## MAT commands

Later versions of Dartmouth BASIC included a suite of MAT commands that allowed operations on entire arrays (matrices) with a single statement. These were also available in SDS BASIC. In their simplest form, the MAT is used like an alternate form of LET, applying an expression to all the elements in an array. For instance:
Will add the value of every value in B to every entry in A, in the same fashion as:
As well as making the code shorter and more obvious, these commands also have the advantage of being highly optimized, easily outperforming the use of FOR/NEXT. Additional functions and statements modify PRINT and INPUT, invert arrays, and build identity matrixes and such in a single statement.