mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
ecs: added label sources
This commit is contained in:
parent
6f3affaaef
commit
c73263d944
@ -92,9 +92,11 @@ export class ECSCompiler extends Tokenizer {
|
||||
}
|
||||
|
||||
annotate<T extends SourceLocated>(fn: () => T) {
|
||||
let tok = this.peekToken();
|
||||
let start = this.peekToken();
|
||||
let obj = fn();
|
||||
if (obj) (obj as SourceLocated).$loc = tok.$loc;
|
||||
let end = this.lasttoken;
|
||||
let $loc = end ? mergeLocs(start.$loc, end.$loc) : start.$loc;
|
||||
if (obj) (obj as SourceLocated).$loc = $loc;
|
||||
return obj;
|
||||
}
|
||||
|
||||
@ -349,7 +351,7 @@ export class ECSCompiler extends Tokenizer {
|
||||
tempbytes = this.parseIntegerConstant();
|
||||
}
|
||||
let system: System = { name, tempbytes, actions: [] };
|
||||
let expr = this.parseBlockStatement();
|
||||
let expr = this.annotate(() => this.parseBlockStatement());
|
||||
let action: Action = { expr, event: name };
|
||||
system.actions.push(action);
|
||||
return system;
|
||||
@ -363,7 +365,7 @@ export class ECSCompiler extends Tokenizer {
|
||||
let critical = undefined;
|
||||
if (this.ifToken('critical')) critical = true;
|
||||
if (this.ifToken('fit')) fitbytes = this.parseIntegerConstant();
|
||||
let expr = this.parseBlockStatement();
|
||||
let expr = this.annotate(() => this.parseBlockStatement());
|
||||
//query, join, select, direction,
|
||||
let action : Action = { expr, event, fitbytes, critical };
|
||||
return action as Action;
|
||||
@ -770,6 +772,7 @@ export class ECSCompiler extends Tokenizer {
|
||||
parseExprList(): Expr[] {
|
||||
return this.parseList(this.parseExpr, ',');
|
||||
}
|
||||
// TODO: annotate with location
|
||||
parseBlockStatement(): Statement {
|
||||
let valtype : IntType = { dtype:'int', lo:0, hi: 0 } // TODO?
|
||||
if (this.peekToken().type == ECSTokenType.CodeFragment) {
|
||||
@ -778,7 +781,7 @@ export class ECSCompiler extends Tokenizer {
|
||||
if (this.ifToken('begin')) {
|
||||
let stmts = [];
|
||||
while (this.peekToken().str != 'end') {
|
||||
stmts.push(this.parseBlockStatement());
|
||||
stmts.push(this.annotate(() => this.parseBlockStatement()));
|
||||
}
|
||||
this.expectToken('end');
|
||||
return { valtype, stmts };
|
||||
@ -812,7 +815,7 @@ export class ECSCompiler extends Tokenizer {
|
||||
let direction = undefined;
|
||||
if (modifiers['asc']) direction = 'asc';
|
||||
else if (modifiers['desc']) direction = 'desc';
|
||||
let body = this.parseBlockStatement();
|
||||
let body = this.annotate(() => this.parseBlockStatement());
|
||||
return { select, query, join, direction, stmts: [body], loop: select == 'foreach' } as QueryExpr;
|
||||
}
|
||||
}
|
||||
|
@ -3,8 +3,10 @@ import { Token } from "../tokenizer";
|
||||
import { SourceLocated, SourceLocation } from "../workertypes";
|
||||
import { Bin, Packer } from "./binpack";
|
||||
|
||||
export class ECSError extends Error {
|
||||
export class ECSError extends Error implements SourceLocated {
|
||||
$loc: SourceLocation;
|
||||
$sources: SourceLocated[] = [];
|
||||
|
||||
constructor(msg: string, obj?: SourceLocation | SourceLocated) {
|
||||
super(msg);
|
||||
Object.setPrototypeOf(this, ECSError.prototype);
|
||||
@ -834,7 +836,12 @@ class ActionEval {
|
||||
__emit(args: string[]) {
|
||||
let event = args[0];
|
||||
let eventargs = args.slice(1);
|
||||
return this.scope.generateCodeForEvent(event, eventargs);
|
||||
try {
|
||||
return this.scope.generateCodeForEvent(event, eventargs);
|
||||
} catch (e) {
|
||||
if (e.$sources) e.$sources.push(this.action);
|
||||
throw e;
|
||||
}
|
||||
}
|
||||
__local(args: string[]) {
|
||||
let tempinc = parseInt(args[0]);
|
||||
@ -1053,6 +1060,7 @@ class ActionEval {
|
||||
case 'once':
|
||||
// TODO: how is this different from begin/end?
|
||||
//state.xreg = state.yreg = null;
|
||||
//state.working = new EntitySet(scope, undefined, [], []);
|
||||
break;
|
||||
case 'foreach':
|
||||
case 'unroll':
|
||||
@ -1077,7 +1085,7 @@ class ActionEval {
|
||||
if (select == 'if') {
|
||||
qr.entities = []; // "if" failed
|
||||
} else {
|
||||
throw new ECSError(`no entities in statement`, action);
|
||||
throw new ECSError(`no entities match query`, qexpr);
|
||||
}
|
||||
} else {
|
||||
// TODO: must be a better way...
|
||||
|
@ -27,6 +27,11 @@ export function assembleECS(step: BuildStep): BuildStepResult {
|
||||
} catch (e) {
|
||||
if (e instanceof ECSError) {
|
||||
compiler.addError(e.message, e.$loc);
|
||||
for (let obj of e.$sources) {
|
||||
let name = (obj as any).event;
|
||||
if (name == 'start') break;
|
||||
compiler.addError(`... ${name}`, obj.$loc); // TODO?
|
||||
}
|
||||
return { errors: compiler.errors };
|
||||
} else if (e instanceof CompileError) {
|
||||
return { errors: compiler.errors };
|
||||
|
Loading…
Reference in New Issue
Block a user