ecs: asc desc

This commit is contained in:
Steven Hugg 2022-02-08 06:18:28 -06:00
parent 2dfe65932b
commit dda51c3467
2 changed files with 41 additions and 18 deletions

View File

@ -2,7 +2,7 @@
import { mergeLocs, Tokenizer, TokenType } from "../tokenizer";
import { SourceLocated } from "../workertypes";
import { newDecoder } from "./decoder";
import { Action, ArrayType, ComponentType, DataField, DataType, DataValue, ECSError, Entity, EntityArchetype, EntityManager, EntityScope, IntType, Query, RefType, SelectType, SELECT_TYPE, SourceFileExport, System } from "./ecs";
import { Action, ActionWithJoin, ArrayType, ComponentType, DataField, DataType, DataValue, ECSError, Entity, EntityArchetype, EntityManager, EntityScope, IntType, Query, RefType, SelectType, SELECT_TYPE, SourceFileExport, System } from "./ecs";
export enum ECSTokenType {
Ellipsis = 'ellipsis',
@ -224,13 +224,16 @@ export class ECSCompiler extends Tokenizer {
parseAction(): Action {
// TODO: unused events?
let event = this.expectIdent().str;
const event = this.expectIdent().str;
this.expectToken('do');
let select = this.expectTokens(SELECT_TYPE).str as SelectType; // TODO: type check?
const all_modifiers = ['cyclecritical','asc','desc']; // TODO
const modifiers = this.parseModifiers(all_modifiers);
// TODO: include modifiers in error msg
const select = this.expectTokens(SELECT_TYPE).str as SelectType; // TODO: type check?
let query = undefined;
let join = undefined;
if (select == 'once') {
if (this.peekToken().str == '[') this.compileError(`A "${select}" query can't include a query.`)
if (this.peekToken().str == '[') this.compileError(`A "${select}" action can't include a query.`)
} else {
query = this.parseQuery();
}
@ -242,12 +245,12 @@ export class ECSCompiler extends Tokenizer {
if (!query) { this.compileError(`A "${select}" query can't include a limit.`); }
else query.limit = this.expectInteger();
}
if (this.ifToken('cyclecritical')) {
// TODO
}
let text = this.parseCode();
let action = { text, event, query, join, select };
return action as Action;
let direction = undefined;
if (modifiers['asc']) direction = 'asc';
else if (modifiers['desc']) direction = 'desc';
let action = { text, event, query, join, select, direction };
return action as ActionWithJoin;
}
parseQuery() {

View File

@ -59,8 +59,6 @@ how to avoid cycle crossing for critical code and data?
*/
import { data } from "jquery";
import { SourceLocated, SourceLocation } from "../workertypes";
export class ECSError extends Error {
@ -132,6 +130,7 @@ export interface ActionOnce extends ActionBase {
export interface ActionWithQuery extends ActionBase {
select: 'foreach' | 'join' | 'with' | 'if' | 'select'
query: Query
direction?: 'asc' | 'desc'
}
export interface ActionWithJoin extends ActionWithQuery {
@ -191,7 +190,7 @@ interface ComponentFieldPair {
export class Dialect_CA65 {
ASM_ITERATE_EACH = `
ASM_ITERATE_EACH_ASC = `
ldx #0
@__each:
{{%code}}
@ -201,7 +200,16 @@ export class Dialect_CA65 {
@__exit:
`;
ASM_ITERATE_JOIN = `
ASM_ITERATE_EACH_DESC = `
ldx #{{%ecount}}-1
@__each:
{{%code}}
dex
bpl @__each
@__exit:
`;
ASM_ITERATE_JOIN_ASC = `
ldy #0
@__each:
ldx {{%joinfield}},y
@ -210,6 +218,16 @@ export class Dialect_CA65 {
cpy #{{%ecount}}
bne @__each
@__exit:
`;
ASM_ITERATE_JOIN_DESC = `
ldy #{{%ecount}}-1
@__each:
ldx {{%joinfield}},y
{{%code}}
dey
bpl @__each
@__exit:
`;
ASM_FILTER_RANGE_LO_X = `
@ -490,8 +508,8 @@ class ActionCPUState {
}
class ActionEval {
em;
dialect;
em : EntityManager;
dialect : Dialect_CA65;
qr: EntitySet;
jr: EntitySet | undefined;
oldState : ActionCPUState;
@ -675,12 +693,14 @@ class ActionEval {
__bss_init(args: string[]) {
return this.scope.allocateInitData(this.scope.bss);
}
wrapCodeInLoop(code: string, action: Action, ents: Entity[], joinfield?: ComponentFieldPair): string {
wrapCodeInLoop(code: string, action: ActionWithQuery, ents: Entity[], joinfield?: ComponentFieldPair): string {
// TODO: check ents
// TODO: check segment bounds
// TODO: what if 0 or 1 entitites?
let s = this.dialect.ASM_ITERATE_EACH;
if (joinfield) s = this.dialect.ASM_ITERATE_JOIN;
// TODO: check > 127 or > 255
let dir = action.direction;
let s = dir == 'desc' ? this.dialect.ASM_ITERATE_EACH_DESC : this.dialect.ASM_ITERATE_EACH_ASC;
if (joinfield) s = dir == 'desc' ? this.dialect.ASM_ITERATE_JOIN_DESC : this.dialect.ASM_ITERATE_JOIN_ASC;
s = s.replace('{{%code}}', code);
return s;
}