1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-11-29 14:51:17 +00:00

ecs: scoping, start labels, subscopes (need unions for data)

This commit is contained in:
Steven Hugg 2022-02-02 17:03:22 -06:00
parent b28a4b5be4
commit 83238f30f1
2 changed files with 33 additions and 11 deletions

View File

@ -255,13 +255,16 @@ export class ECSCompiler extends Tokenizer {
let scope = this.em.newScope(name, this.currentScope || undefined); let scope = this.em.newScope(name, this.currentScope || undefined);
this.currentScope = scope; this.currentScope = scope;
let cmd; let cmd;
while ((cmd = this.expectTokens(['using', 'entity', 'comment', 'end']).str) != 'end') { while ((cmd = this.expectTokens(['using', 'entity', 'scope', 'comment', 'end']).str) != 'end') {
if (cmd == 'using') { if (cmd == 'using') {
this.parseScopeUsing(); this.parseScopeUsing();
} }
if (cmd == 'entity') { if (cmd == 'entity') {
this.annotate(() => this.parseEntity()); this.annotate(() => this.parseEntity());
} }
if (cmd == 'scope') {
this.annotate(() => this.parseScope());
}
if (cmd == 'comment') { if (cmd == 'comment') {
this.expectTokenTypes([ECSTokenType.CodeFragment]); this.expectTokenTypes([ECSTokenType.CodeFragment]);
} }

View File

@ -56,6 +56,7 @@ crazy idea -- full expansion, then relooper
*/ */
import { throws } from "assert";
import { SourceLocated, SourceLocation } from "../workertypes"; import { SourceLocated, SourceLocation } from "../workertypes";
export class ECSError extends Error { export class ECSError extends Error {
@ -230,16 +231,19 @@ export class Dialect_CA65 {
` `
readonly HEADER = ` readonly HEADER = `
.include "vcs-ca65.h" .include "vcs-ca65.h"
.define PAL 0
.code .code
` `
readonly FOOTER = ` readonly FOOTER = `
.segment "VECTORS" .segment "VECTORS"
VecNMI: .word Start VecNMI: .word Main::__NMI
VecReset: .word Start VecReset: .word Main::__Reset
VecBRK: .word Start VecBRK: .word Main::__BRK
` `
readonly TEMPLATE_INIT_MAIN = ` readonly TEMPLATE_INIT_MAIN = `
Start: __NMI:
__Reset:
__BRK:
CLEAN_START CLEAN_START
` `
@ -313,6 +317,14 @@ export class SourceFileExport {
debug_line(path: string, line: number) { debug_line(path: string, line: number) {
this.lines.push(` .dbg line, "${path}", ${line}`); this.lines.push(` .dbg line, "${path}", ${line}`);
} }
startScope(name: string) {
this.lines.push(` .scope ${name}`)
}
endScope(name: string) {
this.lines.push(` .endscope`)
this.lines.push(`${name}__Start = ${name}::__Start`)
// TODO: scope__start = scope::start
}
toString() { toString() {
return this.lines.join('\n'); return this.lines.join('\n');
} }
@ -1003,13 +1015,22 @@ export class EntityScope implements SourceLocated {
} }
} }
dump(file: SourceFileExport) { dump(file: SourceFileExport) {
this.analyzeEntities();
this.generateCode();
file.startScope(this.name);
file.segment(`${this.name}_DATA`, 'bss'); file.segment(`${this.name}_DATA`, 'bss');
if (this.maxTempBytes) this.bss.allocateBytes('TEMP', this.maxTempBytes); if (this.maxTempBytes) this.bss.allocateBytes('TEMP', this.maxTempBytes);
this.bss.dump(file); this.bss.dump(file);
file.segment(`${this.name}_RODATA`, 'rodata'); file.segment(`${this.name}_RODATA`, 'rodata');
this.rodata.dump(file); this.rodata.dump(file);
//file.segment(`${this.name}_CODE`, 'code'); //file.segment(`${this.name}_CODE`, 'code');
file.label('__Start');
this.code.dump(file); this.code.dump(file);
for (let subscope of this.childScopes) {
// TODO: overlay child BSS segments
subscope.dump(file);
}
file.endScope(this.name);
} }
} }
@ -1017,7 +1038,7 @@ export class EntityManager {
archetypes: { [key: string]: EntityArchetype } = {}; archetypes: { [key: string]: EntityArchetype } = {};
components: { [name: string]: ComponentType } = {}; components: { [name: string]: ComponentType } = {};
systems: { [name: string]: System } = {}; systems: { [name: string]: System } = {};
scopes: { [name: string]: EntityScope } = {}; topScopes: { [name: string]: EntityScope } = {};
symbols: { [name: string]: 'init' | 'const' } = {}; symbols: { [name: string]: 'init' | 'const' } = {};
event2systems: { [event: string]: System[] } = {}; event2systems: { [event: string]: System[] } = {};
name2cfpairs: { [cfname: string]: ComponentFieldPair[] } = {}; name2cfpairs: { [cfname: string]: ComponentFieldPair[] } = {};
@ -1026,8 +1047,8 @@ export class EntityManager {
} }
newScope(name: string, parent?: EntityScope) { newScope(name: string, parent?: EntityScope) {
let scope = new EntityScope(this, this.dialect, name, parent); let scope = new EntityScope(this, this.dialect, name, parent);
if (this.scopes[name]) throw new ECSError(`scope ${name} already defined`); if (this.topScopes[name]) throw new ECSError(`scope ${name} already defined`);
this.scopes[name] = scope; if (!parent) this.topScopes[name] = scope;
return scope; return scope;
} }
defineComponent(ctype: ComponentType) { defineComponent(ctype: ComponentType) {
@ -1117,9 +1138,7 @@ export class EntityManager {
} }
exportToFile(file: SourceFileExport) { exportToFile(file: SourceFileExport) {
file.text(this.dialect.HEADER); // TODO file.text(this.dialect.HEADER); // TODO
for (let scope of Object.values(this.scopes)) { for (let scope of Object.values(this.topScopes)) {
scope.analyzeEntities();
scope.generateCode();
scope.dump(file); scope.dump(file);
} }
file.text(this.dialect.FOOTER); // TODO file.text(this.dialect.FOOTER); // TODO