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:
parent
17f99b34d4
commit
8b7b581217
@ -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 {
|
||||||
|
@ -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];
|
||||||
}
|
}
|
||||||
|
@ -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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -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;
|
||||||
|
@ -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]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user