Skip to content

Instantly share code, notes, and snippets.

@mizchi
Created January 26, 2026 13:10
Show Gist options
  • Select an option

  • Save mizchi/a1a08f4afa82857fb713427493ff7673 to your computer and use it in GitHub Desktop.

Select an option

Save mizchi/a1a08f4afa82857fb713427493ff7673 to your computer and use it in GitHub Desktop.
// deno run -A compile-mbt.ts
import * as comlink from "npm:comlink@4.4.2";
const mooncWorkerPath = import.meta.resolve(
"npm:@moonbit/moonc-worker@0.1.202601213/moonc-worker.js"
);
// 標準ライブラリの .mi ファイルを読み込む
function getStdMiFiles(target = "js"): [string, Uint8Array][] {
const home = Deno.env.get("HOME") || "";
const moonHome = `${home}/.moon/lib/core`;
const bundlePath = `${moonHome}/target/${target}/release/bundle`;
const allPkgsPath = `${bundlePath}/all_pkgs.json`;
const allPkgsData = JSON.parse(Deno.readTextFileSync(allPkgsPath));
const packages = allPkgsData.packages || allPkgsData;
const stdMiFiles: [string, Uint8Array][] = [];
for (const pkgInfo of packages) {
const pkg = typeof pkgInfo === "string" ? pkgInfo : pkgInfo.rel;
const pkgName = pkg.split("/").at(-1);
const miPath = `${bundlePath}/${pkg}/${pkgName}.mi`;
try {
const miContent = Deno.readFileSync(miPath);
stdMiFiles.push([`/lib/core/${pkg}:${pkg}`, miContent]);
} catch {
// skip missing files
}
}
return stdMiFiles;
}
function getCoreCore(target = "js"): Uint8Array {
const home = Deno.env.get("HOME") || "";
const corePath = `${home}/.moon/lib/core/target/${target}/release/bundle/core.core`;
return Deno.readFileSync(corePath);
}
async function compile(sourceCode: string) {
const worker = new Worker(mooncWorkerPath, { type: "module" });
const moonc = comlink.wrap<any>(worker);
try {
const stdMiFiles = getStdMiFiles("js");
const buildResult = await moonc.buildPackage({
mbtFiles: [["main.mbt", sourceCode]],
miFiles: [],
indirectImportMiFiles: [],
stdMiFiles,
target: "js",
pkg: "main",
pkgSources: ["main:main:/"],
isMain: true,
errorFormat: "json",
enableValueTracing: false,
noOpt: false,
});
if (buildResult.diagnostics.length > 0) {
return { success: false, errors: buildResult.diagnostics.map((d: string) => JSON.parse(d)) };
}
if (!buildResult.core) {
return { success: false, errors: [{ message: "Compilation failed" }] };
}
const coreCore = getCoreCore("js");
const linkResult = await moonc.linkCore({
coreFiles: [coreCore, buildResult.core],
main: "main",
pkgSources: ["moonbitlang/core:moonbit-core:/lib/core", "main:main:/"],
target: "js",
exportedFunctions: [],
outputFormat: "wasm",
testMode: false,
debug: false,
noOpt: false,
sourceMap: false,
sources: {},
stopOnMain: false,
});
return {
success: true,
js: new TextDecoder().decode(linkResult.result),
};
} finally {
worker.terminate();
}
}
// Main
const sourceCode = `
fn main {
println("Hello from MoonBit!")
let x = 1 + 2
println("1 + 2 = " + x.to_string())
}
`;
console.log("Compiling MoonBit code with Deno...\n");
console.log("Source:");
console.log(sourceCode);
const result = await compile(sourceCode);
if (result.success) {
console.log("\n✓ Compilation successful!");
console.log("\nGenerated JS (first 500 chars):");
console.log(result.js!.slice(0, 500) + "...");
Deno.writeTextFileSync("output.js", result.js!);
console.log("\n→ Full output written to output.js");
} else {
console.error("\n✗ Compilation failed:");
console.error(result.errors);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment