# 13. Differences from BASIC 7.0 If you already write Commodore BASIC, this is the chapter to read first. Everything here is deliberate, and everything is recorded in the repository's `TODO.md` with the reasoning — this is the short version. ## The language ### Variables carry a type suffix, and the suffixes differ | | Integer | Float | String | |---|---|---|---| | C128 | `A%` | `A` | `A$` | | akbasic | `A#` | `A%` | `A$` | There is **no such thing as an unsuffixed variable**. A bare name is a label. ### `=` works in a condition, and `==` works everywhere `IF A = 5 THEN` does what you expect. `==` also means equality and is what the older programs in this repository use. Outside a condition `=` is assignment, as always. ### `AND`, `OR` and `NOT` in conditions These work, and a condition is a whole expression rather than a single comparison, so `IF A = 1 AND B = 2 THEN` parses. Truth is nonzero, so `IF A THEN` works too. ### `MID` and `INSTR` count from zero A C128 counts from one. A failed `INSTR` gives -1 rather than 0. ### `THEN` needs a verb `IF X THEN 100` is not a jump. Write `IF X THEN GOTO 100`. ### Strings are 255 characters and cannot contain a quote There is no escape character. ### Numbers Integers are 64-bit and floats are IEEE doubles, so `PRINT 1.5` gives `1.500000`. A leading zero is not octal; `0x` is hexadecimal. ### Mixed arithmetic follows the left operand, not the wider type **A C128 promotes to float. This does not.** An integer on the left converts the right operand to an integer and throws its fraction away, so `A# * 0.45` is `0` where `0.45 * A#` is `1.35`. It is consistent, it is inherited from the Go interpreter this was ported from, and **nothing fails when you get it wrong** — the program computes something else and carries on. [Chapter 3](03-the-language.md#the-left-operand-decides-whether-the-arithmetic-is-integer-or-float) has the two rules that keep you out of it. This is the difference from 7.0 most likely to turn a working listing into a quietly wrong one. ### Structures are an addition BASIC 7.0 has no records at all. `TYPE`/`END TYPE`, `DIM X@ AS T`, the `@` suffix, `.` and `->`, `PTR TO` and `POINT ... AT` are all new here, and **[Chapter 16](16-structures.md)** is the whole of it. Nothing about it changes an existing program. Two consequences a C128 programmer should know. A structure assignment **copies**, like every other assignment; sharing is spelled `POINT`. And a type name is a bare word, so it shares a namespace with verbs and labels — `TYPE POINT` is refused because `POINT` is now a verb. ## Block structure **A whole loop on one line does not loop.** ```basic 10 FOR I# = 1 TO 3 : PRINT I# : NEXT I# 20 PRINT "DONE" ``` ```output DONE ``` The loop prints nothing. Block skipping walks source *lines*, so a `NEXT` on the same line as its `FOR` is never reached. The same applies to `DO`/`LOOP`. Write loops across lines. ## Two known defects in `FOR` Both are recorded, both have tests asserting the correct behaviour, and both are waiting on a decision rather than on work: - **A step that overshoots runs the body one extra time.** `FOR I = 1 TO 9 STEP 3` runs with 1, 4, 7 *and 10*. - **`FOR I = 1 TO 1` does not run its body at all**, where every other BASIC runs it once. The two errors cancel out for a step of 1, which is why they went unnoticed. Fixing them would change the output of a checked-in acceptance file, which is not something this project does silently. **A loop counter does not survive its loop.** It lives in the loop's own scope, so reading it afterwards gives zero. ## Direct mode A statement typed with no line number runs immediately, as it should. This was not true until recently — the interpreter used to file everything but a handful of verbs as program text. ## Line numbers **A program in a file does not need them.** Every BASIC this dialect descends from required a number on every line; here that requirement belongs to the prompt alone, where the number is the only thing separating program text from a statement to run now. A program loaded from a file, or handed to the library as a string, may leave them out, and a line without one is given the next number going. The two mix: a numbered line sets where the next unnumbered one goes. This is QuickBASIC's idea rather than the C128's, and it is here for the same reason QuickBASIC had it — a program that branches by `LABEL` never names a line number, so the numbers are maintenance with nothing on the other end of it. Two consequences worth knowing: - **`GOTO ` must name a number the program wrote.** In a file with no line numbers `GOTO 100` would otherwise find the hundredth line and branch there. It is refused before the program runs. `GOTO