Elvelt
ブログ一覧に戻る
Engineering|2026/05/15

EMPL IR 設計の舞台裏 — 言語中立な中間表現を作る

DSUV
Written by DSUV

MPL_Compiler の心臓部である EMPL IR(Extended Multi-Platform Language IR)の設計が一段落しました。本記事では、なぜこの IR が必要だったのか、どのようなノード体系を選んだのかを共有します。

動機:言語の「サイロ化」問題

長年にわたり、JavaScript の柔軟性・Python の生産性・Rust の安全性は、それぞれ別々のエコシステムに閉じ込められてきました。これらを同時に享受するには、FFI やマイクロサービス境界といった「橋」を渡すしかなく、その度に複雑性とオーバーヘッドが生まれます。

私たちは、すべての言語を 1 つの中間表現に正規化することで、この橋を 1 か所に集約できると考えました。それが EMPL IR です。

EMPL IR のノード体系

EMPL IR は core/ir/EMPLNode.h に定義されたノードツリーで、ProgramNode を頂点として複数の ModuleNode を束ねます。その下には FunctionDeclNode / ClassDeclNode / VariableDeclNode などの宣言ノード、IfNode / ForNode / TryCatchNode などの制御構造ノード、LambdaNode / AwaitNode / YieldNode などの関数型・非同期ノードが並びます。

特徴的なのは、動的型付けと静的型付けを区別しない点です。すべての値と型を EMPLTypes.h 内の共通型で表現することで、JS の "hello" + 1 も Python の "hello" + 1 も、まったく同じ IR ノードになります。

StandardLibraryCallNode — 言語中立 API 層

もう一つの重要な設計が StandardLibraryCallNode です。JavaScript の console.log("hi") も Python の print("hi") も、内部的には StandardLibraryCallNode("Console", "WriteLine", ["hi"]) という同じ IR ノードに正規化されます。

これにより、フロントエンドはソース言語の構文糖衣を担当し、バックエンドはターゲット言語の呼び出しを担当するという、極めてクリーンな責務分離が実現します。MPL_Standard/Specification.json がこの層にとっての単一の真実の源であり、MPL_Standard/CppImpl.h が C++20 実装です。

今後の課題

一方で、まだ実装されていないノードもあります:InterfaceDeclNodeEnumDeclNodeTypeAliasDeclNodeRecordLiteralNodeTupleLiteralNodeDestructuringPatternNode などです。これらを加えることで、より多くの言語機能を言語中立に表現できるようになります。

旅はまだ続きます。次回は、JavaScript フロントエンドの ESM/CJS モジュール解決と、node_modules / package.jsonexports/imports フィールドへの対応について詳しく書く予定です。

Thanks for reading.

ブログ一覧に戻る