1
0
mirror of https://github.com/sehugg/8bitworkshop.git synced 2024-06-08 08:33:32 +00:00

ecs: moved everything to dialect

This commit is contained in:
Steven Hugg 2022-02-04 11:45:14 -06:00
parent 186baf8c13
commit 2d5eec8ba3
2 changed files with 57 additions and 52 deletions

View File

@ -286,8 +286,10 @@ export class ECSCompiler extends Tokenizer {
let tok = this.expectTokenTypes([ECSTokenType.CodeFragment]); let tok = this.expectTokenTypes([ECSTokenType.CodeFragment]);
let code = tok.str.substring(3, tok.str.length-3); let code = tok.str.substring(3, tok.str.length-3);
let lines = code.split('\n'); let lines = code.split('\n');
let re = /^\s*(;|\/\/|$)/; // ignore comments and blank lines
for (let i=0; i<lines.length; i++) { for (let i=0; i<lines.length; i++) {
lines[i] = ` .dbg line, "${this.path}", ${tok.$loc.line+i}\n` + lines[i]; if (!lines[i].match(re))
lines[i] = this.em.dialect.debug_line(this.path, tok.$loc.line+i) + '\n' + lines[i];
} }
return lines.join('\n'); return lines.join('\n');
} }
@ -338,7 +340,9 @@ export class ECSCompiler extends Tokenizer {
let e = this.currentScope.newEntity(etype); let e = this.currentScope.newEntity(etype);
e.name = name; e.name = name;
let cmd; let cmd;
while ((cmd = this.expectTokens(['const', 'init', 'end']).str) != 'end') { // TODO: remove init?
while ((cmd = this.expectTokens(['const', 'init', 'var', 'end']).str) != 'end') {
if (cmd == 'var') cmd = 'init';
// TODO: check data types // TODO: check data types
let name = this.expectIdent().str; let name = this.expectIdent().str;
let comps = this.em.componentsWithFieldName([{etype: e.etype, cmatch:e.etype.components}], name); let comps = this.em.componentsWithFieldName([{etype: e.etype, cmatch:e.etype.components}], name);
@ -396,9 +400,9 @@ export class ECSCompiler extends Tokenizer {
export() { export() {
let src = new SourceFileExport(); let src = new SourceFileExport();
src.debug_file(this.path); src.line(this.em.dialect.debug_file(this.path));
for (let path of Object.keys(this.em.imported)) for (let path of Object.keys(this.em.imported))
src.debug_file(path); src.line(this.em.dialect.debug_file(path));
this.exportToFile(src); this.exportToFile(src);
return src.toString(); return src.toString();
} }

View File

@ -292,55 +292,54 @@ __BRK:
bss() { bss() {
return `.bss\n`; return `.bss\n`;
} }
debug_file(path: string) {
return `.dbg file, "${path}", 0, 0`
}
debug_line(path: string, line: number) {
return `.dbg line, "${path}", ${line}`
}
startScope(name: string) {
return `.scope ${name}`
}
endScope(name: string) {
return `.endscope\n${name}__Start = ${name}::__Start`
// TODO: scope__start = scope::start
}
segment(seg: string, segtype: 'rodata' | 'bss' | 'code') {
if (segtype == 'bss') {
return `.zeropage`; // TODO
} else {
return `.code`;
}
}
label(sym: string) {
return `${sym}:`;
}
byte(b: number | ConstByte | undefined) {
if (b === undefined) {
return `.res 1`
} else if (typeof b === 'number') {
if (b < 0 || b > 255) throw new ECSError(`out of range byte ${b}`);
return `.byte ${b}`
} else {
if (b.bitofs == 0) return `.byte <${b.symbol}`
else if (b.bitofs == 8) return `.byte >${b.symbol}`
else return `.byte (${b.symbol} >> ${b.bitofs})` // TODO?
}
}
} }
// TODO: merge with Dialect? // TODO: merge with Dialect?
export class SourceFileExport { export class SourceFileExport {
lines: string[] = []; lines: string[] = [];
comment(text: string) { line(s: string) {
this.lines.push(';' + text); this.text(s);
}
segment(seg: string, segtype: 'rodata' | 'bss' | 'code') {
if (segtype == 'bss') {
this.lines.push(`.zeropage`); // TODO
} else {
this.lines.push(`.code`);
}
}
label(sym: string) {
this.lines.push(`${sym}:`);
}
byte(b: number | ConstByte | undefined) {
if (b === undefined) {
this.lines.push(` .res 1`);
} else if (typeof b === 'number') {
if (b < 0 || b > 255) throw new ECSError(`out of range byte ${b}`);
this.lines.push(` .byte ${b}`)
} else {
if (b.bitofs == 0) this.lines.push(` .byte <${b.symbol}`)
else if (b.bitofs == 8) this.lines.push(` .byte >${b.symbol}`)
else this.lines.push(` .byte (${b.symbol} >> ${b.bitofs})`) // TODO?
}
} }
text(s: string) { text(s: string) {
for (let l of s.split('\n')) for (let l of s.split('\n'))
this.lines.push(l); this.lines.push(l);
} }
debug_file(path: string) {
this.lines.push(` .dbg file, "${path}", 0, 0`);
}
debug_line(path: string, line: number) {
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');
} }
@ -385,13 +384,14 @@ class DataSegment {
this.initdata[ofs + i] = bytes[i]; this.initdata[ofs + i] = bytes[i];
} }
} }
dump(file: SourceFileExport) { dump(file: SourceFileExport, dialect: Dialect_CA65) {
for (let i = 0; i < this.size; i++) { for (let i = 0; i < this.size; i++) {
let syms = this.ofs2sym.get(i); let syms = this.ofs2sym.get(i);
if (syms) { if (syms) {
for (let sym of syms) file.label(sym); for (let sym of syms)
file.line(dialect.label(sym));
} }
file.byte(this.initdata[i]); file.line(dialect.byte(this.initdata[i]));
} }
} }
// TODO: move cfname functions in here too // TODO: move cfname functions in here too
@ -1116,20 +1116,21 @@ export class EntityScope implements SourceLocated {
dump(file: SourceFileExport) { dump(file: SourceFileExport) {
this.analyzeEntities(); this.analyzeEntities();
this.generateCode(); this.generateCode();
file.startScope(this.name); let dialect = this.dialect;
file.segment(`${this.name}_DATA`, 'bss'); file.line(dialect.startScope(this.name));
file.line(dialect.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, dialect);
file.segment(`${this.name}_RODATA`, 'rodata'); file.line(dialect.segment(`${this.name}_RODATA`, 'rodata'));
this.rodata.dump(file); this.rodata.dump(file, dialect);
//file.segment(`${this.name}_CODE`, 'code'); //file.segment(`${this.name}_CODE`, 'code');
file.label('__Start'); file.line(dialect.label('__Start'));
this.code.dump(file); this.code.dump(file);
for (let subscope of this.childScopes) { for (let subscope of this.childScopes) {
// TODO: overlay child BSS segments // TODO: overlay child BSS segments
subscope.dump(file); subscope.dump(file);
} }
file.endScope(this.name); file.line(dialect.endScope(this.name));
} }
} }