1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-26 10:49:17 +00:00

added SourceLocation for runtime errors (EmuHalt)

This commit is contained in:
Steven Hugg 2020-08-09 16:32:52 -05:00
parent 17f99b34d4
commit 8b7b581217
5 changed files with 27 additions and 10 deletions

View File

@ -262,6 +262,7 @@ export class BASICParser {
decls: { [name: string]: SourceLocation }; // declared/set vars decls: { [name: string]: SourceLocation }; // declared/set vars
refs: { [name: string]: SourceLocation }; // references refs: { [name: string]: SourceLocation }; // references
path : string;
lineno : number; lineno : number;
tokens: Token[]; tokens: Token[];
eol: Token; eol: Token;
@ -281,7 +282,7 @@ export class BASICParser {
compileError(msg: string, loc?: SourceLocation) { compileError(msg: string, loc?: SourceLocation) {
if (!loc) loc = this.peekToken().$loc; if (!loc) loc = this.peekToken().$loc;
// TODO: pass SourceLocation to errors // TODO: pass SourceLocation to errors
this.errors.push({line:loc.line, msg:msg}); this.errors.push({path:loc.path, line:loc.line, msg:msg});
throw new CompileError(`${msg} (line ${loc.line})`); // TODO: label too? throw new CompileError(`${msg} (line ${loc.line})`); // TODO: label too?
} }
dialectError(what: string, loc?: SourceLocation) { dialectError(what: string, loc?: SourceLocation) {
@ -336,6 +337,7 @@ export class BASICParser {
} }
} }
parseFile(file: string, path: string) : BASICProgram { parseFile(file: string, path: string) : BASICProgram {
this.path = path;
var pgmlines = file.split("\n").map((line) => this.parseLine(line)); var pgmlines = file.split("\n").map((line) => this.parseLine(line));
var program = { opts: this.opts, lines: pgmlines }; var program = { opts: this.opts, lines: pgmlines };
this.checkAll(program); this.checkAll(program);
@ -369,13 +371,13 @@ export class BASICParser {
this.tokens.push({ this.tokens.push({
str: s, str: s,
type: i, type: i,
$loc: { line: this.lineno, start: m.index, end: m.index+s.length } $loc: { path: this.path, line: this.lineno, start: m.index, end: m.index+s.length }
}); });
break; break;
} }
} }
} }
this.eol = { type: TokenType.EOL, str: "", $loc: { line: this.lineno, start: line.length } }; this.eol = { type: TokenType.EOL, str: "", $loc: { path: this.path, line: this.lineno, start: line.length } };
} }
parse() : BASICLine { parse() : BASICLine {
var line = {label: null, stmts: []}; var line = {label: null, stmts: []};
@ -444,7 +446,7 @@ export class BASICParser {
this.compileError(`There should be a command here.`); this.compileError(`There should be a command here.`);
return null; return null;
} }
if (stmt) stmt.$loc = { line: cmdtok.$loc.line, start: cmdtok.$loc.start, end: this.peekToken().$loc.start }; if (stmt) stmt.$loc = { path: cmdtok.$loc.path, line: cmdtok.$loc.line, start: cmdtok.$loc.start, end: this.peekToken().$loc.start };
return stmt; return stmt;
} }
parseVarSubscriptOrFunc(): IndOp { parseVarSubscriptOrFunc(): IndOp {

View File

@ -1,6 +1,7 @@
import * as basic from "./compiler"; import * as basic from "./compiler";
import { EmuHalt } from "../emu"; import { EmuHalt } from "../emu";
import { SourceLocation } from "../workertypes";
function isLiteral(arg: basic.Expr): arg is basic.Literal { function isLiteral(arg: basic.Expr): arg is basic.Literal {
return (arg as any).value != null; return (arg as any).value != null;
@ -110,9 +111,9 @@ export class BASICRuntime {
runtimeError(msg : string) { runtimeError(msg : string) {
this.curpc--; // we did curpc++ before executing statement this.curpc--; // we did curpc++ before executing statement
// TODO: pass source location to error throw new EmuHalt(msg, this.getCurrentSourceLocation());
throw new EmuHalt(`${msg} (line ${this.getLabelForPC(this.curpc)})`);
} }
dialectError(what : string) { dialectError(what : string) {
this.runtimeError(`I can't ${what} in this dialect of BASIC.`); this.runtimeError(`I can't ${what} in this dialect of BASIC.`);
} }
@ -132,6 +133,11 @@ export class BASICRuntime {
return pgmline ? pgmline.label : '?'; return pgmline ? pgmline.label : '?';
} }
getCurrentSourceLocation() : SourceLocation {
var stmt = this.getStatement();
return stmt && stmt.$loc;
}
getStatement() { getStatement() {
return this.allstmts[this.curpc]; return this.allstmts[this.curpc];
} }

View File

@ -1,6 +1,7 @@
"use strict"; "use strict";
import { hex, clamp, lpad } from "./util"; import { hex, clamp, lpad } from "./util";
import { SourceLocation } from "./workertypes";
// external modules // external modules
declare var jt, Javatari; declare var jt, Javatari;
@ -225,8 +226,10 @@ export class RAM {
} }
export class EmuHalt extends Error { export class EmuHalt extends Error {
constructor(msg:string) { $loc : SourceLocation;
constructor(msg: string, loc?: SourceLocation) {
super(msg); super(msg);
this.$loc = loc;
Object.setPrototypeOf(this, EmuHalt.prototype); Object.setPrototypeOf(this, EmuHalt.prototype);
} }
} }

View File

@ -3,13 +3,14 @@ export type FileData = string | Uint8Array;
export interface SourceLocation { export interface SourceLocation {
line: number; line: number;
label?: string;
path?: string; // TODO: make mandatory?
start?: number; start?: number;
end?: number; end?: number;
} }
export interface SourceLine { export interface SourceLine extends SourceLocation {
offset:number; offset:number;
line:number;
insns?:string; insns?:string;
iscode?:boolean; iscode?:boolean;
cycles?:number; cycles?:number;

View File

@ -1884,7 +1884,12 @@ function globalErrorHandler(msgevent) {
if (msg.indexOf("QuotaExceededError") >= 0) { if (msg.indexOf("QuotaExceededError") >= 0) {
requestPersistPermission(false, false); requestPersistPermission(false, false);
} else { } else {
showErrorAlert([{msg:msg,line:0}]); var err = msgevent.error;
var werr : WorkerError = {msg:msg, line:0};
if (err instanceof EmuHalt && err.$loc) {
werr = {msg:msg, path:err.$loc.path, line:err.$loc.line}; // TODO: get start/end columns
}
showErrorAlert([werr]);
} }
} }