From 3b5a268cde475984a5c7adcddaa18d903967274c Mon Sep 17 00:00:00 2001 From: FineArchs <133759614+FineArchs@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:39:02 +0900 Subject: [PATCH 1/2] Update index.ts --- src/interpreter/index.ts | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/src/interpreter/index.ts b/src/interpreter/index.ts index 9f2f26ae..299f3269 100644 --- a/src/interpreter/index.ts +++ b/src/interpreter/index.ts @@ -179,7 +179,7 @@ export class Interpreter { for (const node of script) { switch (node.type) { case 'ns': { - await this.collectNsMember(node); + await this.collectNsMember(node, this.scope); break; } @@ -191,10 +191,11 @@ export class Interpreter { } @autobind - private async collectNsMember(ns: Ast.Namespace): Promise { - const scope = this.scope.createChildScope(); + private async collectNsMember(nsNode: Ast.Namespace, parentScope: Scope, parentPrefix?: string): Promise { + const scope = parentScope.createChildScope(); + const prefix = (parentPrefix ?? '') + nsNode.name + ':'; - for (const node of ns.members) { + for (const node of nsNode.members) { switch (node.type) { case 'def': { if (node.mut) { @@ -207,12 +208,13 @@ export class Interpreter { }; scope.add(node.name, variable); - this.scope.add(ns.name + ':' + node.name, variable); + this.scope.add(prefix + node.name, variable); break; } case 'ns': { - break; // TODO + this.collectNsMember(node, scope, prefix); + break; } default: { From 808ac9060c2f044055afba79b56993cf7135eb30 Mon Sep 17 00:00:00 2001 From: FineArchs <133759614+FineArchs@users.noreply.github.com> Date: Sat, 20 Apr 2024 22:56:53 +0900 Subject: [PATCH 2/2] Update test --- test/index.ts | 15 +++++++++++++++ 1 file changed, 15 insertions(+) diff --git a/test/index.ts b/test/index.ts index 5d4634e9..518ee6ee 100644 --- a/test/index.ts +++ b/test/index.ts @@ -1858,6 +1858,21 @@ describe('namespace', () => { eq(res, STR('kawaii')); }); + test.concurrent('recursive', async () => { + const res = await exe(` + <: Foo:Bar:baz() + + :: Foo { + let ai = 'aichan' + :: Bar { + let kawa = 'kawaii' + @baz() { \`{ai} {kawa}\` } + } + } + `); + eq(res, STR('aichan kawaii')); + }); + test.concurrent('cannot declare mutable variable', async () => { try { await exe(`