mirror of
https://github.com/sehugg/8bitworkshop.git
synced 2024-11-25 18:33:11 +00:00
ecs: baseoffset
This commit is contained in:
parent
1f64a623aa
commit
3a77e31e47
@ -1,7 +1,7 @@
|
||||
|
||||
import { mergeLocs, Tokenizer, TokenType } from "../tokenizer";
|
||||
import { SourceLocated } from "../workertypes";
|
||||
import { Action, ArrayType, ComponentType, DataField, DataType, DataValue, Entity, EntityArchetype, EntityManager, EntityScope, IntType, Query, RefType, SelectType, SourceFileExport, System } from "./ecs";
|
||||
import { Action, ArrayType, ComponentType, DataField, DataType, DataValue, ECSError, Entity, EntityArchetype, EntityManager, EntityScope, IntType, Query, RefType, SelectType, SourceFileExport, System } from "./ecs";
|
||||
|
||||
export enum ECSTokenType {
|
||||
Ellipsis = 'ellipsis',
|
||||
@ -129,14 +129,18 @@ export class ECSCompiler extends Tokenizer {
|
||||
if (this.peekToken().str == '[') {
|
||||
return { dtype: 'ref', query: this.parseQuery() } as RefType;
|
||||
}
|
||||
if (this.peekToken().str == 'array') {
|
||||
if (this.ifToken('array')) {
|
||||
let index : IntType | undefined = undefined;
|
||||
this.expectToken('array');
|
||||
if (this.peekToken().type == ECSTokenType.Integer) {
|
||||
index = this.parseDataType() as IntType;
|
||||
}
|
||||
this.expectToken('of');
|
||||
return { dtype: 'array', index, elem: this.parseDataType() } as ArrayType;
|
||||
let elem = this.parseDataType();
|
||||
let baseoffset;
|
||||
if (this.ifToken('baseoffset')) {
|
||||
baseoffset = this.expectInteger();
|
||||
}
|
||||
return { dtype: 'array', index, elem, baseoffset } as ArrayType;
|
||||
}
|
||||
this.internalError(); throw new Error();
|
||||
}
|
||||
|
@ -58,6 +58,7 @@ how to avoid cycle crossing for critical code and data?
|
||||
*/
|
||||
|
||||
|
||||
import { data } from "jquery";
|
||||
import { SourceLocated, SourceLocation } from "../workertypes";
|
||||
|
||||
export class ECSError extends Error {
|
||||
@ -153,6 +154,7 @@ export interface ArrayType {
|
||||
dtype: 'array'
|
||||
elem: DataType
|
||||
index?: DataType
|
||||
baseoffset?: number
|
||||
}
|
||||
|
||||
export interface RefType {
|
||||
@ -651,8 +653,18 @@ class ActionEval {
|
||||
let bitofs = parseInt(args[1] || '0');
|
||||
return this.generateCodeForField(fieldName, bitofs, canwrite);
|
||||
}
|
||||
__base(args: string[]) {
|
||||
// TODO: refactor into generateCode..
|
||||
let fieldName = args[0];
|
||||
let bitofs = parseInt(args[1] || '0');
|
||||
let component = this.em.singleComponentWithFieldName(this.qr.atypes, fieldName, this.action);
|
||||
let field = component.fields.find(f => f.name == fieldName);
|
||||
if (field == null) throw new ECSError(`no field named "${fieldName}" in component`, this.action);
|
||||
return this.dialect.fieldsymbol(component, field, bitofs);
|
||||
}
|
||||
__index(args: string[]) {
|
||||
let ident = args[0]; // TODO?
|
||||
// TODO: check select type and if we actually have an index...
|
||||
let ident = args[0];
|
||||
if (this.entities.length == 1) {
|
||||
return this.dialect.absolute(ident);
|
||||
} else {
|
||||
@ -727,6 +739,7 @@ class ActionEval {
|
||||
// find archetypes
|
||||
let field = component.fields.find(f => f.name == fieldName);
|
||||
if (field == null) throw new ECSError(`no field named "${fieldName}" in component`, action);
|
||||
let ident = this.dialect.fieldsymbol(component, field, bitofs);
|
||||
// see if all entities have the same constant value
|
||||
// TODO: should be done somewhere else?
|
||||
let constValues = new Set<DataValue>();
|
||||
@ -753,7 +766,6 @@ class ActionEval {
|
||||
let range = this.scope.bss.getFieldRange(component, fieldName) || this.scope.rodata.getFieldRange(component, fieldName);
|
||||
if (!range) throw new ECSError(`couldn't find field for ${component.name}:${fieldName}, maybe no entities?`); // TODO
|
||||
// TODO: dialect
|
||||
let ident = this.dialect.fieldsymbol(component, field, bitofs);
|
||||
let eidofs = qr.entities.length && qr.entities[0].id - range.elo; // TODO: negative?
|
||||
if (baseLookup) {
|
||||
return this.dialect.absolute(ident);
|
||||
@ -940,24 +952,27 @@ export class EntityScope implements SourceLocated {
|
||||
// is it a bounded array? (TODO)
|
||||
if (f.dtype == 'array' && f.index) {
|
||||
let datasym = this.dialect.datasymbol(c, f, e.id);
|
||||
let offset = this.bss.allocateBytes(datasym, getFieldLength(f.index));
|
||||
let databytes = getFieldLength(f.index);
|
||||
let offset = this.bss.allocateBytes(datasym, databytes);
|
||||
let ptrlosym = this.dialect.fieldsymbol(c, f, 0);
|
||||
let ptrhisym = this.dialect.fieldsymbol(c, f, 8);
|
||||
let loofs = segment.allocateBytes(ptrlosym, entcount);
|
||||
let hiofs = segment.allocateBytes(ptrhisym, entcount);
|
||||
if (f.baseoffset) datasym = `(${datasym}+${f.baseoffset})`;
|
||||
segment.initdata[loofs + e.id - range.elo] = { symbol: datasym, bitofs: 0 };
|
||||
segment.initdata[hiofs + e.id - range.elo] = { symbol: datasym, bitofs: 8 };
|
||||
}
|
||||
} else {
|
||||
// this is a constant
|
||||
// is it a byte array?
|
||||
if (v instanceof Uint8Array) {
|
||||
if (v instanceof Uint8Array && f.dtype == 'array') {
|
||||
let datasym = this.dialect.datasymbol(c, f, e.id);
|
||||
segment.allocateInitData(datasym, v);
|
||||
let ptrlosym = this.dialect.fieldsymbol(c, f, 0);
|
||||
let ptrhisym = this.dialect.fieldsymbol(c, f, 8);
|
||||
let loofs = segment.allocateBytes(ptrlosym, entcount);
|
||||
let hiofs = segment.allocateBytes(ptrhisym, entcount);
|
||||
if (f.baseoffset) datasym = `(${datasym}+${f.baseoffset})`;
|
||||
segment.initdata[loofs + e.id - range.elo] = { symbol: datasym, bitofs: 0 };
|
||||
segment.initdata[hiofs + e.id - range.elo] = { symbol: datasym, bitofs: 8 };
|
||||
// TODO: } else if (v instanceof Uint16Array) {
|
||||
|
@ -160,6 +160,9 @@ export class Tokenizer {
|
||||
let tok = this.lasttoken = (this.tokens.shift() || this.eof);
|
||||
return tok;
|
||||
}
|
||||
ifToken(match: string): Token | undefined {
|
||||
if (this.peekToken().str == match) return this.consumeToken();
|
||||
}
|
||||
expectToken(str: string, msg?: string): Token {
|
||||
let tok = this.consumeToken();
|
||||
let tokstr = tok.str;
|
||||
|
Loading…
Reference in New Issue
Block a user