bas55 (ECMA-55 Minimal BASIC System) 2.0

ECMA-55 Minimal BASIC System

This manual is for bas55 (ECMA-55 Minimal BASIC System) version 2.0 (updated 6 May 2023).

Copyright © 2023 Jorge Giner Cordero

Permission is granted to copy, distribute and/or modify this document under the terms of the GNU Free Documentation License, Version 1.3 or any later version published by the Free Software Foundation; with no Invariant Sections, no Front-Cover texts and no Back-Cover Texts. A copy of the license is included in the section entitled “GNU Free Documentation License.”

Table of Contents


1 About

bas55 is an implementation of the Minimal BASIC programming language as defined by the ECMA-55 standard. bas55 provides an interpreter and an editor with line renumbering capabilities.

bas55 is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, either version 3 of the License, or (at your option) any later version.

bas55 is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.

You should have received a copy of the GNU General Public License along with bas55. If not, see https://www.gnu.org/licenses/.

The latest version of the program, source code and documentation can be found at https://jorgicor.niobe.org/bas55.


2 Tutorial

In these first sections we are going to see how to use bas55 and how to program in Minimal BASIC.


2.1 Hello world

First, start bas55 by executing it at the command line. You will see the program name and license, and then ‘Ready.’. You have just started bas55 in editor mode. Now, you can enter your program. Start by typing these two lines:

10 print "Hello, world"
20 end

This is your first program. A BASIC program is made by numbered lines, each line containing an statement. The first line contains the ‘print’ statement followed by a string of characters between quotes. With this line, we want to print on the screen the sentence ‘Hello, world’. The second line (line number 20) has an ‘end’ statement. Every BASIC program must have one and only one line with an ‘end’ statement, and this line must be the last one.

Now that we have the program, let’s run it. Type ‘run’. The system will compile and run our program. We will see this result:

HELLO, WORLD
Ready.

It is ok, but the first thing you notice is that the letters are all upper case. This happens because every line you enter in bas55 are translated to upper case when you are in editor mode. bas55 allows you to enter lines in lower case letters but only as a convenience. A correct BASIC program must be always in upper case.

You can see your program source by typing ‘LIST’. You will see on the screen:

10 PRINT "HELLO, WORLD"
20 END

As you see, your program is all in upper case.

If you want to change a line, you type the line again starting with the same line number. For example, we want to print ‘GOODBYE, CRUEL WORLD’ instead of ‘HELLO, WORLD’. Just type the line:

10 PRINT "GOODBYE, CRUEL WORLD"
LIST
10 PRINT "GOODBYE, CRUEL WORLD"
20 END

Now we want to print another line after the first. We can add a new line to the program between the lines 10 and 20. For that, we can use any line number from 11 to 19. We choose 15.

15 PRINT "GOODBYE"
LIST
10 PRINT "GOODBYE, CRUEL WORLD"
15 PRINT "GOODBYE"
20 END

As you see, when using LIST the lines appear ordered by line number.

Normally, the lines of a BASIC program are numbered 10, 20, 30, etc. so we can have space to insert a line between other two lines. But this is up to you. bas55 gives you the RENUM command that you can use to renumber the lines of a program. Let’s type it:

RENUM
LIST
10 PRINT "GOODBYE, CRUEL WORLD"
20 PRINT "GOODBYE"
30 END

The lines have been renumbered.

To remove a line, simply type its number and press the ENTER key.

10
LIST
20 PRINT "GOODBYE"
30 END

And renumber if you like:

RENUM
LIST
10 PRINT "GOODBYE"
20 END

You can list only one line:

LIST 10
10 PRINT "GOODBYE"

And you can list a range of lines:

5 PRINT "HELLO, WORLD"
RENUM
LIST
10 PRINT "HELLO, WORLD"
20 PRINT "GOODBYE"
30 END
LIST 20-30
20 PRINT "GOODBYE"
30 END

Or the lines from one you specify to the last:

LIST 20-
20 PRINT "GOODBYE"
30 END

Or the lines from the first to one you specify:

LIST -20
10 PRINT "HELLO, WORLD"
20 PRINT "BYE"

2.2 Saving and loading

To save our program on a file, use the SAVE command and the name of the file between quotes.

SAVE "HELLO.BAS"

And your program will be saved as HELLO.BAS.

To start a new program and remove the one in memory, simply use NEW.

NEW
LIST

Now, if we want to load our previous saved program, we use the LOAD command.

LOAD "HELLO.BAS"
LIST
10 PRINT "HELLO, WORLD"
20 PRINT "GOODBYE"
30 END

You can use your favorite text editor to write a BASIC program and the load it into bas55. Only keep in mind that bas55 allows to enter a program using lower case letters in editor mode, but when you are loading a program using LOAD the program bust be a valid BASIC program, that is, it must be all in upper case.


2.3 Comments

You can use the REM statement to put comments in your program. A line starting with a REM statement is not executed, and you can put your comment after the REM. For example:

10 REM THIS PROGRAM IS A TEST
20 REM AND DOES NOTHING
30 END

2.4 Input and variables

You can ask the user of your program to enter numbers or text. For that, you have to store the user’s input into variables. A variable is a name we give to some data. This is an example:

10 PRINT "ENTER A NUMBER:"
20 INPUT A
30 PRINT "YOUR NUMBER IS:"
40 PRINT A
50 END

If you run this program, you will see:

ENTER A NUMBER:
?

The editing cursor will be after the question mark. This means that the system is waiting for you to enter some data. We can enter a number, for example ‘3.5’:

ENTER A NUMBER:
? 3.5
YOUR NUMBER IS:
 3.5

When the user enters the number, ‘A’ will be equal to that number, so we can use it in another parts of the program. In this case, we use it in a PRINT statement to write back that number. ‘A’ is a numeric variable.

BASIC distinguish between variables whose value is a number (numeric variables) and variables whose value is text (string variables). For numeric variables you use the letters ‘A’ to ‘Z’, and also these letters followed by a number from 0 to 9. ‘A’, ‘B0’, ‘Z6’ are examples of numeric variables.

String variables consist of one letter from ‘A’ to ‘Z’ followed by the dollar sign ‘$’. ‘A$’, ‘B$’, ‘Z$’ are examples of string variables.

We can use INPUT and PRINT with these two types of variables.

10 PRINT "ENTER YOUR NAME:"
20 INPUT A$
30 PRINT "WELCOME"
40 PRINT A$
50 END

We can run this program and enter our name:

ENTER YOUR NAME:
? JAMES
WELCOME
JAMES

A string variable can hold at maximum 18 characters. If the user enters a longer string, bas55 will print an error message and the INPUT will be retried.

INPUT can be used to ask the user to enter a list of numbers or character strings, separated by commas. For example:

10 PRINT "ENTER YOUR NAME AND YOUR AGE, SEPARATED BY A COMMA:"
20 INPUT A$, A
30 PRINT "YOUR NAME IS"
40 PRINT A$
50 PRINT "YOUR AGE IS"
60 PRINT A
70 END

Here you will have to enter your name first, a comma, and your age.

