From ed51ebc916a0806f4c78513ec947bc0b2db8219e Mon Sep 17 00:00:00 2001 From: Xie Yuheng Date: Mon, 1 Apr 2024 07:54:58 +0800 Subject: [PATCH] =?UTF-8?q?[lang1]=20=E6=94=AF=E6=8C=81=20`(import)`?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- TODO.md | 1 - src/lang1/mod/index.ts | 1 + src/lang1/mod/modResolve.ts | 5 +++++ src/lang1/run/execute.ts | 7 ++++++- src/lang1/run/importOne.ts | 29 +++++++++++++++++++++++++++++ 5 files changed, 41 insertions(+), 2 deletions(-) create mode 100644 src/lang1/mod/modResolve.ts create mode 100644 src/lang1/run/importOne.ts diff --git a/TODO.md b/TODO.md index 205a765..e7d048f 100644 --- a/TODO.md +++ b/TODO.md @@ -1,4 +1,3 @@ -[lang1] 支持 `(import)` [lang1] test `(import)` > [lang0] 支持直接递归函数与相互递归函数,不能判断等价的地方就不判断。 diff --git a/src/lang1/mod/index.ts b/src/lang1/mod/index.ts index bb33960..30cdcc6 100644 --- a/src/lang1/mod/index.ts +++ b/src/lang1/mod/index.ts @@ -1,4 +1,5 @@ export * from "./Mod.js" +export * from "./modResolve.js" export * from "./createMod.js" export * from "./modDefine.js" export * from "./modFind.js" diff --git a/src/lang1/mod/modResolve.ts b/src/lang1/mod/modResolve.ts new file mode 100644 index 0000000..5288b72 --- /dev/null +++ b/src/lang1/mod/modResolve.ts @@ -0,0 +1,5 @@ +import { type Mod } from "./index.js" + +export function modResolve(mod: Mod, href: string): URL { + return new URL(href, mod.url) +} diff --git a/src/lang1/run/execute.ts b/src/lang1/run/execute.ts index 518620e..ab01d9f 100644 --- a/src/lang1/run/execute.ts +++ b/src/lang1/run/execute.ts @@ -2,6 +2,7 @@ import { formatExp } from "../format/formatExp.js" import { modDefine, type Mod } from "../mod/index.js" import { reduce } from "../reduce/reduce.js" import { type Stmt } from "../stmt/Stmt.js" +import { importOne } from "./importOne.js" export function execute(mod: Mod, stmt: Stmt): null | string { switch (stmt["@kind"]) { @@ -20,7 +21,11 @@ export function execute(mod: Mod, stmt: Stmt): null | string { } case "Import": { - throw new Error("TODO") + for (const entry of stmt.entries) { + importOne(mod, stmt.path, entry) + } + + return null } } } diff --git a/src/lang1/run/importOne.ts b/src/lang1/run/importOne.ts new file mode 100644 index 0000000..c1f036c --- /dev/null +++ b/src/lang1/run/importOne.ts @@ -0,0 +1,29 @@ +import { modDefine, modFind, modResolve } from "../mod/index.js" +import type { Mod } from "../mod/Mod.js" +import type { ImportEntry } from "../stmt/Stmt.js" +import { executeMod } from "./executeMod.js" + +export function importOne(mod: Mod, path: string, entry: ImportEntry): void { + const url = modResolve(mod, path) + if (url.href === mod.url.href) { + throw new Error(`I can not circular import: ${path}`) + } + + const found = mod.loadedMods.get(url.href) + if (found === undefined) { + throw new Error(`Mod is not loaded: ${path}`) + } + + executeMod(found.mod) + + const { name, rename } = entry + + const def = modFind(found.mod, name) + if (def === undefined) { + throw new Error( + `I can not import undefined name: ${name}, from path: ${path}`, + ) + } + + modDefine(mod, rename || name, def) +}