1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-26 06:29:29 +00:00

ecs: with/if

This commit is contained in:
Steven Hugg 2022-02-03 09:24:00 -06:00
parent a7f708a303
commit bc3b2cd81d
3 changed files with 22 additions and 11 deletions

View File

@ -20,14 +20,14 @@
'end', 'component', 'system', 'entity', 'scope', 'using', 'demo', 'end', 'component', 'system', 'entity', 'scope', 'using', 'demo',
'const', 'init', 'locals', 'const', 'init', 'locals',
'on', 'do', 'emit', 'limit', 'on', 'do', 'emit', 'limit',
'once', 'foreach', 'with', 'join' 'once', 'foreach', 'with', 'join', 'if',
]; ];
var keywords_list = [ var keywords_list = [
'processor', 'processor',
'byte', 'word', 'long', 'byte', 'word', 'long',
'include', 'seg', 'dc', 'ds', 'dv', 'hex', 'err', 'org', 'rorg', 'echo', 'rend', 'include', 'seg', 'dc', 'ds', 'dv', 'hex', 'err', 'org', 'rorg', 'echo', 'rend',
'align', 'subroutine', 'equ', 'eqm', 'set', 'mac', 'endm', 'mexit', 'ifconst', 'align', 'subroutine', 'equ', 'eqm', 'set', 'mac', 'endm', 'mexit', 'ifconst',
'ifnconst', 'if', 'else', 'endif', 'eif', 'repeat', 'repend' 'ifnconst', 'else', 'endif', 'eif', 'repeat', 'repend'
]; ];
var directives = new Map(); var directives = new Map();

View File

@ -212,7 +212,7 @@ export class ECSCompiler extends Tokenizer {
let event = this.expectIdent().str; let event = this.expectIdent().str;
this.expectToken('do'); this.expectToken('do');
let select = this.expectTokens( let select = this.expectTokens(
['once', 'foreach', 'join', 'with', 'select']).str as SelectType; // TODO: type check? ['once', 'foreach', 'join', 'with', 'if', 'select']).str as SelectType; // TODO: type check?
let query = undefined; let query = undefined;
let join = undefined; let join = undefined;
if (select != 'once') { if (select != 'once') {

View File

@ -111,7 +111,7 @@ export interface System extends SourceLocated {
tempbytes?: number; tempbytes?: number;
} }
export type SelectType = 'once' | 'foreach' | 'join' | 'with' | 'select'; export type SelectType = 'once' | 'foreach' | 'join' | 'with' | 'if' | 'select';
export interface ActionBase extends SourceLocated { export interface ActionBase extends SourceLocated {
select: SelectType; select: SelectType;
@ -125,7 +125,7 @@ export interface ActionOnce extends ActionBase {
} }
export interface ActionWithQuery extends ActionBase { export interface ActionWithQuery extends ActionBase {
select: 'foreach' | 'join' | 'with' | 'select' select: 'foreach' | 'join' | 'with' | 'if' | 'select'
query: Query query: Query
limit?: number limit?: number
} }
@ -529,14 +529,20 @@ class ActionEval {
this.jr = new QueryResult(this.scope, (this.action as ActionWithJoin).join); this.jr = new QueryResult(this.scope, (this.action as ActionWithJoin).join);
state.x = this.jr; state.x = this.jr;
break; break;
case 'if':
case 'with': case 'with':
if (state.x) { if (state.x) {
let int = state.x.intersection(this.qr); let int = state.x.intersection(this.qr);
// TODO: what if we filter 0 entities? if (int.entities.length == 0) {
if (int.entities.length == 0) throw new ECSError('queries do not intersect', this.action); if (this.action.select == 'with')
let indofs = int.entities[0].id - state.x.entities[0].id; throw new ECSError('queries do not intersect', this.action);
state.xofs += indofs; // TODO: should merge with filter else
state.x = int; break;
} else {
let indofs = int.entities[0].id - state.x.entities[0].id;
state.xofs += indofs; // TODO: should merge with filter
state.x = int;
}
} else { } else {
if (this.qr.entities.length != 1) if (this.qr.entities.length != 1)
throw new ECSError(`query outside of loop must match exactly one entity`, this.action); throw new ECSError(`query outside of loop must match exactly one entity`, this.action);
@ -566,7 +572,7 @@ class ActionEval {
if (action.select == 'join' && this.jr) { if (action.select == 'join' && this.jr) {
let jentities = this.jr.entities; let jentities = this.jr.entities;
if (jentities.length == 0) if (jentities.length == 0)
throw new ECSError(`join query doesn't match any entities`, action); // 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); let joinfield = this.getJoinField(action, this.qr.atypes, this.jr.atypes);
// TODO: what if only 1 item? // TODO: what if only 1 item?
// TODO: should be able to access fields via Y reg // TODO: should be able to access fields via Y reg
@ -580,6 +586,8 @@ class ActionEval {
if (action.limit) { if (action.limit) {
entities = entities.slice(0, action.limit); entities = entities.slice(0, action.limit);
} }
if (entities.length == 0 && action.select == 'if')
return '';
if (entities.length == 0) if (entities.length == 0)
throw new ECSError(`query doesn't match any entities`, action.query); // TODO throw new ECSError(`query doesn't match any entities`, action.query); // TODO
this.qr.entities = entities; this.qr.entities = entities;
@ -587,6 +595,9 @@ class ActionEval {
if (action.select == 'with' && entities.length > 1) { if (action.select == 'with' && entities.length > 1) {
code = this.wrapCodeInFilter(code); code = this.wrapCodeInFilter(code);
} }
if (action.select == 'if' && entities.length > 1) {
code = this.wrapCodeInFilter(code);
}
// define properties // define properties
props['%elo'] = entities[0].id.toString(); props['%elo'] = entities[0].id.toString();
props['%ehi'] = entities[entities.length - 1].id.toString(); props['%ehi'] = entities[entities.length - 1].id.toString();