ENTER YOUR NAME AND YOUR AGE, SEPARATED BY A COMMA:
? JAMES, 33
YOUR NAME IS
JAMES
YOUR AGE IS
 33

2.5 Using variables

One way to make a variable equal to a value is by using INPUT and let the user enter the value. Another way is using LET.

10 LET A$="PI"
20 LET A=3.1416
30 PRINT A$
40 PRINT A
50 END

With this program, ‘A’ will be equal to ‘3.1416’, and ‘A$’ will be equal to the string ‘PI’. You can change the value of a variable, simply by using LET with another value. Running this program:

10 LET A=3.1416
20 PRINT A
30 LET A=123456
40 PRINT A
50 END

You will get:

 3.1416
 123456

A variable can be made equal to the value of other variable.

10 LET A=1
20 LET B=A
30 PRINT B
40 END

This will print

 1

The same can be done for string variables.

We can use mathematical expressions in a LET or PRINT statement:

10 PRINT "WRITE A NUMBER:"
20 INPUT N
30 LET N=N*N
40 PRINT N+1
50 END

If we run this program and input the number ‘2’, the response will be ‘5’:

WRITE A NUMBER:
? 2
 5

In a numeric expression, we can use the operators ‘*’, ‘/’, ‘+’, ‘-’ and ‘^’ to multiply, divide, add, subtract or power. The power operator has the highest priority. Then multiplication and division. Then addition and subtraction. You can use parenthesis to change these priorities. Operations with the same priority are evaluated from left to right.

10 PRINT 5+3*2
20 PRINT (5+3)*2
30 END

This will print:

 11
 16

At line 10, as multiplication has higher priority, ‘3*2’ is calculated first, and the addition of ‘5’. At line 20, we are using parenthesis to select which operation is calculated first.

If a numeric variable is used before any value has been assigned to it in the program, the value of the variable defaults to ‘0’. For a string variable, it defaults to the empty string. You can enable the debug mode if you want the interpreter to warn you about any variable that is used before any value has been assigned to it.

A string variable can hold at maximum 18 characters. The BASIC program will stop with an exception if you try to store a longer string into a string variable with LET.


2.6 Numbers

Numbers are written in your program following scientific notation. The general syntax is:

sd..drd..dEsd..d

Here, ‘s’ is an optional sign symbol (‘+’ or ‘-’), ‘d’ is a number digit and ‘r’ is a full-stop. Some parts of this general syntax are optional. These are the possibilities, which can precede an optional ‘Esd..d’ part.

sd..d
sd..dr
sd..drd..d
srd..d

Example of numeric constants are:

1	500	-21.	.255	1E10	5E-1	4.E+1

bas55 uses the 17 first significant digits when reading a number. A number is rounded if it is written with more than 17 significant digits. bas55 works internally with IEEE double-precision floating-point numbers. Numbers printed with the PRINT statement show up to 8 significant digits.


2.7 Arrays

You can use tables of one dimension or two dimensions. We call them arrays. To store a value in an array slot we use the name of the array (which must be one letter) and using parenthesis to specify the required slot index.

With this program we store ‘1’ and ‘2’ in the slots 0 and 1 of the one dimensional array ‘A’.

10 LET A(0)=1
20 LET A(1)=2
30 PRINT A(0)
40 PRINT A(1)
50 END

This will print ‘1’ and ‘2’. Once you use a variable name as an array, it cannot be used as a simple numeric variable. And once a variable has been used as a numeric variable, it cannot be used as an array. This program commits both mistakes and will not run.

10 LET A=1
20 LET A(0)=1
30 LET B(0)=1
40 LET B=1
50 END

The value of each array slot is ‘0’ if no other value has been assigned to it before.

10 PRINT A(0)
20 END

will print:

 0

Note that this behavior is not required by the standard, and other implementations may not initialize all variables to zero. You can enable the debug mode if you want the interpreter to warn you about variables that are used before any value has been assigned to them.

Arrays always have a size of 11 elements by default, from 0 to 10. If you want to change this, you can use DIM to define the highest index the array can accept. This has to be done before any access to the array in your program.

This program

10 DIM A(100)
20 LET A(100)=5
30 PRINT A(100)
40 END

will define the array ‘A’ to have 101 elements, from 0 to 100, and will print the number ‘5’.

When you write an array index, any numeric expression whose value is within the range of the array indexes is allowed. For example:

10 LET A=5
20 LET B(A+A)=33
20 PRINT B(A+A)
30 END

This will print ‘33’, which is stored at index 10 in ‘B’.

You can use arrays of two dimensions as well:

10 DIM B(15,15)
20 LET B(15,15)=5
30 PRINT B(15,15)
40 END

Once an array has been used with one dimension, it cannot be used with two dimensions. And an array used with two dimensions, cannot be used with one.

The index of the first element of an array is always zero. BASIC allows to change this and use arrays where the index of the first element starts at 1. To allow this, we have to use the OPTION BASE 1 statement in our program, before using any array or any DIM statement. In that case, by default, the arrays will have 10 elements, indexed from 1 to 10.

10 OPTION BASE 1
20 REM USING LET A(0)=3 NOW IS AN ERROR, THE FIRST ELEMENT IS AT INDEX 1
30 LET A(1)=3
40 END

2.8 Printing

You can print more than one item using the PRINT statement by separating the items by commas or semicolons. Using commas will move the cursor to the next printing column. Each line has a printing column every 16 characters (that is, the second column starts at position 17).

10 PRINT "COLUMN 1", "COLUMN 2"
20 PRINT 5, 6
30 END

will print:

COLUMN 1      COLUMN 2
 5             6

A semicolon will leave the cursor at the same position it is, that is, it is only used to separate items in a PRINT statement.

10 PRINT "PI=";3.1416
20 END

will print:

PI= 3.1416

You can use TAB to move the cursor to a specific character column in the line. TAB needs a numeric expression between parenthesis.

10 PRINT ,"A"
10 PRINT TAB(17);"A"
20 END

will print at character column 17:

              A
              A

Note that expressions or TAB specifiers must be separated by commas or semicolons, but commas or semicolons can appear one after the other several times. Also, the PRINT statement alone is correct and will pass to the next line.

10 PRINT "LINE 1"
20 PRINT
30 PRINT "LINE 3"
40 PRINT ,,"COLUMN 30"
60 END

This program prints:

LINE 1

LINE 3
                             COLUMN 30

2.9 Built in functions

BASIC allows some mathematical functions to be used in numeric expressions. For example, to calculate the square root of 4:

10 PRINT SQR(4)
20 END

Functions need an argument between parenthesis, which must be a numeric expression. The provided functions are:

ABS(X)

Absolute value of X.

ATN(X)

Arctangent of X in radians.

COS(X)

Cosine of X, where X is in radians.

EXP(X)

Exponential of X.

INT(X)

The largest integer not greater than X.

LOG(X)

The natural logarithm of X.

SGN(X)

1 if X is positive, -1 if it is negative, 0 if it is 0.

SIN(X)

Sine of X, X in radians.

SQR(X)

Square root of X.

TAN(X)

