diff --git a/src/common/ecs/compiler.ts b/src/common/ecs/compiler.ts index 33061c3f..922f0f37 100644 --- a/src/common/ecs/compiler.ts +++ b/src/common/ecs/compiler.ts @@ -13,10 +13,11 @@ export enum ECSTokenType { export class ECSCompiler extends Tokenizer { - em = new EntityManager(new Dialect_CA65()); // TODO currentScope: EntityScope | null = null; - constructor() { + constructor( + public readonly em: EntityManager) + { super(); //this.includeEOL = true; this.setTokenRules([ @@ -53,9 +54,17 @@ export class ECSCompiler extends Tokenizer { } } + getImportFile: (path: string) => string; + + importFile(path: string) { + let text = this.getImportFile && this.getImportFile(path); + if (!text) this.compileError(`I can't find the import file "${path}".`); + new ECSCompiler(this.em).parseFile(path, text); + } + parseTopLevel() { //this.skipBlankLines(); - let tok = this.expectTokens(['component', 'system', 'scope', 'resource', 'comment']); + let tok = this.expectTokens(['component', 'system', 'scope', 'resource', 'import', 'demo', 'comment']); if (tok.str == 'component') { return this.em.defineComponent(this.parseComponentDefinition()); } @@ -68,6 +77,16 @@ export class ECSCompiler extends Tokenizer { if (tok.str == 'resource') { return this.em.defineSystem(this.parseResource()); } + if (tok.str == 'import') { + let tok = this.expectTokenTypes([ECSTokenType.QuotedString]); + let path = tok.str.substring(1, tok.str.length-1); + return this.importFile(path); + } + if (tok.str == 'demo') { + let scope = this.parseScope(); + scope.isDemo = true; + return scope; + } if (tok.str == 'comment') { this.expectTokenTypes([ECSTokenType.CodeFragment]); return; @@ -253,6 +272,7 @@ export class ECSCompiler extends Tokenizer { parseScope() : EntityScope { let name = this.expectIdent().str; let scope = this.em.newScope(name, this.currentScope || undefined); + scope.filePath = this.path; this.currentScope = scope; let cmd; while ((cmd = this.expectTokens(['using', 'entity', 'scope', 'comment', 'end']).str) != 'end') { diff --git a/src/common/ecs/ecs.ts b/src/common/ecs/ecs.ts index 461c86aa..dc1e3af9 100644 --- a/src/common/ecs/ecs.ts +++ b/src/common/ecs/ecs.ts @@ -56,7 +56,6 @@ crazy idea -- full expansion, then relooper */ -import { throws } from "assert"; import { SourceLocated, SourceLocation } from "../workertypes"; export class ECSError extends Error { @@ -730,6 +729,8 @@ export class EntityScope implements SourceLocated { maxTempBytes = 0; resources = new Set(); state = new ActionState(); + isDemo = false; + filePath = ''; constructor( public readonly em: EntityManager, @@ -1139,7 +1140,10 @@ export class EntityManager { exportToFile(file: SourceFileExport) { file.text(this.dialect.HEADER); // TODO for (let scope of Object.values(this.topScopes)) { - scope.dump(file); + // TODO: demos + if (!scope.isDemo) { + scope.dump(file); + } } file.text(this.dialect.FOOTER); // TODO } diff --git a/src/common/tokenizer.ts b/src/common/tokenizer.ts index 4fad3494..9c7b2ec7 100644 --- a/src/common/tokenizer.ts +++ b/src/common/tokenizer.ts @@ -171,7 +171,7 @@ export class Tokenizer { expectTokens(strlist: string[], msg?: string): Token { let tok = this.consumeToken(); let tokstr = tok.str; - if (strlist.indexOf(tokstr) < 0) { + if (!strlist.includes(tokstr)) { this.compileError(msg || `There should be a ${strlist.map((s) => `"${s}"`).join(' or ')} here, not "${tokstr}".`); } return tok; diff --git a/src/ide/project.ts b/src/ide/project.ts index a399ef33..0c11974a 100644 --- a/src/ide/project.ts +++ b/src/ide/project.ts @@ -150,6 +150,7 @@ export class CodeProject { files.push(dir + '/' + fn); } + // TODO: use tool id to parse files, not platform parseIncludeDependencies(text:string):string[] { let files = []; let m; @@ -199,13 +200,18 @@ export class CodeProject { this.pushAllFiles(files, m[2]); } // for wiz - let re5 = /^\s*(import|embed)\s+"(.+?)";/gmi; + let re5 = /^\s*(import|embed)\s*"(.+?)";/gmi; while (m = re5.exec(text)) { if (m[1] == 'import') this.pushAllFiles(files, m[2] + ".wiz"); else this.pushAllFiles(files, m[2]); } + // for ecs + let re6 = /^\s*(import)\s*"(.+?)"/gmi; + while (m = re6.exec(text)) { + this.pushAllFiles(files, m[2]); + } } return files; } diff --git a/src/test/testecs.ts b/src/test/testecs.ts index 5e505300..1b626032 100644 --- a/src/test/testecs.ts +++ b/src/test/testecs.ts @@ -290,7 +290,8 @@ function testECS() { } function testCompiler() { - let c = new ECSCompiler(); + let em = new EntityManager(new Dialect_CA65()); // TODO + let c = new ECSCompiler(em); try { c.parseFile(` // comment diff --git a/src/worker/tools/ecs.ts b/src/worker/tools/ecs.ts index 37a1eef7..3600ae1a 100644 --- a/src/worker/tools/ecs.ts +++ b/src/worker/tools/ecs.ts @@ -1,11 +1,15 @@ import { ECSCompiler } from "../../common/ecs/compiler"; -import { ECSError } from "../../common/ecs/ecs"; +import { Dialect_CA65, ECSError, EntityManager } from "../../common/ecs/ecs"; import { CompileError } from "../../common/tokenizer"; import { CodeListingMap } from "../../common/workertypes"; import { BuildStep, BuildStepResult, gatherFiles, getWorkFileAsString, putWorkFile, staleFiles } from "../workermain"; export function assembleECS(step: BuildStep): BuildStepResult { - let compiler = new ECSCompiler(); + let em = new EntityManager(new Dialect_CA65()); // TODO + let compiler = new ECSCompiler(em); + compiler.getImportFile = (path: string) => { + return getWorkFileAsString(path); + } gatherFiles(step, { mainFilePath: "main.ecs" }); var destpath = step.prefix + '.ca65'; if (staleFiles(step, [destpath])) {