1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-08 08:33:32 +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',
'const', 'init', 'locals',
'on', 'do', 'emit', 'limit',
'once', 'foreach', 'with', 'join'
'once', 'foreach', 'with', 'join', 'if',
];
var keywords_list = [
'processor',
'byte', 'word', 'long',
'include', 'seg', 'dc', 'ds', 'dv', 'hex', 'err', 'org', 'rorg', 'echo', 'rend',
'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();

View File

@ -212,7 +212,7 @@ export class ECSCompiler extends Tokenizer {
let event = this.expectIdent().str;
this.expectToken('do');
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 join = undefined;
if (select != 'once') {

View File

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