mirror of
https://github.com/inexorabletash/jsbasic.git
synced 2024-11-27 12:49:56 +00:00
Parse error cleanup. Don't tokenize digraphs.
This commit is contained in:
parent
e44c2069e8
commit
c96d891dc3
80
basic.js
80
basic.js
@ -1173,10 +1173,8 @@ this.basic = (function() {
|
|||||||
currLineNumber = 0;
|
currLineNumber = 0;
|
||||||
|
|
||||||
function parse_error(msg) {
|
function parse_error(msg) {
|
||||||
var e = new basic.ParseError(msg + " in line " + currLineNumber,
|
return new basic.ParseError(msg + " in line " + currLineNumber,
|
||||||
currLine, currColumn);
|
currLine, currColumn);
|
||||||
|
|
||||||
throw e;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
@ -1214,7 +1212,7 @@ this.basic = (function() {
|
|||||||
regexStringLiteral = /^"([^"]*?)(?:"|(?=\n|\r|$))/,
|
regexStringLiteral = /^"([^"]*?)(?:"|(?=\n|\r|$))/,
|
||||||
regexNumberLiteral = /^[0-9]*\.?[0-9]+(?:[eE]\s*[\-+]?\s*[0-9]+)?/,
|
regexNumberLiteral = /^[0-9]*\.?[0-9]+(?:[eE]\s*[\-+]?\s*[0-9]+)?/,
|
||||||
regexHexLiteral = /^\$[0-9A-Fa-f]+/,
|
regexHexLiteral = /^\$[0-9A-Fa-f]+/,
|
||||||
regexOperator = /^(;|<[ \t]*=|=[ \t]*<|>[ \t]*=|=[ \t]*>|=[ \t]*=|<[ \t]*>|>[ \t]*<|=|<|>|\+|-|\*|\/|\^|\(|\)|,)/,
|
regexOperator = /^[;=<>+\-*\/\^(),]/,
|
||||||
|
|
||||||
regexLineNumber = /^[0-9]+/,
|
regexLineNumber = /^[0-9]+/,
|
||||||
regexSeparator = /^:/,
|
regexSeparator = /^:/,
|
||||||
@ -1268,7 +1266,7 @@ this.basic = (function() {
|
|||||||
// Extension - allow leading : to continue previous line
|
// Extension - allow leading : to continue previous line
|
||||||
token.separator = stream.lastMatch[0];
|
token.separator = stream.lastMatch[0];
|
||||||
} else {
|
} else {
|
||||||
parse_error("Syntax error: Expected line number or separator");
|
throw parse_error("Syntax error: Expected line number or separator");
|
||||||
}
|
}
|
||||||
} else if (stream.match(regexRemark)) {
|
} else if (stream.match(regexRemark)) {
|
||||||
token.remark = stream.lastMatch[2];
|
token.remark = stream.lastMatch[2];
|
||||||
@ -1291,7 +1289,7 @@ this.basic = (function() {
|
|||||||
} else if (stream.match(regexSeparator)) {
|
} else if (stream.match(regexSeparator)) {
|
||||||
token.separator = stream.lastMatch[0];
|
token.separator = stream.lastMatch[0];
|
||||||
} else {
|
} else {
|
||||||
parse_error("Syntax error: Unexpected '" + source.substr(0, 40) + "'");
|
throw parse_error("Syntax error: Unexpected '" + source.substr(0, 40) + "'");
|
||||||
}
|
}
|
||||||
return token;
|
return token;
|
||||||
}
|
}
|
||||||
@ -1301,7 +1299,7 @@ this.basic = (function() {
|
|||||||
match = function match(type, value) {
|
match = function match(type, value) {
|
||||||
|
|
||||||
if (!lookahead) {
|
if (!lookahead) {
|
||||||
parse_error("Syntax error: Expected " + type + ", saw end of file");
|
throw parse_error("Syntax error: Expected " + type + ", saw end of file");
|
||||||
}
|
}
|
||||||
|
|
||||||
var token = lookahead;
|
var token = lookahead;
|
||||||
@ -1311,11 +1309,11 @@ this.basic = (function() {
|
|||||||
lookahead = nextToken();
|
lookahead = nextToken();
|
||||||
|
|
||||||
if (!{}.hasOwnProperty.call(token, type)) {
|
if (!{}.hasOwnProperty.call(token, type)) {
|
||||||
parse_error("Syntax error: Expected " + type + ", saw " + JSON.stringify(token));
|
throw parse_error("Syntax error: Expected " + type + ", saw " + JSON.stringify(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
if (value !== (void 0) && token[type] !== value) {
|
if (value !== (void 0) && token[type] !== value) {
|
||||||
parse_error("Syntax error: Expected '" + value + "', saw " + JSON.stringify(token));
|
throw parse_error("Syntax error: Expected '" + value + "', saw " + JSON.stringify(token));
|
||||||
}
|
}
|
||||||
|
|
||||||
return token[type];
|
return token[type];
|
||||||
@ -1397,7 +1395,7 @@ this.basic = (function() {
|
|||||||
|
|
||||||
function enforce_type(actual, expected) {
|
function enforce_type(actual, expected) {
|
||||||
if (actual !== expected) {
|
if (actual !== expected) {
|
||||||
parse_error('Type mismatch error: Expected ' + expected);
|
throw parse_error('Type mismatch error: Expected ' + expected);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1477,7 +1475,7 @@ this.basic = (function() {
|
|||||||
|
|
||||||
function parsefunction(name) {
|
function parsefunction(name) {
|
||||||
if (!{}.hasOwnProperty.call(funlib, name)) {
|
if (!{}.hasOwnProperty.call(funlib, name)) {
|
||||||
parse_error("Undefined function: " + name);
|
throw parse_error("Undefined function: " + name);
|
||||||
}
|
}
|
||||||
|
|
||||||
match("operator", "(");
|
match("operator", "(");
|
||||||
@ -1618,31 +1616,29 @@ this.basic = (function() {
|
|||||||
|
|
||||||
function parseRelationalExpression() {
|
function parseRelationalExpression() {
|
||||||
var lhs = parseAdditiveExpression(), rhs, op;
|
var lhs = parseAdditiveExpression(), rhs, op;
|
||||||
while (
|
while (test('operator', '<') || test('operator', '>') || test('operator', '=')) {
|
||||||
test('operator', '<') || test('operator', '>') ||
|
|
||||||
test('operator', '=') || test('operator', '==') ||
|
|
||||||
test('operator', '<=') || test('operator', '=<') ||
|
|
||||||
test('operator', '>=') || test('operator', '=>') ||
|
|
||||||
test('operator', '<>') || test('operator', '><')) {
|
|
||||||
|
|
||||||
op = match('operator');
|
op = match('operator');
|
||||||
|
switch (op) {
|
||||||
|
case '<':
|
||||||
|
if (test('operator', '=', true)) { op = '<='; break; }
|
||||||
|
if (test('operator', '>', true)) { op = '!=='; break; }
|
||||||
|
break;
|
||||||
|
case '>':
|
||||||
|
if (test('operator', '=', true)) { op = '>='; break; }
|
||||||
|
if (test('operator', '<', true)) { op = '!=='; break; }
|
||||||
|
break;
|
||||||
|
case '=':
|
||||||
|
if (test('operator', '<', true)) { op = '<='; break; }
|
||||||
|
if (test('operator', '>', true)) { op = '>='; break; }
|
||||||
|
if (test('operator', '=', true)) { op = '==='; break; }
|
||||||
|
op = '===';
|
||||||
|
}
|
||||||
|
|
||||||
rhs = parseAdditiveExpression();
|
rhs = parseAdditiveExpression();
|
||||||
|
|
||||||
enforce_type(rhs.type, lhs.type);
|
enforce_type(rhs.type, lhs.type);
|
||||||
|
lhs = lhs = { source: '((' + lhs.source + op + rhs.source + ')?1:0)', type: 'number' };
|
||||||
switch (op) {
|
|
||||||
case "<": lhs = { source: '((' + lhs.source + '<' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
case ">": lhs = { source: '((' + lhs.source + '>' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
case "<=":
|
|
||||||
case "=<": lhs = { source: '((' + lhs.source + '<=' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
case ">=":
|
|
||||||
case "=>": lhs = { source: '((' + lhs.source + '>=' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
case "=":
|
|
||||||
case "==": lhs = { source: '((' + lhs.source + '===' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
case "<>":
|
|
||||||
case "><": lhs = { source: '((' + lhs.source + '!==' + rhs.source + ')?1:0)', type: 'number' }; break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
return lhs;
|
return lhs;
|
||||||
}
|
}
|
||||||
@ -1748,7 +1744,7 @@ this.basic = (function() {
|
|||||||
match("operator", "=");
|
match("operator", "=");
|
||||||
|
|
||||||
if (vartype(name) !== vartype(param)) {
|
if (vartype(name) !== vartype(param)) {
|
||||||
parse_error("DEF FN function type and argument type must match");
|
throw parse_error("DEF FN function type and argument type must match");
|
||||||
}
|
}
|
||||||
|
|
||||||
expr = vartype(name) === 'string'
|
expr = vartype(name) === 'string'
|
||||||
@ -1782,7 +1778,7 @@ this.basic = (function() {
|
|||||||
|
|
||||||
keyword = match('reserved');
|
keyword = match('reserved');
|
||||||
if (keyword !== kws.GOTO && keyword !== kws.GOSUB) {
|
if (keyword !== kws.GOTO && keyword !== kws.GOSUB) {
|
||||||
parse_error("Syntax error: Expected " + kws.GOTO + " or " + kws.GOSUB);
|
throw parse_error("Syntax error: Expected " + kws.GOTO + " or " + kws.GOSUB);
|
||||||
}
|
}
|
||||||
|
|
||||||
args = [];
|
args = [];
|
||||||
@ -1804,7 +1800,7 @@ this.basic = (function() {
|
|||||||
case kws.FOR: // FOR i = m TO n STEP s
|
case kws.FOR: // FOR i = m TO n STEP s
|
||||||
name = match('identifier');
|
name = match('identifier');
|
||||||
if (vartype(name) !== 'float') {
|
if (vartype(name) !== 'float') {
|
||||||
parse_error("Syntax error: Expected floating point variable");
|
throw parse_error("Syntax error: Expected floating point variable");
|
||||||
}
|
}
|
||||||
identifiers.variables[name] = true;
|
identifiers.variables[name] = true;
|
||||||
|
|
||||||
@ -2049,8 +2045,7 @@ this.basic = (function() {
|
|||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
||||||
case kws.LIST: // List program statements
|
case kws.LIST: // List program statements
|
||||||
parse_error("Introspection statement not supported: " + keyword);
|
throw parse_error("Introspection statement not supported: " + keyword);
|
||||||
return;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -2063,16 +2058,14 @@ this.basic = (function() {
|
|||||||
case kws.SCALE: // Set rotation angle for hires shape
|
case kws.SCALE: // Set rotation angle for hires shape
|
||||||
case kws.DRAW: // Draw hires shape
|
case kws.DRAW: // Draw hires shape
|
||||||
case kws.XDRAW: // XOR draw hires shape
|
case kws.XDRAW: // XOR draw hires shape
|
||||||
parse_error("Display statement not supported: " + keyword);
|
throw parse_error("Display statement not supported: " + keyword);
|
||||||
return;
|
|
||||||
|
|
||||||
// Interpreter Routines
|
// Interpreter Routines
|
||||||
case kws.CONT: // Continue stopped program (immediate mode)
|
case kws.CONT: // Continue stopped program (immediate mode)
|
||||||
case kws.DEL: // Deletes program statements
|
case kws.DEL: // Deletes program statements
|
||||||
case kws.NEW: // Wipe program
|
case kws.NEW: // Wipe program
|
||||||
case kws.RUN: // Execute program
|
case kws.RUN: // Execute program
|
||||||
parse_error("Interpreter statement not supported: " + keyword);
|
throw parse_error("Interpreter statement not supported: " + keyword);
|
||||||
return;
|
|
||||||
|
|
||||||
// Native Routines
|
// Native Routines
|
||||||
case kws.HIMEM: // Set upper bound of variable memory
|
case kws.HIMEM: // Set upper bound of variable memory
|
||||||
@ -2080,8 +2073,7 @@ this.basic = (function() {
|
|||||||
case kws.LOMEM: // Set low bound of variable memory
|
case kws.LOMEM: // Set low bound of variable memory
|
||||||
case kws.WAIT: // Wait for memory value to match a condition
|
case kws.WAIT: // Wait for memory value to match a condition
|
||||||
case kws.AMPERSAND: // Command hook
|
case kws.AMPERSAND: // Command hook
|
||||||
parse_error("Native interop statement not supported: " + keyword);
|
throw parse_error("Native interop statement not supported: " + keyword);
|
||||||
return;
|
|
||||||
|
|
||||||
// Tape Routines
|
// Tape Routines
|
||||||
case kws.LOAD: // Load program from cassette port
|
case kws.LOAD: // Load program from cassette port
|
||||||
@ -2089,8 +2081,7 @@ this.basic = (function() {
|
|||||||
case kws.SAVE: // Save program to cassette port
|
case kws.SAVE: // Save program to cassette port
|
||||||
case kws.STORE: // Store array to cassette port
|
case kws.STORE: // Store array to cassette port
|
||||||
case kws.SHLOAD: // Load shape table from cassette port
|
case kws.SHLOAD: // Load shape table from cassette port
|
||||||
parse_error("Tape statement not supported: " + keyword);
|
throw parse_error("Tape statement not supported: " + keyword);
|
||||||
return;
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
//
|
//
|
||||||
@ -2100,8 +2091,7 @@ this.basic = (function() {
|
|||||||
|
|
||||||
// Parts of other statements - AT, FN, STEP, TO, THEN, etc.
|
// Parts of other statements - AT, FN, STEP, TO, THEN, etc.
|
||||||
default:
|
default:
|
||||||
parse_error("Syntax error: " + keyword);
|
throw parse_error("Syntax error: " + keyword);
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user