Skip to content

Commit 908ce27

Browse files
authored
Merge pull request #12 from jgarzik/updates
tighten xbasic64’s GW-BASIC/QuickBASIC compatibility
2 parents d76fa14 + 9677865 commit 908ce27

27 files changed

Lines changed: 4359 additions & 867 deletions

File tree

LANGREF.md

Lines changed: 90 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,16 @@ Multiple statements can appear on one line separated by colons:
6969
A = 1 : B = 2 : PRINT A + B
7070
```
7171

72+
### Line Continuation
73+
74+
A trailing underscore joins a statement to the next line. Nothing may follow it
75+
on the line it ends:
76+
77+
```basic
78+
Total = Price * Quantity + _
79+
Shipping
80+
```
81+
7282
### Block Terminators
7383

7484
Each multi-line block may be closed with either the two-word form or a single
@@ -260,13 +270,21 @@ case-sensitive and a prefix sorts before the longer string (`"ab" < "abc"`).
260270
| `XOR` | Bitwise/logical XOR |
261271
| `NOT` | Bitwise/logical NOT |
262272

263-
These operate bitwise on integers, allowing both logical tests and bit manipulation:
273+
These operate bitwise on integers, allowing both logical tests and bit
274+
manipulation. Their operands are converted to integers first, and the result is
275+
an integer:
264276

265277
```basic
266278
IF A > 0 AND B > 0 THEN PRINT "Both positive"
267279
Flags% = Flags% OR &H01 ' Set bit 0
280+
Mask% = NOT &H00FF ' -256: every bit flipped
268281
```
269282

283+
`NOT` complements every bit, so `NOT 1` is `-2`, which is non-zero and therefore
284+
*true*. This matters only when testing a value that is not already a truth
285+
value: comparisons yield -1 or 0, and `NOT` maps those to each other, so
286+
`IF NOT (A > 0)` behaves as expected while `IF NOT 1` does not.
287+
270288
### String Concatenation
271289

272290
```basic
@@ -287,6 +305,9 @@ From highest to lowest:
287305

288306
Because `^` binds tighter than unary negation, `-2 ^ 2` is `-(2 ^ 2)` = -4.
289307

308+
Operators of equal precedence associate left to right, `^` included: `2 ^ 3 ^ 2`
309+
is `(2 ^ 3) ^ 2` = 64, and `100 - 10 - 5` is 85.
310+
290311
Use parentheses to override precedence:
291312
```basic
292313
Result = (A + B) * C
@@ -382,10 +403,24 @@ Read user input:
382403

383404
```basic
384405
INPUT X ' Prompt with "? "
385-
INPUT "Enter name: ", N$ ' Custom prompt
406+
INPUT "Enter name: "; N$ ' Prints: Enter name: ?
407+
INPUT "Enter name: ", N$ ' Prints: Enter name:
386408
INPUT "X, Y: ", X, Y ' Multiple values
387409
```
388410

411+
The separator decides the question mark: a `;` after the prompt adds `? `, a
412+
`,` suppresses it, and a prompt-less `INPUT` prints `? ` on its own.
413+
414+
A `;` *before* the prompt is accepted and ignored:
415+
416+
```basic
417+
INPUT ; "Enter name: "; N$
418+
```
419+
420+
In GW-BASIC it suppressed the newline echoed when the operator pressed Return.
421+
That newline comes from the terminal here rather than from the program, so
422+
there is nothing for it to suppress.
423+
389424
### LINE INPUT
390425

391426
Read entire line as string (no parsing):
@@ -394,6 +429,9 @@ Read entire line as string (no parsing):
394429
LINE INPUT "Enter text: ", Text$
395430
```
396431

432+
`LINE INPUT` never adds a question mark; write one into the prompt if you want
433+
one.
434+
397435
### IF...THEN...ELSE
398436

399437
**Single-line form:**
@@ -402,6 +440,23 @@ IF X > 0 THEN PRINT "Positive"
402440
IF X > 0 THEN Y = 1 ELSE Y = 0
403441
```
404442

443+
Both branches take a list of statements separated by colons. Everything after
444+
`THEN` up to `ELSE` or the end of the line is conditional, and everything after
445+
`ELSE` is too:
446+
447+
```basic
448+
IF X > 0 THEN Y = 1 : PRINT "Positive" ELSE Y = 0 : PRINT "Not positive"
449+
```
450+
451+
A bare line number after `THEN` or `ELSE` is an implied `GOTO`:
452+
453+
```basic
454+
10 IF X < 0 THEN 90
455+
20 IF X = 0 THEN 90 ELSE 80
456+
80 PRINT "Positive"
457+
90 PRINT "Done"
458+
```
459+
405460
**Block form:**
406461
```basic
407462
IF X > 0 THEN
@@ -454,13 +509,24 @@ FOR K = 0 TO 1 STEP 0.1
454509
NEXT K
455510
```
456511

457-
The loop variable name after `NEXT` is optional:
512+
The loop variable name after `NEXT` is optional, and a bare `NEXT` closes the
513+
innermost open loop:
458514
```basic
459515
FOR I = 1 TO 10
460516
PRINT I
461517
NEXT
462518
```
463519

520+
If the name *is* given it must be the one that loop counts, so `FOR I ... NEXT J`
521+
is an error rather than a loop closed by surprise. One `NEXT` may close several
522+
nested loops, innermost first:
523+
```basic
524+
FOR I = 1 TO 3
525+
FOR J = 1 TO 3
526+
PRINT I * J
527+
NEXT J, I
528+
```
529+
464530
### WHILE...WEND
465531

466532
Pre-test loop:
@@ -577,6 +643,18 @@ RESTORE ' Reset data pointer to beginning
577643
RESTORE 100 ' Resume at the DATA on line 100
578644
```
579645

646+
A DATA item needs quotes only if it contains a comma, a colon, or spaces that
647+
matter. Otherwise write it plainly; surrounding spaces are trimmed and the text
648+
is taken exactly as written, case included. An omitted item reads as 0 or `""`:
649+
650+
```basic
651+
DATA hello, World, "a,b", " padded "
652+
DATA 1,,3
653+
```
654+
655+
A colon ends a DATA statement, so another statement may follow it on the same
656+
line.
657+
580658
### CLS
581659

582660
Clear screen:
@@ -925,7 +1003,10 @@ blanks and line breaks, so several fields may come from one line and one
9251003
field may span several. A field wrapped in quotes may contain commas.
9261004
`LINE INPUT #` takes a whole line, commas and all.
9271005

928-
`EOF()` gives the usual read-until-the-end loop:
1006+
Reading past the end of a file is an error (`Input past end of file`), as is
1007+
opening a file that is not there (`File not found`) or re-using a file number
1008+
that is still open (`File already open`). `EOF()` gives the usual
1009+
read-until-the-end loop:
9291010

9301011
```basic
9311012
OPEN "data.txt" FOR INPUT AS #1
@@ -1080,9 +1161,13 @@ END SUB
10801161
10811162
' Call the subroutine
10821163
PrintGreeting "World"
1083-
PrintGreeting("World") ' Parentheses optional
1164+
PrintGreeting("World") ' Parentheses optional
1165+
CALL PrintGreeting("World") ' CALL is accepted too
10841166
```
10851167

1168+
`CALL` is recognised only before a name at the start of a statement, so a
1169+
program may still use it as a variable.
1170+
10861171
### FUNCTION
10871172

10881173
Procedures that return a value:

0 commit comments

Comments
 (0)