ecs: started w/ new IndexRegister

This commit is contained in:
Steven Hugg 2022-02-16 11:54:44 -06:00
parent 3268925638
commit a425012b2b
4 changed files with 93 additions and 139 deletions

View File

@ -525,36 +525,43 @@ class IndexRegister {
entityCount() {
return this.ehi - this.elo + 1;
}
narrow(eset: EntitySet): IndexRegister {
let i = new IndexRegister(this.scope);
i.narrowInPlace(eset);
return i;
clone() {
return Object.assign(new IndexRegister(this.scope), this);
}
narrowInPlace(eset: EntitySet) {
if (this.scope != eset.scope) throw new ECSError(`scope mismatch`);
if (!eset.isContiguous()) throw new ECSError(`entities are not contiguous`);
let newelo = eset.entities[0].id;
let newehi = eset.entities[eset.entities.length - 1].id;
if (this.elo > newelo) throw new ECSError(`cannot narrow to new range, elo`);
if (this.ehi < newehi) throw new ECSError(`cannot narrow to new range, ehi`);
if (this.lo == null || this.hi == null) {
this.lo = 0;
this.hi = newehi - newelo + 1;
narrow(eset: EntitySet, action?: SourceLocated) {
let i = this.clone();
return i.narrowInPlace(eset, action) ? i : null;
}
narrowInPlace(eset: EntitySet, action?: SourceLocated): boolean {
if (this.scope != eset.scope) throw new ECSError(`scope mismatch`, action);
if (!eset.isContiguous()) throw new ECSError(`entities are not contiguous`, action);
if (this.eset) {
this.eset = this.eset.intersection(eset);
} else {
this.eset = eset;
}
if (this.eset.entities.length == 0) {
return false;
}
let newelo = this.eset.entities[0].id;
let newehi = this.eset.entities[this.eset.entities.length - 1].id;
if (this.lo === null || this.hi === null) {
this.lo = 0;
this.hi = newehi - newelo;
this.offset = 0;
} else {
if (action) console.log((action as any).event, this.offset, newelo, this.elo);
this.offset += newelo - this.elo;
}
this.elo = newelo;
this.ehi = newehi;
this.eset = eset;
if (action) console.log((action as any).event, this.offset, this.elo, this.ehi, newelo, newehi);
return true;
}
}
// todo: generalize
class ActionCPUState {
x: EntitySet | null = null;
y: EntitySet | null = null;
xofs: number = 0;
yofs: number = 0;
xreg: IndexRegister | null = null;
yreg: IndexRegister | null = null;
}
@ -602,35 +609,37 @@ class ActionEval {
// TODO: generalize to other cpus/langs
switch (this.action.select) {
case 'foreach':
if (state.x && state.y) throw new ECSError('no more index registers', this.action);
if (state.x) state.y = this.qr;
else state.x = this.qr;
if (state.xreg && state.yreg) throw new ECSError('no more index registers', this.action);
if (state.xreg) state.yreg = new IndexRegister(this.scope, this.qr);
else state.xreg = new IndexRegister(this.scope, this.qr);
break;
case 'join':
if (state.x || state.y) throw new ECSError('no free index registers for join', this.action);
if (state.xreg || state.yreg) throw new ECSError('no free index registers for join', this.action);
this.jr = new EntitySet(this.scope, (this.action as ActionWithJoin).join);
state.y = this.qr;
state.x = this.jr;
state.xreg = new IndexRegister(this.scope, this.jr);
state.yreg = new IndexRegister(this.scope, this.qr);
break;
case 'if':
case 'with':
// TODO: what if not in X because 1 element?
if (state.x) {
let int = state.x.intersection(this.qr);
if (int.entities.length == 0) {
if (this.action.select == 'with')
throw new ECSError('no entities match this query', this.action);
else
break;
if (state.xreg && state.xreg.eset) {
state.xreg = state.xreg.narrow(this.qr, this.action);
if (state.xreg == null || state.xreg.eset?.entities == null) {
if (this.action.select == 'if') {
this.entities = [];
break; // "if" failed
} else {
throw new ECSError(`no entities in statement`, this.action);
}
} else {
let indofs = int.entities[0].id - state.x.entities[0].id;
state.xofs += indofs; // TODO: should merge with filter
state.x = int;
this.entities = int.entities; // TODO?
this.entities = state.xreg.eset.entities; // TODO?
}
} else if (this.action.select == 'with') {
if (this.instance.params.refEntity && this.instance.params.refField) {
state.x = this.qr;
if (state.xreg)
state.xreg.eset = this.qr;
else
state.xreg = new IndexRegister(this.scope, this.qr);
// ???
} else if (this.qr.entities.length != 1)
throw new ECSError(`${this.instance.system.name} query outside of loop must match exactly one entity`, this.action); //TODO
@ -701,8 +710,9 @@ class ActionEval {
props['%ehi'] = entities[entities.length - 1].id.toString();
props['%ecount'] = entities.length.toString();
props['%efullcount'] = fullEntityCount.toString();
props['%xofs'] = this.scope.state.xofs.toString();
props['%yofs'] = this.scope.state.yofs.toString();
// TODO
props['%xofs'] = (this.scope.state.xreg?.offset || 0).toString();
props['%yofs'] = (this.scope.state.yreg?.offset || 0).toString();
}
// replace @labels
code = code.replace(label_re, (s: string, a: string) => `${label}__${a}`);
@ -806,7 +816,7 @@ class ActionEval {
wrapCodeInFilter(code: string) {
// TODO: :-p
const ents = this.entities;
const ents2 = this.oldState.x?.entities;
const ents2 = this.oldState.xreg?.eset?.entities;
if (ents && ents2) {
let lo = ents[0].id;
let hi = ents[ents.length - 1].id;
@ -892,20 +902,24 @@ class ActionEval {
return this.dialect.absolute(ident, eidofs);
} else {
let ir;
if (this.scope.state.x?.intersection(qr)) {
ir = this.scope.state.x;
eidofs -= this.scope.state.xofs;
let int;
let xreg = this.scope.state.xreg;
let yreg = this.scope.state.yreg;
if (xreg && (int = xreg.eset?.intersection(qr))) {
//console.log('x',qr.entities[0].id,xreg.elo,int.entities[0].id,xreg.offset);
ir = xreg.eset;
eidofs -= xreg.offset;
}
else if (this.scope.state.y?.intersection(qr)) {
ir = this.scope.state.y;
eidofs -= this.scope.state.yofs;
else if (yreg && (int = yreg.eset?.intersection(qr))) {
ir = yreg.eset;
eidofs -= yreg.offset;
}
if (!ir) throw new ECSError(`no intersection for index register`, action);
if (ir.entities.length == 0) throw new ECSError(`no common entities for index register`, action);
if (!ir.isContiguous()) throw new ECSError(`entities in query are not contiguous`, action);
if (ir == this.scope.state.x)
if (ir == this.scope.state.xreg?.eset)
return this.dialect.indexed_x(ident, eidofs);
if (ir == this.scope.state.y)
if (ir == this.scope.state.yreg?.eset)
return this.dialect.indexed_y(ident, eidofs);
throw new ECSError(`cannot find "${component.name}:${field.name}" in state`, action);
}

View File

@ -106,7 +106,7 @@ describe('Compiler', function() {
if (outtxt.trim() != goodtxt.trim()) {
let asmpath = '/tmp/' + asmfn;
writeFileSync(asmpath, outtxt, 'utf-8');
console.log(spawnSync('/usr/bin/diff', [asmpath, goodpath], {encoding:'utf-8'}).stdout);
console.log(spawnSync('/usr/bin/diff', [goodpath, asmpath], {encoding:'utf-8'}).stdout);
throw new Error(`files different; to fix: cp ${asmpath} ${goodpath}`);
}
});

View File

@ -82,40 +82,10 @@ FrameLoop__start__2__NextFrame:
;;; start action StaticKernel 4 kernelsetup
cpx #0+2
jcs StaticKernel__kernelsetup__5____skipxhi
cpx #0
jcc StaticKernel__kernelsetup__5____skipxlo
lda PFColor_pfcolor_b0,x
sta COLUPF
StaticKernel__kernelsetup__5____skipxlo:
StaticKernel__kernelsetup__5____skipxhi:
;;; end action StaticKernel 4 kernelsetup
;;; start action StaticKernel 4 kernelsetup
cpx #0+4
jcs StaticKernel__kernelsetup__6____skipxhi
cpx #0
jcc StaticKernel__kernelsetup__6____skipxlo
lda Playfield_pf_b0,x
sta PF0
lda Playfield_pf_b8,x
sta PF1
lda Playfield_pf_b16,x
sta PF2
StaticKernel__kernelsetup__6____skipxlo:
StaticKernel__kernelsetup__6____skipxhi:
;;; end action StaticKernel 4 kernelsetup
@ -127,7 +97,7 @@ StaticKernel__kernelsetup__6____skipxhi:
;;; start action StaticKernel 4 kernel
ldx #0
StaticKernel__kernel__7____each:
StaticKernel__kernel__5____each:
sta WSYNC
.code
@ -142,24 +112,24 @@ StaticKernel__kernel__7____each:
;;; start action StaticKernel 4 kernelsetup
cpx #5+2
jcs StaticKernel__kernelsetup__9____skipxhi
jcs StaticKernel__kernelsetup__7____skipxhi
cpx #5
jcc StaticKernel__kernelsetup__9____skipxlo
jcc StaticKernel__kernelsetup__7____skipxlo
lda PFColor_pfcolor_b0-5,x
sta COLUPF
StaticKernel__kernelsetup__9____skipxlo:
StaticKernel__kernelsetup__7____skipxlo:
StaticKernel__kernelsetup__9____skipxhi:
StaticKernel__kernelsetup__7____skipxhi:
;;; end action StaticKernel 4 kernelsetup
;;; start action StaticKernel 4 kernelsetup
cpx #4
jcc StaticKernel__kernelsetup__10____skipxlo
jcc StaticKernel__kernelsetup__8____skipxlo
lda Playfield_pf_b0-4,x
sta PF0
@ -168,22 +138,22 @@ StaticKernel__kernelsetup__9____skipxhi:
lda Playfield_pf_b16-4,x
sta PF2
StaticKernel__kernelsetup__10____skipxlo:
StaticKernel__kernelsetup__8____skipxlo:
;;; end action StaticKernel 4 kernelsetup
ldy KernelSection_lines_b0,x
StaticKernel__kernel__7__loop:
StaticKernel__kernel__5__loop:
sta WSYNC
dey
bne StaticKernel__kernel__7__loop
bne StaticKernel__kernel__5__loop
inx
cpx #8
jne StaticKernel__kernel__7____each
StaticKernel__kernel__7____exit:
jne StaticKernel__kernel__5____each
StaticKernel__kernel__5____exit:
;;; end action StaticKernel 4 kernel
@ -193,7 +163,7 @@ StaticKernel__kernel__7____exit:
;;; start action JoyButton 5 postframe
lda INPT4 ;read button input
bmi JoyButton__postframe__11__NotPressed
bmi JoyButton__postframe__9__NotPressed
.code
;;; start action Local 6 joybutton
@ -203,7 +173,7 @@ StaticKernel__kernel__7____exit:
;;; end action Local 6 joybutton
JoyButton__postframe__11__NotPressed:
JoyButton__postframe__9__NotPressed:
;;; end action JoyButton 5 postframe
@ -213,7 +183,7 @@ JoyButton__postframe__11__NotPressed:
;;; start action ResetSwitch 2 nextframe
lsr SWCHB ; test Game Reset switch
bcs ResetSwitch__nextframe__13__NoStart
bcs ResetSwitch__nextframe__11__NoStart
.code
;;; start action ResetConsole 3 resetswitch
@ -222,7 +192,7 @@ JoyButton__postframe__11__NotPressed:
;;; end action ResetConsole 3 resetswitch
ResetSwitch__nextframe__13__NoStart:
ResetSwitch__nextframe__11__NoStart:
;;; end action ResetSwitch 2 nextframe

View File

@ -83,40 +83,10 @@ FrameLoop__start__2__NextFrame:
;;; start action StaticKernel 4 kernelsetup
cpx #0+2
jcs StaticKernel__kernelsetup__5____skipxhi
cpx #0
jcc StaticKernel__kernelsetup__5____skipxlo
lda PFColor_pfcolor_b0,x
sta COLUPF
StaticKernel__kernelsetup__5____skipxlo:
StaticKernel__kernelsetup__5____skipxhi:
;;; end action StaticKernel 4 kernelsetup
;;; start action StaticKernel 4 kernelsetup
cpx #0+4
jcs StaticKernel__kernelsetup__6____skipxhi
cpx #0
jcc StaticKernel__kernelsetup__6____skipxlo
lda Playfield_pf_b0,x
sta PF0
lda Playfield_pf_b8,x
sta PF1
lda Playfield_pf_b16,x
sta PF2
StaticKernel__kernelsetup__6____skipxlo:
StaticKernel__kernelsetup__6____skipxhi:
;;; end action StaticKernel 4 kernelsetup
@ -128,7 +98,7 @@ StaticKernel__kernelsetup__6____skipxhi:
;;; start action StaticKernel 4 kernel
ldx #0
StaticKernel__kernel__7____each:
StaticKernel__kernel__5____each:
sta WSYNC
.code
@ -143,24 +113,24 @@ StaticKernel__kernel__7____each:
;;; start action StaticKernel 4 kernelsetup
cpx #5+2
jcs StaticKernel__kernelsetup__9____skipxhi
jcs StaticKernel__kernelsetup__7____skipxhi
cpx #5
jcc StaticKernel__kernelsetup__9____skipxlo
jcc StaticKernel__kernelsetup__7____skipxlo
lda PFColor_pfcolor_b0-5,x
sta COLUPF
StaticKernel__kernelsetup__9____skipxlo:
StaticKernel__kernelsetup__7____skipxlo:
StaticKernel__kernelsetup__9____skipxhi:
StaticKernel__kernelsetup__7____skipxhi:
;;; end action StaticKernel 4 kernelsetup
;;; start action StaticKernel 4 kernelsetup
cpx #4
jcc StaticKernel__kernelsetup__10____skipxlo
jcc StaticKernel__kernelsetup__8____skipxlo
lda Playfield_pf_b0-4,x
sta PF0
@ -169,7 +139,7 @@ StaticKernel__kernelsetup__9____skipxhi:
lda Playfield_pf_b16-4,x
sta PF2
StaticKernel__kernelsetup__10____skipxlo:
StaticKernel__kernelsetup__8____skipxlo:
;;; end action StaticKernel 4 kernelsetup
@ -178,11 +148,11 @@ StaticKernel__kernelsetup__10____skipxlo:
;;; start action StaticKernel 4 kerneldraw
ldy KernelSection_lines_b0,x
StaticKernel__kerneldraw__11__loop:
StaticKernel__kerneldraw__9__loop:
sta WSYNC
dey
bne StaticKernel__kerneldraw__11__loop
bne StaticKernel__kerneldraw__9__loop
;;; end action StaticKernel 4 kerneldraw
@ -190,8 +160,8 @@ StaticKernel__kerneldraw__11__loop:
inx
cpx #8
jne StaticKernel__kernel__7____each
StaticKernel__kernel__7____exit:
jne StaticKernel__kernel__5____each
StaticKernel__kernel__5____exit:
;;; end action StaticKernel 4 kernel
@ -201,7 +171,7 @@ StaticKernel__kernel__7____exit:
;;; start action JoyButton 5 postframe
lda INPT4 ;read button input
bmi JoyButton__postframe__12__NotPressed
bmi JoyButton__postframe__10__NotPressed
.code
;;; start action Local 6 joybutton
@ -211,7 +181,7 @@ StaticKernel__kernel__7____exit:
;;; end action Local 6 joybutton
JoyButton__postframe__12__NotPressed:
JoyButton__postframe__10__NotPressed:
;;; end action JoyButton 5 postframe
@ -221,7 +191,7 @@ JoyButton__postframe__12__NotPressed:
;;; start action ResetSwitch 2 nextframe
lsr SWCHB ; test Game Reset switch
bcs ResetSwitch__nextframe__14__NoStart
bcs ResetSwitch__nextframe__12__NoStart
.code
;;; start action ResetConsole 3 resetswitch
@ -230,7 +200,7 @@ JoyButton__postframe__12__NotPressed:
;;; end action ResetConsole 3 resetswitch
ResetSwitch__nextframe__14__NoStart:
ResetSwitch__nextframe__12__NoStart:
;;; end action ResetSwitch 2 nextframe