Tangent of X, X in radians.


2.10 Random numbers

You can use the function RND without any argument, to get a random number in the range [0, 1[. RND can be used in any numeric expression. The sequence of numbers you will get by calling RND will be always the same. If you want the sequence to start randomly, you can use the statement RANDOMIZE.

10 PRINT RND, RND
20 RANDOMIZE
30 PRINT RND, RND
40 END

When we run this program, we will get 4 numbers. If we run the program again, the we will see that the first two numbers are the same as in the previous execution, but not the last two.


2.11 Conditional execution

Imagine we want to present a menu to the user, wait for input, and execute a different code depending on his response. We can use the IF statement to check for conditions and jump to a line of our program if the condition is true.

10 PRINT "1 - SAY HELLO"
20 PRINT "2 - SAY GOODBYE"
40 PRINT "3 - END"
50 PRINT "SELECT AND OPTION (1,2,3):"
60 INPUT N
70 IF N=1 THEN 130
80 IF N=2 THEN 150
90 IF N<>3 THEN 100
100 STOP
110 PRINT "ERROR"
120 GOTO 10
130 PRINT "HELLO"
140 GOTO 10
150 PRINT "GOODBYE"
160 GO TO 10
170 END

You can see the IF statement at lines 70, 80 and 90. Its basic form is IF condition THEN line. It tests the condition, and if it is true, then the program continues its execution at the line after the THEN word. If the condition is false, execution continues at the next line as usual.

In this program, if the user enters a ‘1’, line 70 will jump to the line 130 and ‘HELLO’ will be printed. If the user enters ‘2’, the condition at line 70 will be false, so we will continue at line 80. Here, the condition will be true, so we will jump to the line 150 and ‘GOODBYE’ will be printed. If the user enters a number different than 1, 2 or 3, we will jump to line 110 and print ‘ERROR’. Otherwise the execution continues at line 100.

The STOP statement is used to stop a program before we reach the END statement. A program can only have one END statement and must be at the last line, but can contain any number of STOP statements.

The GOTO statement followed by a line number, can be used to jump to a line without checking for any condition. Note that GOTO can be written using two words as well: GO TO.

The conditions that we can test in an IF statement are:

A=B

True if the numeric expression A is equal to the numeric expression B. True if the string constant or string variable A is equal to the string constant or string variable B.

A<>B

True if the numeric expression A is not equal to the numeric expression B. True if the string constant or string variable A is not equal to the string constant or string variable B.

A>B

True if the numeric expression A is greater than the numeric expression B.

A>=B

True if the numeric expression A is greater or equal than the numeric expression B.

A<B

True if the numeric expression A is less than the numeric expression B.

A<=B

True if the numeric expression A is less or equal than the numeric expression B.

With the ON statement we can jump to a line in a line list depending on the value of a numeric expression. The above program can be written this way:

10 PRINT "1 - SAY HELLO"
20 PRINT "2 - SAY GOODBYE"
40 PRINT "3 - END"
50 PRINT "SELECT AND OPTION (1,2,3):"
60 INPUT N
70 IF N<1 THEN 100
80 IF N>3 THEN 100
90 ON N GOTO 120, 140, 170
100 PRINT "ERROR"
110 GOTO 10
120 PRINT "HELLO"
130 GOTO 10
140 PRINT "GOODBYE"
150 GO TO 10
160 END

A numeric expression must follow the ON word. The expression is rounded to an integer and this number is used to select one of the lines in the line list after the GOTO. The number ‘1’ will select the first line in the list, ‘2’ the second, etc. The program will stop with an error if the rounded integer is less than 1 or greater than the number of lines in the line list. We check that at lines 70 and 80.


2.12 Subroutines

Imagine that we want to calculate the roots of a second degree equation. We know the formula, for ‘ax^2 + bx + c’, the roots are given by the equations ‘(-b + SQR(b^2 - 4ac)) / 2a’ and ‘(-b - SQR(b^2 - 4ac)) / 2a’.

We can write this program if we want to calculate it for two different equations:

10 LET A=4
20 LET B=7
30 LET C=1
40 LET R0=(-B + SQR(B^2 - 4*A*C))/2*A
50 LET R1=(-B - SQR(B^2 - 4*A*C))/2*A
60 PRINT R0, R1
70 LET A=16
80 LET B=25
90 LET C=2
100 LET R0=(-B + SQR(B^2 - 4*A*C))/2*A
110 LET R1=(-B - SQR(B^2 - 4*A*C))/2*A
120 PRINT R0, R1
130 END

But in this example we are duplicating code. What we want is to have the code to calculate the roots only once. To achieve that, we can use a subroutine. GOSUB stands for ‘go to subroutine’. We use it with a line number and the program will go to that line number and will continue the execution at that line. We can then use the statement RETURN to return to the line after the line with the GOSUB.

For example, applied to the above program:

10 LET A=4
20 LET B=7
30 LET C=1
40 GOSUB 120
50 PRINT R0, R1
60 LET A=16
70 LET B=25
80 LET C=2
90 GO SUB 120
100 PRINT R0, R1
110 STOP
120 REM CALC ROOTS OF SECOND DEGREE EQUATION AX^2 + BX + C
130 ON ENTRY: A, B, C ARE THE COEFICIENTS
140 ON EXIT: R0, R1 ARE THE ROOTS
150 LET R0=(-B + SQR(B^2 - 4*A*C))/2*A
160 LET R1=(-B - SQR(B^2 - 4*A*C))/2*A
170 RETURN
180 END

Our subroutine starts at line 120. It needs the variables ‘A’, ‘B’ and ‘C’ to be defined, and will calculate the roots in ‘R0’ and ‘R1’. You can call this subroutine by using GOSUB 120. The program will jump to that line and execute the next lines until a RETURN is found. When we reach the RETURN we will return to the point of the call. In this program, when we call the subroutine at line 40 and the subroutine ends with a RETURN, the execution will continue at line 50.

Note that we need a STOP statement at line 110 to stop our program. If not it will continue at line 120, thus entering the subroutine and reaching the RETURN statement. This will be an error as we reach a RETURN without having issued any GOSUB.

Note that GOSUB can be written with two words as well: GO SUB.


2.13 User functions

BASIC allows to define your own functions by using ‘DEF FNX’, where ‘X’ is a letter. You can define functions with zero or one argument.

10 DEF FNA=2*X
20 LET X=3
30 PRINT FNA
40 END

This program will print ‘6’.

Every function have to be declared before being used. And a function declared with an argument cannot be redeclared without arguments, or vice versa.

If we define a function with an argument, the argument must be a letter. Once inside the function, when this argument is used, it takes the value we passed to the function, not the value of the variable of the same name in the program. For example:

10 DEF FNA(X)=X+Y
20 LET X=3
30 LET Y=4
30 PRINT FNA(5)
40 END

This program will print ‘9’. When the function ‘FNA’ is called, ‘X’ inside the function expression will take the value we have passed (‘5’ in this case and not the value ‘3’ of the variable in the program) and will take the value of ‘Y’ in the program (‘4’). That is, ‘FNA(5)=5+4=9’. The value of ‘X’ in the program will not change, it will be ‘3’.


2.14 Loops

Imagine that you want to print the values from 1 to 10. You can write something like this:

10 LET I=1
20 PRINT I
30 LET I=I+1
40 IF I<11 THEN 20
50 END

You can achieve a similar effect using the FOR loop. With the FOR loop, you can forget about changing the value of the loop control variable (the variable ‘I’ in this case) and jumping back to the correct line (as we do at line 40).

10 FOR I=1 TO 10
20   PRINT I
30 NEXT I
40 END

You can see here the general syntax. The variable ‘I’ will have the value of ‘1’ at the beginning. Then the next lines are executed until we reach a NEXT statement followed by the variable we use in the FOR. When we reach the NEXT we increment the loop variable ‘I’ by one. Then we check if ‘I’ is greater equal to the limit specified in the FOR statement after the word TO. If it is greater, the loop ends and the execution continues at the next line (at line 40 in this case). If not, we jump back to the line after the FOR. This means that after exiting the loop, the variable has the next value not used, in this case, ‘11’.

It is possible to specify an increment value different than 1. This program prints 2, 4, 6, 8 and 10.

10 FOR I=2 TO 10 STEP 2
20   PRINT I
30 NEXT I
40 END

The step value can be negative and the start value greater than the limit. This program prints 10, 8, 6, 4, 2.

10 FOR I=10 TO 2 STEP -2
20   PRINT I
30 NEXT I
40 END

We can have a FOR loop inside another FOR loop:

10 FOR I=1 TO 5
20   FOR J=1 TO 5
30     PRINT I, J
40   NEXT J
50 NEXT I
60 END

We cannot have a nested FOR loop inside another with the same control variable. This program is incorrect:

10 FOR I=1 TO 5
20   FOR I=2 TO 3
30     PRINT I
40   NEXT I
50 NEXT I
60 END

Also, you cannot jump into a line inside a FOR block from outside that block. This program is incorrect:

10 FOR I=1 TO 5
20   PRINT I
30 NEXT I
40 GOTO 20
50 END

Line 40 is jumping inside the FOR block and this is not allowed. The same happens if we use a GOSUB or an IF statement jumping inside that block.

Note that if inside a FOR block there is no other FOR block, the control variable of that FOR block must match the NEXT control variable ending that block. For example, this program is incorrect:

10 FOR I=1 TO 10
20   FOR J=1 TO 10
30     PRINT I
40   NEXT I
50 NEXT J
60 END

2.15 Constant data

You can declare constants in your program by using the DATA statement followed by a list of numbers, quoted strings or unquoted strings separated by commas. You can then store this data in variables with the READ statement, which has the same syntax as the INPUT statement.

10 DATA 1, "HELLO"
20 FOR I=1 TO 4
30   READ A, B$
40   PRINT A, B$
50 NEXT I
60 DATA 2, BYE
70 END

This program prints:

 1            HELLO
 2            BYE

Note that in a DATA statement, you can use character strings without starting and ending them with quotes, but in that case, you can only use letters, numbers, spaces, the plus and minus signs (‘+’, ‘-’) or a full stop (‘.’).

The READ statement reads elements starting from the first DATA statement in your program. If you want to read again from the first element, you must use the RESTORE statement. This program prints ‘1’ and ‘2’, and then ‘1’ and ‘2’ again.

10 DATA 1, 2, 3, 4
20 READ A, B
30 PRINT A, B
40 RESTORE
50 READ A, B
60 PRINT A, B
70 END

The maximum number of characters that can be READ into a string variable is 18. If you READ a longer string, the program will stop with an exception.


2.16 Sieve of Eratosthenes

A gift from Eratosthenes of Cyrene, 276 BC - 194 BC...

10  REM SIEVE OF ERATOSTHENES, BY ERATHOSTENES OF CYRENE 276BC-194BC
20  DIM A(1000)
30  FOR I=1 TO 1000
40    LET A(I)=0
50  NEXT I
60  PRINT "FIND PRIMES FROM 2 TO N (N <= 1000). ENTER N: "
70  INPUT N
80  IF N<2 THEN 60
90  IF N>1000 THEN 60
100 LET S=SQR(N)
110 FOR I=2 TO S
120   IF A(I)=1 THEN 170
130   LET D=N/I
140   FOR J=I TO D
150     LET A(I*J)=1
160   NEXT J
170 NEXT I
180 FOR I=2 TO N
190   IF A(I)=1 THEN 210
200   PRINT I
210 NEXT I
220 END

3 Reference


3.1 Editor

When bas55 is invoked without arguments, it starts in editor mode. You can then write a BASIC program by entering lines beginning with a number. The number will be used to order the lines in the program. To delete a line, simply write the line number you want to delete and press the ENTER key. To replace a line, rewrite the line with using the same line number as the line you want to substitute.

If you write a line that does not begin with a line number, it will be taken as an editor command. Available commands are:

HELP

Display the list of commands available.

COMPILE or C

Compile the current program to bytecode (in memory).

RUN

Compile (if needed) and run the current program.

LIST

List the current program lines. You can optionally pass a range of lines. ‘LIST n’ will only print line number ‘n’. ‘LIST a-n’ will print lines from line number ‘a’ to ‘b’. ‘LIST a-’ will print lines from line number ‘a’ to the last. ‘LIST -b’ will print lines from the first to the line number ‘b’.

NEW

Start editing a new program.

LOAD "program.bas"

Load the BASIC program in the file program.bas.

SAVE "program.bas"

Save the current program lines to the file program.bas.

RENUM

Renumber the lines of the current program.

SETGOSUB n

Allocate enough space so that, at maximum, ‘nGOSUB statements can be executed without any RETURN statement.

DEBUG ON/OFF

DEBUG ON will enable the debug mode; DEBUG OFF will disable it. It is enabled by default in edit mode, and disabled in batch mode. It will warn if a variable is used before a value is assigned to it.

LICENSE

Display the license text.

QUIT

Quit to the OS.


3.1.1 Microsoft Windows

When running bas55 on Microsoft Windows in editor mode, you can use the up and down arrows on your keyboard to show the lines that you typed before. For example, if you type:

10 PRINT "HELLO"
20 END

And the you press the up arrow, you will get:

20 END

If you press it again, you will get:

10 PRINT "HELLO"

If you press now the down arrow key you will get again:

20 END

When you get one of these lines that you typed previously, you can use the left and right arrows to move through the line and make any modifications that you wish. If you then press the ENTER key, the line will be saved with the modifications.


3.1.2 Unix-like systems

On GNU/Linux, BSD systems, etc, if bas55 has been compiled with ‘GNU readline’ support (recommended) or ‘NetBSD libedit’ support, when executing the program in editor mode you will see something like:

bas55 2.0 (with GNU readline support)

Or:

bas55 2.0 (with NetBSD libedit support)

In this case, you have the same editing enhancements as on Microsoft Windows, and some more.

When bas55 is compiled with support of one of these libraries, you can access any line of your BASIC program by writing its number and then pressing the TAB key. Then you will get the line and you will be able to edit it.

For example, if your program was:

10 PRINT "HELLO"
20 END

You can type 10 and then press the TAB key, and you will get

10 PRINT "HELLO"

and you can move through this line and edit it.

Another enhancement is that some commands can be autocompleted by pressing the TAB key. For example, if you type ‘10 PR’ and then you press TAB, ‘PR’ will be expanded to ‘PRINT’.

Finally, the names of the files provided to the LOAD and SAVE commands, will be autocompleted by using the TAB key with the files on your actual filesystem. For example, if in your current directory there is a file called program.bas and you type ‘LOAD "pro’ and then you press TAB, you will get ‘LOAD "program.bas’.


3.2 Invoking bas55

To compile and run program.bas:

bas55 program.bas

To start bas55 in editor mode:

bas55

Additional command line options are:

-h, --help

Display usage information and exit.

-v, --version

Display version information and exit.

-g n, --gosub n

Allocate enough space so that, at maximum, ‘nGOSUB statements can be executed without any RETURN statement. The default is 256.

-d, --debug

Enable debug mode. It will warn if a variable is used before a value is assigned to it.


3.3 Implementation-defined features

The ECMA-55 Standard leaves some features to be defined by the implementor, given that the limits recommended by the standard are respected. In bas55 they are:

  • - Accuracy of evaluation of numeric expressions: we use IEEE 754 double-precision binary floating-point format. For the mathematical functions sin, cos, etc. bas55 uses its own implementation, trying to get the same result on every platform.
  • - End-of-line: we accept Windows and Unix end-of-lines.
  • - Exrad-width for printing numeric representations: 3 digits.
  • - Initial value of variables: 0 for numeric variables and array slots; the empty string for string variables.
  • - Input-prompt: question mark followed by a single space.
  • - Longest string that can be retained: this is limited by the longest program line allowed, which is 72 as required by the standard. Thus 65 characters can be retained.
  • - Value of machine infinitesimal: the minimum normal value is 2.2250738585072014 * 10^(-308) approximately, although smaller values can be represented by losing precision. The minimum subnormal value is 4.9406564584124654 * 10^(-324) approximately.
  • - Value of machine infinity: it is defined by the IEEE 754 standard as a special binary value. You can obtain infinity by dividing one by zero, and a negative infinity by dividing minus one by zero. The maximum normal value is 1.7976931348623157 * 10^(308) approximately.
  • - Margin for output lines: 80 characters.
  • - Precision of numeric values: 17 significant decimal digits and 3 digits for the exrad.
  • - Print-zone length: 16 characters.
  • - Pseudo-random number sequence: bas55 uses its own random number generator which should give the same result on every platform.
  • - Significance width for printing numeric representations: a maximum of 15 characters are used: 8 decimal digits plus 3 digits for the exrad plus 5 characters to accommodate signs, final space, etc.
  • - Is unary minus accepted after an operator? Yes, we accept this 1 + -3; and this 1 + –3. Warning: this is not required or accepted by the standard.
  • - Contrary to the standard, in bas55 zero divided by zero gives an undefined value (not-a-number or NAN), and not positive infinity.

4 Source guide


4.1 Modules

  • Layer 0: Base modules
    • - getlin.c: get a line from a file or console. Line editing support.
    • - list.h: single linked list macros.
    • - ngetopt.c: command line argument parsing.
    • - util.c: generic functions.
    • - err.c: error reporting functions and error text.
    • - datalex.c: parsing of quoted or unquoted strings, numbers or comma separated lists of these elements.
    • - codedvar.c: utilities for encoding a variable name as an integer.
    • - bmath.c: implementation of mathematical functions.
  • Layer 1: BASIC source store and byte compiled code
    • - str.c: string constants and garbage collected dynamic strings appearing in the BASIC program.
    • - ifun.c: internal BASIC functions (SIN, COS, etc.).
    • - data.c: compiled DATA statements.
    • - code.c: compiled bytecode representing the BASIC program.
    • - araydsc.c: stores for each array its dimensions and position in the virtual machine’s RAM.
    • - dbg.c: debug support for testing variables not initialized when running the BASIC program.
    • - line.c: BASIC source stored as lines.
  • Layer 2: The virtual machine
    • - vm.c: virtual machine that can execute the byte compiled BASIC program stored in modules code.c, str.c, data.c and arraydsc.c.
  • Layer 3: Compiler
    • - grammar.y: Yacc BASIC grammar.
    • - parse.c: bytecode compiler, compiles the lines in module lines.c and generates the compiled program in modules code.c, str.c and data.c.
    • - lex.c: lexical analysis.
  • Layer 4: Program
    • - edit.c: editor mode.
    • - cmd.c: editor mode command handling.
    • - ecma55.c: main program, starts editor or compiles and executes program.

4.2 Operation

A BASIC source code is stored as separated lines in line.c. The compiler translates those lines into opcodes (in code.c), string constants as they appear in the code (in str.c), DATA statements (in data.c), array descriptors (with info about arrays like their dimensions, in arraydsc.c) and some debug info (in dbg.c). If there are not compilation errors, then the program can be run by vm.c, which takes the generated program and starts interpreting the opcodes. During the program execution, probably new strings will be generated in str.c and others will be discarded (but not the ones defined in the program).

In both compilation and execution phases, memory is allocated at start and deallocated when the operation ends.

After compiling without errors, we know the amount of RAM for the virtual machine that the BASIC program will need for executing. This RAM is an an array of numbers, or indexes that point to strings in str.c. Every variable and array declared in the program will have one or more positions used in this array.

Moreover, the compiler can calculate the amount of stack required by all the program, as we can know the stack needed by each statement, and BASIC does not allow a user defined function to call itself or call another function defined after it. But it can’t calculate the amount of stack needed for GOSUB calls. If your program does more than 256 consecutive GOSUB calls without using any RETURN statement, you will need to raise the number of allowed calls by a command line option or by using SETGOSUB in editor mode.

If we run out of memory while compiling or running the program, the operation will stop.


4.3 Translation

The program is compiled for a typical stack machine. The compilation generates a series of slots, each slot being an instruction opcode, an integer or a floating number. A typical expression like ‘3*2+5’ is translated to:

    0: PUSH_NUM_OP
    1: 3.0
    2: PUSH_NUM_OP
    3: 2.0
    4: MUL_OP
    5: PUSH_NUM_OP
    6: 5.0
    7: ADD_OP

When executing this code, the values are put on the stack until they are used by the operators. For example, PUSH_OP puts the next number on the top of the stack. MUL_OP takes the two numbers on the top of the stack and multiplies them, pops them from the stack, and puts the result back to the top of the stack. For instance, when we execute the opcode at 0, we get this stack:

	0: 3.0

After executing the opcode at 2:

	1: 2.0
	0: 3.0

After executing the opcode MUL_OP at 4 we get this stack:

	0: 6.0

In the following sections we describe how other more complex BASIC statements are translated.


4.3.1 LET

10 LET A=B(1)+C(2,3)

is translated to:

	0:  PUSH_NUM_OP
	1:  1.0
	2:  GET_LIST_OP
	3:  B
	4:  PUSH_NUM_OP
	5:  2.0
	6:  PUSH_NUM_OP
	7:  3.0
	8:  GET_TABLE_OP
	10: C
	11: LET_VAR_OP
	12: address of A in RAM 

For each variable A to Z that is an array, we maintain a descriptor that knows the position of the first element of the array in the virtual machine’s RAM. The descriptor also stores the dimensions of the array, so we can check for out of range accesses. When we find a GET_LIST_OP B we go to the descriptor of B to get this information.

On the other hand, code like LET_VAR_OP expects only the raw position in vm’s RAM that was allocated for the variable.

And

10 LET A(1,2)=3

is translated to:

	0:  PUSH_NUM_OP
	1:  1.0
	2:  PUSH_NUM_OP
	3:  2.0
	4:  PUSH_NUM_OP
	5:  3.0
	6:  LET_TABLE_OP
	7:  A

4.3.2 ON GOTO

10 ON A GOTO 100, 200

is translated to:

	0: GET_VAR_OP
	1: address of A
	2: ON_GOTO_OP
	3: 2
	4: 100
	5: 200

The number 2 at slot 3 is the number of elements in the GOTO list; in this case 2: 100 and 200.


4.3.3 IF

10 IF A>3 THEN 100

is translated to:

	0: GET_VAR_OP
	1: address of A
	2: PUSH_NUM_OP
	3: 3.0
	4: GREATER_OP
	5: GOTO_IF_TRUE
	6: 100

4.3.4 FOR

10 FOR I=1 TO 10 STEP 2
15 LET A=I*2
20 NEXT I

is translated to:

	0:  PUSH_NUM_OP
	1:  1.0
	2:  PUSH_NUM_OP
	3:  10.0
	4:  PUSH_NUM_OP
	5:  2.0
	6:  FOR_OP
	7:  address of temporary var (call it ‘vstep’)
	8:  address of temporary var (call it ‘vlimit’)
	9:  address of I
	10: FOR_CMP_OP
	11: 21 (index past NEXT)
	12: GET_VAR_OP
	13: address of I
	14: PUSH_NUM_OP
	15: 2.0
	16: MUL_OP
	17: LET_VAR_OP
	18: address of A
	19: NEXT_OP
	20: 10 (index to FOR_CMP_OP)
	21: 

When executed, FOR_OP takes the 3 values on top of the stack and sets ‘vstep’, ‘vlimit’ and the loop control variable (‘I’ in this case). FOR_CMP_OP checks for loop termination. NEXT_OP increments the loop variable by the loop step and returns to the FOR_CMP_OP.


4.3.5 DEF

10 DEF FNA(X)=X*X
20 LET X=FNA(2)

is translated to:

	0:  GOTO_OP
	1:  8 (index past RETURN_OP)
	2:  GET_VAR_OP
	3:  address of FNA's X
	4:  GET_VAR_OP
	5:  address of FNA's X
	6:  MUL_OP
	7:  RETURN_OP
	8:  PUSH_NUM_OP
	9:  2.0
	10: LET_VAR_OP
	11: address of FNA's X
	12: GOSUB_OP
	13: 2 (index of FNA start code)
	14: LET_VAR_OP
	15: address of X

4.3.6 INPUT

10 INPUT A, B(1), S$

is translated to:

	0:  INPUT_OP
	1:  INPUT_NUM_OP
	2:  5 (index to the end of INPUT A) 
	3:  LET_VAR_OP
	4:  address of A
	5:  INPUT_NUM_OP
	6:  11 (index to the end of INPUT B(1))
	7:  PUSH_NUM_OP
	8:  1.0
	9:  INPUT_LIST_OP
	10: B
	11: INPUT_STR_OP
	12: 15 (index to the end of INPUT S$)
	13: LET_STRVAR_OP
	14: address of S$
	15: INPUT_END_OP

4.3.7 PRINT

10 PRINT "RESULT="; 2+3

is translated to:

	0:  PUSH_STR_OP
	1:  address of "RESULT="
	2:  PRINT_STR_OP
	3:  PUSH_NUM_OP
	4:  2.0
	5:  PUSH_NUM_OP
	6:  3.0
	7:  ADD_OP
	8:  PRINT_NUM_OP

4.3.8 DEBUG

bas55 always guarantees that every variable and every array is filled with zeroes when the BASIC program is run, but this is not required by the standard. If you want to make your program fully portable you have to assume that possibly variables are not initialized to zero in other implementations.

To assist you, when in debug mode, bas55 checks if any variable or array element has been assigned a value before being involved in any expression. We issue a warning if the test fails.

Of course, this slows down the execution of the BASIC program. By default, bas55 runs in debug mode only when started in editor mode. You can set the debug mode on or off in the editor with the command DEBUG ON or DEBUG OFF, or you can start bas55 with the option -d (or --debug).


5 GNU Free Documentation License

Version 1.3, 3 November 2008
Copyright © 2000, 2001, 2002, 2007, 2008 Free Software Foundation, Inc.
https://fsf.org/

Everyone is permitted to copy and distribute verbatim copies
of this license document, but changing it is not allowed.
  1. PREAMBLE

    The purpose of this License is to make a manual, textbook, or other functional and useful document free in the sense of freedom: to assure everyone the effective freedom to copy and redistribute it, with or without modifying it, either commercially or noncommercially. Secondarily, this License preserves for the author and publisher a way to get credit for their work, while not being considered responsible for modifications made by others.

    This License is a kind of “copyleft”, which means that derivative works of the document must themselves be free in the same sense. It complements the GNU General Public License, which is a copyleft license designed for free software.

    We have designed this License in order to use it for manuals for free software, because free software needs free documentation: a free program should come with manuals providing the same freedoms that the software does. But this License is not limited to software manuals; it can be used for any textual work, regardless of subject matter or whether it is published as a printed book. We recommend this License principally for works whose purpose is instruction or reference.

  2. APPLICABILITY AND DEFINITIONS

    This License applies to any manual or other work, in any medium, that contains a notice placed by the copyright holder saying it can be distributed under the terms of this License. Such a notice grants a world-wide, royalty-free license, unlimited in duration, to use that work under the conditions stated herein. The “Document”, below, refers to any such manual or work. Any member of the public is a licensee, and is addressed as “you”. You accept the license if you copy, modify or distribute the work in a way requiring permission under copyright law.

    A “Modified Version” of the Document means any work containing the Document or a portion of it, either copied verbatim, or with modifications and/or translated into another language.

    A “Secondary Section” is a named appendix or a front-matter section of the Document that deals exclusively with the relationship of the publishers or authors of the Document to the Document’s overall subject (or to related matters) and contains nothing that could fall directly within that overall subject. (Thus, if the Document is in part a textbook of mathematics, a Secondary Section may not explain any mathematics.) The relationship could be a matter of historical connection with the subject or with related matters, or of legal, commercial, philosophical, ethical or political position regarding them.

    The “Invariant Sections” are certain Secondary Sections whose titles are designated, as being those of Invariant Sections, in the notice that says that the Document is released under this License. If a section does not fit the above definition of Secondary then it is not allowed to be designated as Invariant. The Document may contain zero Invariant Sections. If the Document does not identify any Invariant Sections then there are none.

    The “Cover Texts” are certain short passages of text that are listed, as Front-Cover Texts or Back-Cover Texts, in the notice that says that the Document is released under this License. A Front-Cover Text may be at most 5 words, and a Back-Cover Text may be at most 25 words.

    A “Transparent” copy of the Document means a machine-readable copy, represented in a format whose specification is available to the general public, that is suitable for revising the document straightforwardly with generic text editors or (for images composed of pixels) generic paint programs or (for drawings) some widely available drawing editor, and that is suitable for input to text formatters or for automatic translation to a variety of formats suitable for input to text formatters. A copy made in an otherwise Transparent file format whose markup, or absence of markup, has been arranged to thwart or discourage subsequent modification by readers is not Transparent. An image format is not Transparent if used for any substantial amount of text. A copy that is not “Transparent” is called “Opaque”.

    Examples of suitable formats for Transparent copies include plain ASCII without markup, Texinfo input format, LaTeX input format, SGML or XML using a publicly available DTD, and standard-conforming simple HTML, PostScript or PDF designed for human modification. Examples of transparent image formats include PNG, XCF and JPG. Opaque formats include proprietary formats that can be read and edited only by proprietary word processors, SGML or XML for which the DTD and/or processing tools are not generally available, and the machine-generated HTML, PostScript or PDF produced by some word processors for output purposes only.

    The “Title Page” means, for a printed book, the title page itself, plus such following pages as are needed to hold, legibly, the material this License requires to appear in the title page. For works in formats which do not have any title page as such, “Title Page” means the text near the most prominent appearance of the work’s title, preceding the beginning of the body of the text.

    The “publisher” means any person or entity that distributes copies of the Document to the public.

    A section “Entitled XYZ” means a named subunit of the Document whose title either is precisely XYZ or contains XYZ in parentheses following text that translates XYZ in another language. (Here XYZ stands for a specific section name mentioned below, such as “Acknowledgements”, “Dedications”, “Endorsements”, or “History”.) To “Preserve the Title” of such a section when you modify the Document means that it remains a section “Entitled XYZ” according to this definition.

    The Document may include Warranty Disclaimers next to the notice which states that this License applies to the Document. These Warranty Disclaimers are considered to be included by reference in this License, but only as regards disclaiming warranties: any other implication that these Warranty Disclaimers may have is void and has no effect on the meaning of this License.

  3. VERBATIM COPYING

    You may copy and distribute the Document in any medium, either commercially or noncommercially, provided that this License, the copyright notices, and the license notice saying this License applies to the Document are reproduced in all copies, and that you add no other conditions whatsoever to those of this License. You may not use technical measures to obstruct or control the reading or further copying of the copies you make or distribute. However, you may accept compensation in exchange for copies. If you distribute a large enough number of copies you must also follow the conditions in section 3.

    You may also lend copies, under the same conditions stated above, and you may publicly display copies.

  4. COPYING IN QUANTITY

    If you publish printed copies (or copies in media that commonly have printed covers) of the Document, numbering more than 100, and the Document’s license notice requires Cover Texts, you must enclose the copies in covers that carry, clearly and legibly, all these Cover Texts: Front-Cover Texts on the front cover, and Back-Cover Texts on the back cover. Both covers must also clearly and legibly identify you as the publisher of these copies. The front cover must present the full title with all words of the title equally prominent and visible. You may add other material on the covers in addition. Copying with changes limited to the covers, as long as they preserve the title of the Document and satisfy these conditions, can be treated as verbatim copying in other respects.

    If the required texts for either cover are too voluminous to fit legibly, you should put the first ones listed (as many as fit reasonably) on the actual cover, and continue the rest onto adjacent pages.

    If you publish or distribute Opaque copies of the Document numbering more than 100, you must either include a machine-readable Transparent copy along with each Opaque copy, or state in or with each Opaque copy a computer-network location from which the general network-using public has access to download using public-standard network protocols a complete Transparent copy of the Document, free of added material. If you use the latter option, you must take reasonably prudent steps, when you begin distribution of Opaque copies in quantity, to ensure that this Transparent copy will remain thus accessible at the stated location until at least one year after the last time you distribute an Opaque copy (directly or through your agents or retailers) of that edition to the public.

    It is requested, but not required, that you contact the authors of the Document well before redistributing any large number of copies, to give them a chance to provide you with an updated version of the Document.

  5. MODIFICATIONS

    You may copy and distribute a Modified Version of the Document under the conditions of sections 2 and 3 above, provided that you release the Modified Version under precisely this License, with the Modified Version filling the role of the Document, thus licensing distribution and modification of the Modified Version to whoever possesses a copy of it. In addition, you must do these things in the Modified Version:

    1. Use in the Title Page (and on the covers, if any) a title distinct from that of the Document, and from those of previous versions (which should, if there were any, be listed in the History section of the Document). You may use the same title as a previous version if the original publisher of that version gives permission.
    2. List on the Title Page, as authors, one or more persons or entities responsible for authorship of the modifications in the Modified Version, together with at least five of the principal authors of the Document (all of its principal authors, if it has fewer than five), unless they release you from this requirement.
    3. State on the Title page the name of the publisher of the Modified Version, as the publisher.
    4. Preserve all the copyright notices of the Document.
    5. Add an appropriate copyright notice for your modifications adjacent to the other copyright notices.
    6. Include, immediately after the copyright notices, a license notice giving the public permission to use the Modified Version under the terms of this License, in the form shown in the Addendum below.
    7. Preserve in that license notice the full lists of Invariant Sections and required Cover Texts given in the Document’s license notice.
    8. Include an unaltered copy of this License.
    9. Preserve the section Entitled “History”, Preserve its Title, and add to it an item stating at least the title, year, new authors, and publisher of the Modified Version as given on the Title Page. If there is no section Entitled “History” in the Document, create one stating the title, year, authors, and publisher of the Document as given on its Title Page, then add an item describing the Modified Version as stated in the previous sentence.
    10. Preserve the network location, if any, given in the Document for public access to a Transparent copy of the Document, and likewise the network locations given in the Document for previous versions it was based on. These may be placed in the “History” section. You may omit a network location for a work that was published at least four years before the Document itself, or if the original publisher of the version it refers to gives permission.
    11. For any section Entitled “Acknowledgements” or “Dedications”, Preserve the Title of the section, and preserve in the section all the substance and tone of each of the contributor acknowledgements and/or dedications given therein.
    12. Preserve all the Invariant Sections of the Document, unaltered in their text and in their titles. Section numbers or the equivalent are not considered part of the section titles.
    13. Delete any section Entitled “Endorsements”. Such a section may not be included in the Modified Version.
    14. Do not retitle any existing section to be Entitled “Endorsements” or to conflict in title with any Invariant Section.
    15. Preserve any Warranty Disclaimers.

    If the Modified Version includes new front-matter sections or appendices that qualify as Secondary Sections and contain no material copied from the Document, you may at your option designate some or all of these sections as invariant. To do this, add their titles to the list of Invariant Sections in the Modified Version’s license notice. These titles must be distinct from any other section titles.

    You may add a section Entitled “Endorsements”, provided it contains nothing but endorsements of your Modified Version by various parties—for example, statements of peer review or that the text has been approved by an organization as the authoritative definition of a standard.

    You may add a passage of up to five words as a Front-Cover Text, and a passage of up to 25 words as a Back-Cover Text, to the end of the list of Cover Texts in the Modified Version. Only one passage of Front-Cover Text and one of Back-Cover Text may be added by (or through arrangements made by) any one entity. If the Document already includes a cover text for the same cover, previously added by you or by arrangement made by the same entity you are acting on behalf of, you may not add another; but you may replace the old one, on explicit permission from the previous publisher that added the old one.

    The author(s) and publisher(s) of the Document do not by this License give permission to use their names for publicity for or to assert or imply endorsement of any Modified Version.

  6. COMBINING DOCUMENTS

    You may combine the Document with other documents released under this License, under the terms defined in section 4 above for modified versions, provided that you include in the combination all of the Invariant Sections of all of the original documents, unmodified, and list them all as Invariant Sections of your combined work in its license notice, and that you preserve all their Warranty Disclaimers.

    The combined work need only contain one copy of this License, and multiple identical Invariant Sections may be replaced with a single copy. If there are multiple Invariant Sections with the same name but different contents, make the title of each such section unique by adding at the end of it, in parentheses, the name of the original author or publisher of that section if known, or else a unique number. Make the same adjustment to the section titles in the list of Invariant Sections in the license notice of the combined work.

    In the combination, you must combine any sections Entitled “History” in the various original documents, forming one section Entitled “History”; likewise combine any sections Entitled “Acknowledgements”, and any sections Entitled “Dedications”. You must delete all sections Entitled “Endorsements.”

  7. COLLECTIONS OF DOCUMENTS

    You may make a collection consisting of the Document and other documents released under this License, and replace the individual copies of this License in the various documents with a single copy that is included in the collection, provided that you follow the rules of this License for verbatim copying of each of the documents in all other respects.

    You may extract a single document from such a collection, and distribute it individually under this License, provided you insert a copy of this License into the extracted document, and follow this License in all other respects regarding verbatim copying of that document.

  8. AGGREGATION WITH INDEPENDENT WORKS

    A compilation of the Document or its derivatives with other separate and independent documents or works, in or on a volume of a storage or distribution medium, is called an “aggregate” if the copyright resulting from the compilation is not used to limit the legal rights of the compilation’s users beyond what the individual works permit. When the Document is included in an aggregate, this License does not apply to the other works in the aggregate which are not themselves derivative works of the Document.

    If the Cover Text requirement of section 3 is applicable to these copies of the Document, then if the Document is less than one half of the entire aggregate, the Document’s Cover Texts may be placed on covers that bracket the Document within the aggregate, or the electronic equivalent of covers if the Document is in electronic form. Otherwise they must appear on printed covers that bracket the whole aggregate.

  9. TRANSLATION

    Translation is considered a kind of modification, so you may distribute translations of the Document under the terms of section 4. Replacing Invariant Sections with translations requires special permission from their copyright holders, but you may include translations of some or all Invariant Sections in addition to the original versions of these Invariant Sections. You may include a translation of this License, and all the license notices in the Document, and any Warranty Disclaimers, provided that you also include the original English version of this License and the original versions of those notices and disclaimers. In case of a disagreement between the translation and the original version of this License or a notice or disclaimer, the original version will prevail.

    If a section in the Document is Entitled “Acknowledgements”, “Dedications”, or “History”, the requirement (section 4) to Preserve its Title (section 1) will typically require changing the actual title.

  10. TERMINATION

    You may not copy, modify, sublicense, or distribute the Document except as expressly provided under this License. Any attempt otherwise to copy, modify, sublicense, or distribute it is void, and will automatically terminate your rights under this License.

    However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation.

    Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice.

    Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, receipt of a copy of some or all of the same material does not give you any rights to use it.

  11. FUTURE REVISIONS OF THIS LICENSE

    The Free Software Foundation may publish new, revised versions of the GNU Free Documentation License from time to time. Such new versions will be similar in spirit to the present version, but may differ in detail to address new problems or concerns. See https://www.gnu.org/licenses/.

    Each version of the License is given a distinguishing version number. If the Document specifies that a particular numbered version of this License “or any later version” applies to it, you have the option of following the terms and conditions either of that specified version or of any later version that has been published (not as a draft) by the Free Software Foundation. If the Document does not specify a version number of this License, you may choose any version ever published (not as a draft) by the Free Software Foundation. If the Document specifies that a proxy can decide which future versions of this License can be used, that proxy’s public statement of acceptance of a version permanently authorizes you to choose that version for the Document.

  12. RELICENSING

    “Massive Multiauthor Collaboration Site” (or “MMC Site”) means any World Wide Web server that publishes copyrightable works and also provides prominent facilities for anybody to edit those works. A public wiki that anybody can edit is an example of such a server. A “Massive Multiauthor Collaboration” (or “MMC”) contained in the site means any set of copyrightable works thus published on the MMC site.

    “CC-BY-SA” means the Creative Commons Attribution-Share Alike 3.0 license published by Creative Commons Corporation, a not-for-profit corporation with a principal place of business in San Francisco, California, as well as future copyleft versions of that license published by that same organization.

    “Incorporate” means to publish or republish a Document, in whole or in part, as part of another Document.

    An MMC is “eligible for relicensing” if it is licensed under this License, and if all works that were first published under this License somewhere other than this MMC, and subsequently incorporated in whole or in part into the MMC, (1) had no cover texts or invariant sections, and (2) were thus incorporated prior to November 1, 2008.

    The operator of an MMC Site may republish an MMC contained in the site under CC-BY-SA on the same site at any time before August 1, 2009, provided the MMC is eligible for relicensing.

ADDENDUM: How to use this License for your documents

To use this License in a document you have written, include a copy of the License in the document and put the following copyright and license notices just after the title page:

  Copyright (C)  year  your name.
  Permission is granted to copy, distribute and/or modify this document
  under the terms of the GNU Free Documentation License, Version 1.3
  or any later version published by the Free Software Foundation;
  with no Invariant Sections, no Front-Cover Texts, and no Back-Cover
  Texts.  A copy of the license is included in the section entitled ``GNU
  Free Documentation License''.

If you have Invariant Sections, Front-Cover Texts and Back-Cover Texts, replace the “with…Texts.” line with this:

    with the Invariant Sections being list their titles, with
    the Front-Cover Texts being list, and with the Back-Cover Texts
    being list.

If you have Invariant Sections without Cover Texts, or some other combination of the three, merge those two alternatives to suit the situation.

If your document contains nontrivial examples of program code, we recommend releasing these examples in parallel under your choice of free software license, such as the GNU General Public License, to permit their use in free software.