From a425012b2b5826e4806bcd668be00926f87baa5a Mon Sep 17 00:00:00 2001 From: Steven Hugg Date: Wed, 16 Feb 2022 11:54:44 -0600 Subject: [PATCH] ecs: started w/ new IndexRegister --- src/common/ecs/ecs.ts | 110 ++++++++++++++++++++++++------------------ src/test/testecs.ts | 2 +- test/ecs/vcs1.txt | 60 ++++++----------------- test/ecs/vcslib.txt | 60 ++++++----------------- 4 files changed, 93 insertions(+), 139 deletions(-) diff --git a/src/common/ecs/ecs.ts b/src/common/ecs/ecs.ts index 0edc5e5f..eaae6441 100644 --- a/src/common/ecs/ecs.ts +++ b/src/common/ecs/ecs.ts @@ -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); } diff --git a/src/test/testecs.ts b/src/test/testecs.ts index 4b07d0cf..eb4af3ed 100644 --- a/src/test/testecs.ts +++ b/src/test/testecs.ts @@ -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}`); } }); diff --git a/test/ecs/vcs1.txt b/test/ecs/vcs1.txt index c13f7bb2..2f038c3f 100644 --- a/test/ecs/vcs1.txt +++ b/test/ecs/vcs1.txt @@ -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 diff --git a/test/ecs/vcslib.txt b/test/ecs/vcslib.txt index 38fa892b..c317ee78 100644 --- a/test/ecs/vcslib.txt +++ b/test/ecs/vcslib.txt @@ -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