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:
parent
b28a4b5be4
commit
83238f30f1
@ -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]);
|
||||||
}
|
}
|
||||||
|
@ -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
|
||||||
|
Loading…
Reference in New Issue
Block a user