1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-29 14:51:17 +00:00

ecs: added label sources

This commit is contained in:
Steven Hugg 2022-02-27 10:58:47 -06:00
parent 6f3affaaef
commit c73263d944
3 changed files with 25 additions and 9 deletions

View File

@ -92,9 +92,11 @@ export class ECSCompiler extends Tokenizer {
} }
annotate<T extends SourceLocated>(fn: () => T) { annotate<T extends SourceLocated>(fn: () => T) {
let tok = this.peekToken(); let start = this.peekToken();
let obj = fn(); 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; return obj;
} }
@ -349,7 +351,7 @@ export class ECSCompiler extends Tokenizer {
tempbytes = this.parseIntegerConstant(); tempbytes = this.parseIntegerConstant();
} }
let system: System = { name, tempbytes, actions: [] }; let system: System = { name, tempbytes, actions: [] };
let expr = this.parseBlockStatement(); let expr = this.annotate(() => this.parseBlockStatement());
let action: Action = { expr, event: name }; let action: Action = { expr, event: name };
system.actions.push(action); system.actions.push(action);
return system; return system;
@ -363,7 +365,7 @@ export class ECSCompiler extends Tokenizer {
let critical = undefined; let critical = undefined;
if (this.ifToken('critical')) critical = true; if (this.ifToken('critical')) critical = true;
if (this.ifToken('fit')) fitbytes = this.parseIntegerConstant(); if (this.ifToken('fit')) fitbytes = this.parseIntegerConstant();
let expr = this.parseBlockStatement(); let expr = this.annotate(() => this.parseBlockStatement());
//query, join, select, direction, //query, join, select, direction,
let action : Action = { expr, event, fitbytes, critical }; let action : Action = { expr, event, fitbytes, critical };
return action as Action; return action as Action;
@ -770,6 +772,7 @@ export class ECSCompiler extends Tokenizer {
parseExprList(): Expr[] { parseExprList(): Expr[] {
return this.parseList(this.parseExpr, ','); return this.parseList(this.parseExpr, ',');
} }
// TODO: annotate with location
parseBlockStatement(): Statement { parseBlockStatement(): Statement {
let valtype : IntType = { dtype:'int', lo:0, hi: 0 } // TODO? let valtype : IntType = { dtype:'int', lo:0, hi: 0 } // TODO?
if (this.peekToken().type == ECSTokenType.CodeFragment) { if (this.peekToken().type == ECSTokenType.CodeFragment) {
@ -778,7 +781,7 @@ export class ECSCompiler extends Tokenizer {
if (this.ifToken('begin')) { if (this.ifToken('begin')) {
let stmts = []; let stmts = [];
while (this.peekToken().str != 'end') { while (this.peekToken().str != 'end') {
stmts.push(this.parseBlockStatement()); stmts.push(this.annotate(() => this.parseBlockStatement()));
} }
this.expectToken('end'); this.expectToken('end');
return { valtype, stmts }; return { valtype, stmts };
@ -812,7 +815,7 @@ export class ECSCompiler extends Tokenizer {
let direction = undefined; let direction = undefined;
if (modifiers['asc']) direction = 'asc'; if (modifiers['asc']) direction = 'asc';
else if (modifiers['desc']) direction = 'desc'; 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; return { select, query, join, direction, stmts: [body], loop: select == 'foreach' } as QueryExpr;
} }
} }

View File

@ -3,8 +3,10 @@ import { Token } from "../tokenizer";
import { SourceLocated, SourceLocation } from "../workertypes"; import { SourceLocated, SourceLocation } from "../workertypes";
import { Bin, Packer } from "./binpack"; import { Bin, Packer } from "./binpack";
export class ECSError extends Error { export class ECSError extends Error implements SourceLocated {
$loc: SourceLocation; $loc: SourceLocation;
$sources: SourceLocated[] = [];
constructor(msg: string, obj?: SourceLocation | SourceLocated) { constructor(msg: string, obj?: SourceLocation | SourceLocated) {
super(msg); super(msg);
Object.setPrototypeOf(this, ECSError.prototype); Object.setPrototypeOf(this, ECSError.prototype);
@ -834,7 +836,12 @@ class ActionEval {
__emit(args: string[]) { __emit(args: string[]) {
let event = args[0]; let event = args[0];
let eventargs = args.slice(1); 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[]) { __local(args: string[]) {
let tempinc = parseInt(args[0]); let tempinc = parseInt(args[0]);
@ -1053,6 +1060,7 @@ class ActionEval {
case 'once': case 'once':
// TODO: how is this different from begin/end? // TODO: how is this different from begin/end?
//state.xreg = state.yreg = null; //state.xreg = state.yreg = null;
//state.working = new EntitySet(scope, undefined, [], []);
break; break;
case 'foreach': case 'foreach':
case 'unroll': case 'unroll':
@ -1077,7 +1085,7 @@ class ActionEval {
if (select == 'if') { if (select == 'if') {
qr.entities = []; // "if" failed qr.entities = []; // "if" failed
} else { } else {
throw new ECSError(`no entities in statement`, action); throw new ECSError(`no entities match query`, qexpr);
} }
} else { } else {
// TODO: must be a better way... // TODO: must be a better way...

View File

@ -27,6 +27,11 @@ export function assembleECS(step: BuildStep): BuildStepResult {
} catch (e) { } catch (e) {
if (e instanceof ECSError) { if (e instanceof ECSError) {
compiler.addError(e.message, e.$loc); 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 }; return { errors: compiler.errors };
} else if (e instanceof CompileError) { } else if (e instanceof CompileError) {
return { errors: compiler.errors }; return { errors: compiler.errors };