mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-12-25 15:30:03 +00:00
ecs: no error if select is empty
This commit is contained in:
parent
513fb85b8e
commit
dbc84c94b2
@ -232,7 +232,6 @@ export class ECSCompiler extends Tokenizer {
|
||||
join = this.parseQuery();
|
||||
}
|
||||
let emits;
|
||||
let limit;
|
||||
if (this.peekToken().str == 'limit') {
|
||||
this.consumeToken();
|
||||
if (!query) { this.compileError(`A "${select}" query can't include a limit.`); }
|
||||
@ -350,6 +349,9 @@ export class ECSCompiler extends Tokenizer {
|
||||
if (!field) { this.internalError(); throw new Error(); }
|
||||
this.expectToken('=');
|
||||
let value = this.parseDataValue(field);
|
||||
let symtype = this.currentScope.isConstOrInit(comps[0], name);
|
||||
if (symtype && symtype != cmd)
|
||||
this.compileError(`I can't mix const and init values for a given field in a scope.`);
|
||||
if (cmd == 'const') this.currentScope.setConstValue(e, comps[0], name, value);
|
||||
if (cmd == 'init') this.currentScope.setInitValue(e, comps[0], name, value);
|
||||
}
|
||||
|
@ -100,9 +100,7 @@ export interface ComponentType extends SourceLocated {
|
||||
|
||||
export interface Query extends SourceLocated {
|
||||
include: ComponentType[]; // TODO: make ComponentType
|
||||
listen?: ComponentType[];
|
||||
exclude?: ComponentType[];
|
||||
updates?: ComponentType[];
|
||||
limit?: number;
|
||||
}
|
||||
|
||||
@ -520,9 +518,9 @@ class ActionEval {
|
||||
if (q) this.qr = new EntitySet(scope, q);
|
||||
else this.qr = new EntitySet(scope, undefined, [], []);
|
||||
this.entities = this.qr.entities;
|
||||
let query = (this.action as ActionWithQuery).query;
|
||||
if (query && this.entities.length == 0)
|
||||
throw new ECSError(`query doesn't match any entities`, query); // TODO
|
||||
//let query = (this.action as ActionWithQuery).query;
|
||||
//TODO? if (query && this.entities.length == 0)
|
||||
//throw new ECSError(`query doesn't match any entities`, query); // TODO
|
||||
}
|
||||
begin() {
|
||||
let state = this.scope.state = Object.assign({}, this.scope.state);
|
||||
@ -569,7 +567,8 @@ class ActionEval {
|
||||
const tag_re = /\{\{(.+?)\}\}/g;
|
||||
const label_re = /@(\w+)\b/g;
|
||||
|
||||
if (this.entities.length == 0 && this.action.select == 'if')
|
||||
const allowEmpty = ['if','foreach','join'];
|
||||
if (this.entities.length == 0 && allowEmpty.includes(this.action.select))
|
||||
return '';
|
||||
|
||||
let action = this.action;
|
||||
@ -581,10 +580,11 @@ class ActionEval {
|
||||
// TODO: detect cycles
|
||||
// TODO: "source"?
|
||||
// TODO: what if only 1 item?
|
||||
// TODO: what if join is subset of items?
|
||||
if (action.select == 'join' && this.jr) {
|
||||
let jentities = this.jr.entities;
|
||||
if (jentities.length == 0)
|
||||
throw new ECSError(`join query doesn't match any entities`, (action as ActionWithJoin).join); // TODO
|
||||
if (jentities.length == 0) return '';
|
||||
// TODO? throw new ECSError(`join query doesn't match any entities`, (action as ActionWithJoin).join); // TODO
|
||||
let joinfield = this.getJoinField(action, this.qr.atypes, this.jr.atypes);
|
||||
// TODO: what if only 1 item?
|
||||
// TODO: should be able to access fields via Y reg
|
||||
@ -801,6 +801,7 @@ export class EntityScope implements SourceLocated {
|
||||
childScopes: EntityScope[] = [];
|
||||
systems: System[] = [];
|
||||
entities: Entity[] = [];
|
||||
fieldtypes: { [name: string]: 'init' | 'const' } = {};
|
||||
bss = new DataSegment();
|
||||
rodata = new DataSegment();
|
||||
code = new CodeSegment();
|
||||
@ -1017,16 +1018,15 @@ export class EntityScope implements SourceLocated {
|
||||
setConstValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) {
|
||||
let c = this.em.singleComponentWithFieldName([{ etype: e.etype, cmatch: [component] }], fieldName, e);
|
||||
e.consts[mksymbol(component, fieldName)] = value;
|
||||
if (this.em.symbols[mksymbol(component, fieldName)] == 'init')
|
||||
throw new ECSError(`Can't mix const and init values for a component field`, e);
|
||||
this.em.symbols[mksymbol(component, fieldName)] = 'const';
|
||||
this.fieldtypes[mksymbol(component, fieldName)] = 'const';
|
||||
}
|
||||
setInitValue(e: Entity, component: ComponentType, fieldName: string, value: DataValue) {
|
||||
let c = this.em.singleComponentWithFieldName([{ etype: e.etype, cmatch: [component] }], fieldName, e);
|
||||
e.inits[mkscopesymbol(this, component, fieldName)] = value;
|
||||
if (this.em.symbols[mksymbol(component, fieldName)] == 'const')
|
||||
throw new ECSError(`Can't mix const and init values for a component field`, e);
|
||||
this.em.symbols[mksymbol(component, fieldName)] = 'init';
|
||||
this.fieldtypes[mksymbol(component, fieldName)] = 'init';
|
||||
}
|
||||
isConstOrInit(component: ComponentType, fieldName: string) : 'const' | 'init' {
|
||||
return this.fieldtypes[mksymbol(component, fieldName)];
|
||||
}
|
||||
generateCodeForEvent(event: string): string {
|
||||
// find systems that respond to event
|
||||
@ -1128,7 +1128,6 @@ export class EntityManager {
|
||||
components: { [name: string]: ComponentType } = {};
|
||||
systems: { [name: string]: System } = {};
|
||||
topScopes: { [name: string]: EntityScope } = {};
|
||||
symbols: { [name: string]: 'init' | 'const' } = {};
|
||||
event2systems: { [event: string]: System[] } = {};
|
||||
name2cfpairs: { [cfname: string]: ComponentFieldPair[] } = {};
|
||||
mainPath: string = '';
|
||||
|
@ -27,12 +27,14 @@ function parseCA65Listing(code: string, symbols, params, dbg: boolean) {
|
||||
var segMatch = /[.]segment\s+"(\w+)"/i;
|
||||
var lines = [];
|
||||
var linenum = 0;
|
||||
let curpath = '';
|
||||
// TODO: only does .c functions, not all .s files
|
||||
for (var line of code.split(re_crlf)) {
|
||||
var dbgm = dbgLineMatch.exec(line);
|
||||
if (dbgm && dbgm[1]) {
|
||||
var dbgtype = dbgm[4];
|
||||
offset = parseInt(dbgm[1], 16);
|
||||
curpath = dbgm[5];
|
||||
if (dbgtype == 'func') {
|
||||
var funcm = funcLineMatch.exec(dbgm[6]);
|
||||
if (funcm) {
|
||||
@ -45,9 +47,9 @@ function parseCA65Listing(code: string, symbols, params, dbg: boolean) {
|
||||
}
|
||||
}
|
||||
if (dbg && dbgm && dbgtype == 'line') {
|
||||
//console.log(dbgm[6], offset, segofs);
|
||||
//console.log(dbgm[5], dbgm[6], offset, segofs);
|
||||
lines.push({
|
||||
// TODO: sourcefile
|
||||
path: dbgm[5],
|
||||
line: parseInt(dbgm[6]),
|
||||
offset: offset + segofs,
|
||||
insns: null
|
||||
@ -65,6 +67,7 @@ function parseCA65Listing(code: string, symbols, params, dbg: boolean) {
|
||||
linenum--;
|
||||
} else if (!dbg) {
|
||||
lines.push({
|
||||
path: curpath,
|
||||
line: linenum,
|
||||
offset: offset + segofs,
|
||||
insns: insns,
|
||||
@ -219,6 +222,7 @@ export function linkLD65(step: BuildStep): BuildStepResult {
|
||||
var asmlines = []; // TODO: parseCA65Listing(lstout, symbolmap, params, false);
|
||||
var srclines = parseCA65Listing(lstout, symbolmap, params, true);
|
||||
putWorkFile(fn, lstout);
|
||||
// TODO: multiple source files
|
||||
// TODO: you have to get rid of all source lines to get asm listing
|
||||
listings[fn] = {
|
||||
asmlines: srclines.length ? asmlines : null,
|
||||
|
Loading…
Reference in New Issue
Block a user