|  | 
| 1 | 1 | import { ParsingError } from "@xieyuheng/x-data.js" | 
|  | 2 | +import dedent from "dedent" | 
|  | 3 | +import assert from "node:assert" | 
| 2 | 4 | import fs from "node:fs" | 
| 3 | 5 | import { expFreeNames } from "../exp/expFreeNames.ts" | 
|  | 6 | +import { expIndirectFreeNames } from "../exp/index.ts" | 
| 4 | 7 | import { formatExp } from "../format/formatExp.ts" | 
| 5 |  | -import { | 
| 6 |  | -  createMod, | 
| 7 |  | -  modFind, | 
| 8 |  | -  modOwnDefs, | 
| 9 |  | -  type Def, | 
| 10 |  | -  type Mod, | 
| 11 |  | -} from "../mod/index.ts" | 
|  | 8 | +import { createMod, modFind, modOwnDefs, type Mod } from "../mod/index.ts" | 
| 12 | 9 | import { parseStmts } from "../parse/index.ts" | 
| 13 | 10 | import { globalLoadedMods } from "./globalLoadedMods.ts" | 
| 14 | 11 | import { handleDefine } from "./handleDefine.ts" | 
| @@ -42,24 +39,34 @@ async function run(mod: Mod): Promise<void> { | 
| 42 | 39 |   for (const stmt of mod.stmts) await handleDefine(mod, stmt) | 
| 43 | 40 |   for (const stmt of mod.stmts) await handleImport(mod, stmt) | 
| 44 | 41 | 
 | 
| 45 |  | -  for (const def of modOwnDefs(mod).values()) postprocessDef(mod, def) | 
|  | 42 | +  postprocess(mod) | 
| 46 | 43 | 
 | 
| 47 | 44 |   for (const stmt of mod.stmts) await handleEffect(mod, stmt) | 
| 48 | 45 | 
 | 
| 49 | 46 |   mod.isFinished = true | 
| 50 | 47 | } | 
| 51 | 48 | 
 | 
| 52 |  | -function postprocessDef(mod: Mod, def: Def): void { | 
| 53 |  | -  def.freeNames = expFreeNames(new Set(), def.exp) | 
| 54 |  | -  for (const name of def.freeNames) { | 
| 55 |  | -    if (modFind(mod, name) === undefined) { | 
| 56 |  | -      throw new Error( | 
| 57 |  | -        [ | 
| 58 |  | -          `[load] I find undefined name: ${name}`, | 
| 59 |  | -          `  defining: ${def.name}`, | 
| 60 |  | -          `  body: ${formatExp(def.exp)}`, | 
| 61 |  | -        ].join("\n"), | 
| 62 |  | -      ) | 
|  | 49 | +function postprocess(mod: Mod): void { | 
|  | 50 | +  for (const def of modOwnDefs(mod).values()) { | 
|  | 51 | +    def.freeNames = expFreeNames(new Set(), def.exp) | 
|  | 52 | +  } | 
|  | 53 | + | 
|  | 54 | +  for (const def of modOwnDefs(mod).values()) { | 
|  | 55 | +    assert(def.freeNames) | 
|  | 56 | +    for (const name of def.freeNames) { | 
|  | 57 | +      if (!modFind(mod, name)) { | 
|  | 58 | +        throw new Error(dedent` | 
|  | 59 | +          [load] I find undefined name: ${name} | 
|  | 60 | +            defining: ${def.name} | 
|  | 61 | +            to: : ${formatExp(def.exp)} | 
|  | 62 | +          `) | 
|  | 63 | +      } | 
|  | 64 | +    } | 
|  | 65 | +  } | 
|  | 66 | + | 
|  | 67 | +  for (const def of modOwnDefs(mod).values()) { | 
|  | 68 | +    if (expIndirectFreeNames(mod, def.exp).has(def.name)) { | 
|  | 69 | +      def.isRecursive = true | 
| 63 | 70 |     } | 
| 64 | 71 |   } | 
| 65 | 72 | } | 
0 commit comments