8

I'm working my way through my retrobasic interpreter, feeding it an expanding diet of 101 BASIC Games. Here's an odd one...

40 DIM F(6,6),H(6,6),A(4),B(4),C(6),L(3)
...
90 A=INT(6*RND(1)+1)

This kills my interpreter because the DIM says this is an array, but on line 90 we try to set its value without a subscript and it expects two.

What is the right thing here:

  1. are DIM A(4) and A two different variables?
  2. when there's no subscript, do you assume 1,1...?

Anyone know what a real BASIC does here?

Maury Markowitz
  • 19,803
  • 1
  • 47
  • 138

4 Answers4

15

They're two different variables, at least in the version of MS BASIC on the C64:

DIM A(4)

READY.
PRINT A, A(1)
 0         0

READY.
A = 1

READY.
PRINT A, A(1)
 1         0

Basically A and A(...) refer to two different variables, just like A$ and A% are also different variables than A.

  • Fantastic thanks! Boy MS is weird... ok I guess I'll add ( to the name in these cases. – Maury Markowitz Nov 22 '19 at 20:22
  • @MauryMarkowitz The 90 A=INT(6*RND(1)+1) line was almost certainly intended to set a different variable than the A(4) variable., so I don't know if you need to change anything. It's not really any different than A and A$ being two different variables. –  Nov 22 '19 at 20:24
  • Indeed, but my parser is seeing a variable called A and then saying it's an array. I need to change the name of A in my code to A( so it doesn't see them as the same variable. This is how Atari BASIC did it, I suspect MS did too. – Maury Markowitz Nov 22 '19 at 20:27
  • @MauryMarkowitz Ah, ok, that makes sense. –  Nov 22 '19 at 20:29
  • I agree. This behavior matches my recollection of GWBASIC. It’s probably a general feature of all editions Microsoft BASIC. – Euro Micelli Nov 22 '19 at 23:15
  • @MauryMarkowitz It's not that weird; it's the simplest way to implement type safety! You always know the type of the variable, and you can't ever confuse variables of different types. It's a rather ingenious way to implement a decent type system for a computer that has a single kilobyte of memory :) – Luaan Nov 23 '19 at 08:30
  • @Luaan - well, A and A() are the same in this case, and the DEFSTR (et all) upsets the syntax-based typing as well. – Maury Markowitz Nov 23 '19 at 13:31
  • @MauryMarkowitz They're not the same; A isn't defined in the first case, so PRINT A prints zero. It has nothing to do with the value in A(1). – Luaan Nov 23 '19 at 15:40
  • @Luaan same type, singles. – Maury Markowitz Nov 23 '19 at 21:08
  • @RossRidge - can you do one more little test for me? Can you try some variations of INPUT to see which works and where the ? prompt appears, if anywhere? INPUT A:INPUT "HELLO",A:INPUT A,"HELLO" etc. – Maury Markowitz Nov 23 '19 at 21:09
  • 1
    Locomotive BASIC (Amstrad CPC range) also treated A and A(0) as different variables. – CJ Dennis Nov 24 '19 at 04:40
  • 1
    @MauryMarkowitz I suggest downloading Vice or some other emulator, that's how I did the test above. –  Nov 24 '19 at 04:46
  • What about printing A(0)? – JeremyP Nov 26 '19 at 10:03
  • @JeremyP Right, the above examples should be written with A(0) if one suspects some kind of aliasing between simple variables and one dimensional arrays. At least MS BASIC class interpreters are using 0 as start index (for the first element). But as already mentioned here, the most BASIC interpreters keep simple variables and arrays separate and this without the need for explicit declaration. At least simple variables are created on first use and typical MS interpreters reserve 11 elements (from 0 to 10) for undeclared arrays. That's why the example in the question will usually work. – Johann Klasek Dec 16 '19 at 21:44
  • A nice side-effect in MS BASIC class interpreters is to use DIM even for simple variables. DIM A, A(20) declares a simple variable early which let you define the order of definition for such variables. This gives you the advantage to control how fast a variable can found and accessed in the (in most cases linear searched) variable table. – Johann Klasek Dec 16 '19 at 21:50
4

It depends on your BASIC. Some Basic distinguish between arrays and simple variables, some don't.

MS-BASIC, Sinclair's ZX81 and many other separate them.

Similar for simple variables, some BASIC distinguish between simple varables of different type. So A, A$, A! and A% are different variables.

The workings come from the way variables are searched. The interpreter always scans a whole variable name until the first stop character. If it's one of the type characters it will be part of then name - this includes opening parentheses as array delimiters.

Raffzahn
  • 222,541
  • 22
  • 631
  • 918
3

To further confuse the issue, both ANSI/ECMA BASIC standards, in their minimal and full implementations, do not allow simple scalars an arrays to have the same name. This from ECMA-55: Minimal BASIC, page 9:

The same letter shall not be the name of both a simple variable and an array, nor the name of both a one-dimensional and a two- dimensional array.

(emphasis mine).

This is surprising, as:

  1. Kemeny, one of the authors of Dartmouth BASIC, was on the ANSI standard committee;

  2. Microsoft BASIC-80 v5 — which claims ANSI Minimal BASIC compatibility, including passing its test suite — allows arrays and scalars to share the same name.

For example, running this code through the strict bas55 Minimal BASIC interpreter:

10 DIM A(3)
20 LET A(1)=5
30 LET A=1
40 PRINT A,A(1)
50 END

results in the following errors:

30: error: type mismatch for variable A
 info: it was previously used or DIM as a one-dimension array
 LET A=1
     ^
40: error: type mismatch for variable A
 info: it was previously used or DIM as a one-dimension array
 PRINT A,A(1)
       ^

Every other interpreter I have runs the program without complaint.

scruss
  • 21,585
  • 1
  • 45
  • 113
  • 1
    I think this is written as a conformance requirement on the program, not the language implementation (i.e. a program that does this is not compatible, just like one that uses a 19-character string, but a specific implementation may accept it). – Michael Homer Nov 24 '19 at 06:05
2

I propose that Dartmouth's implementation of BASIC should be regarded as definitive, since they invented the language.

In Dartmouth BASIC, A and A() were distinct variables.

The single letter denoting a list or table name may also be used to denote a simple variable without confusion.

(In this context, "list" is a 1-dimensional array, "table" is a 2-dimensional array).

See this 1964 Dartmouth College Computation Center document, page 36.

It's true that the OP is specifically asking about Microsoft BASIC, but since he also asks in the final line "Anyone know what a real BASIC does here?", I think Dartmouth BASIC is relevant. Dartmouth BASIC is the real and original BASIC; any other implementation claiming language compatibility is obliged to follow suit in this respect.

dave
  • 35,301
  • 3
  • 80
  • 160
  • Later Dartmouth interpreters added the MAT matrix commands which few interpreters implement now: which is definitive? Maybe consider the ANSI/ECMA BASIC standards: ECMA-55: Minimal BASIC (1978) and ECMA-116: BASIC (1986), less machine specific than Dartmouth's GE dependencies and Kemeny was on the ANSI committee. They do not allow simple variables and arrays to share a name – scruss Nov 23 '19 at 21:25