Make line numbers relevant; resolves issue #5

This commit is contained in:
Joshua Bell 2014-12-28 20:55:23 -07:00
parent cef9261ca2
commit f55aa51023
3 changed files with 45 additions and 14 deletions

View File

@ -10,7 +10,6 @@ Notes & Known Issues
* The BASIC program is compiled to JavaScript before execution. Syntax errors are therefore detected at compile-time rather than at run-time as on a traditional interpreter. For example, the following program would run without errors on an Apple since the erroneous second statement is never reached. `10 END : CHR$(PRINT)`
* Handling of BASIC code that does not match the canonical `LIST` output format may not behave as on an Apple:
* Keyword parsing differs from Applesoft command line. For example `FOR I = S TO P` doesn't collapse into `FOR I = STOP`.
* The interpreter doesn't actually care about line numbers for statement ordering (just for `GOTO/GOSUB` targets and `IF` statements). So `20 PRINT "A"`, `10 PRINT "B"` will just print `A`, then `B`
* Limitations:
* Floating point overflow is only detected on variable assignment.
* Only a subset of DOS 3.3 and ProDOS useful for basic file I/O are implemented.

View File

@ -2132,24 +2132,48 @@ this.basic = (function() {
function parseStatement() {
if (test('data')) {
program.data = program.data.concat(match('data'));
return;
return undefined;
} else if (test('remark', void 0, true)) {
return;
return undefined;
} else if (test('reserved') || test('identifier')) {
program.statements.push(mkfun(parseCommand()));
return mkfun(parseCommand());
} else {
// So TRACE output is correct
program.statements.push(empty_statement);
return empty_statement;
}
}
// Line = line-number Statement { separator Statement }
function parseLine() {
program.statements.push(match('lineNumber'));
parseStatement();
var num = match('lineNumber');
var statements = [];
var statement = parseStatement();
if (statement) statements.push(statement);
while (test('separator', ':', true)) {
parseStatement();
statement = parseStatement();
if (statement) statements.push(statement);
}
insertLine(num, statements);
}
function insertLine(number, statements) {
var remove = 0;
for (var i = 0, len = program.statements.length; i < len; ++i) {
if (typeof program.statements[i] !== 'number')
continue;
if (program.statements[i] < number)
continue;
if (program.statements[i] === number) {
var n = i;
do {
++n;
++remove;
} while (n < len && typeof program.statements[n] !== 'number');
}
break;
}
var args = [i, remove, number].concat(statements);
program.statements.splice.apply(program.statements, args);
}
// Program = Line { Line }

View File

@ -325,8 +325,8 @@
6000 PRINT : PRINT "Inline Data ";
6010 DATA 1,2,3
6011 DATA "A","B","C"
6001 DATA 1,2,3
6002 DATA "A","B","C"
6010 T$ = "READ"
: RESTORE
@ -349,7 +349,7 @@
7010 REM Test GR as part of I/O (sets cursor to window bottom)
7010 REM ************************************************************
7010 POKE 49232,0 : POKE 49234,0 : POKE 49238,0
7011 POKE 49232,0 : POKE 49234,0 : POKE 49238,0
7020 T$ = "COLOR="
: T = 0 : U = 0 : FOR I = 0 TO 15 : COLOR= I : PLOT 0,0 : T = T + I : U = U + SCRN(0,0) : NEXT
@ -748,9 +748,9 @@
17040 T$ = "Sequential Access/ONERR"
: PRINT CHR$(4)"OPEN JABBERWOCKY"
: PRINT CHR$(4)"READ JABBERWOCKY"
: ONERR GOTO 10742 : N = 0
: ONERR GOTO 17042 : N = 0
: FOR N = 0 TO 10 : INPUT A$ : NEXT
10742 POKE 216,0 : PRINT CHR$(4)"CLOSE" : S = (N = 4) : GOSUB 1
17042 POKE 216,0 : PRINT CHR$(4)"CLOSE" : S = (N = 4) : GOSUB 1
17050 T$ = "RENAME"
: PRINT CHR$(4)"OPEN TESTDATA"
@ -812,8 +812,16 @@
: T = 2
18071 S = (T=1) AND (PEEK(222)=107) : GOSUB 1 : POKE 216,0
18080 T$ = "Duplicate Lines"
18081 T = 1
18082 T = T + 1 : REM Should be overwritten
18082 T = T + 1
18083 S = (T = 2) : GOSUB 1
18090 T$ = "Line Ordering"
18092 T = 2
18091 T = 1
18093 S = (T = 2) : GOSUB 1
20000 PRINT : PRINT : PRINT "Executed tests: "; TE
20010 PRINT "Successful tests: "; TS