1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-05-28 08:41:30 +00:00

ecs: no error if select is empty

This commit is contained in:
Steven Hugg 2022-02-03 19:38:35 -06:00
parent 513fb85b8e
commit dbc84c94b2
3 changed files with 23 additions and 18 deletions

View File

@ -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);
}

View File

@ -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 = '';

View File

@ -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,