Skip to content

feat: 名前空間付き import (PR1: plain import + 修飾呼び出し)#133

Open
ryuichi1208 wants to merge 6 commits into
mainfrom
feat/namespaced-imports
Open

feat: 名前空間付き import (PR1: plain import + 修飾呼び出し)#133
ryuichi1208 wants to merge 6 commits into
mainfrom
feat/namespaced-imports

Conversation

@ryuichi1208

Copy link
Copy Markdown
Member

概要

rw を単一ファイルから複数ファイルへ拡張する、Python 風 import の PR1 / 全3 PRimport foo で同一ディレクトリの foo.rw を取り込み、foo.bar() と修飾して呼べるようにする。名前空間付き import の全インフラ(DOT トークン・ローダ・名前空間付き関数テーブル・irgen シンボル規約・循環検出)を本 PR に集約する。

  • import math_libmath_lib.add(2, 3) と修飾呼び出し
  • 推移的 import を許し、循環は検出してエラー。import 先の main 定義もエラー
  • 別モジュールの同名関数が共存できる(rw_user_<module>_<name> シンボル)

from x import y(PR2)と import x as m(PR3)は後続。設計は docs/specs/17-namespaced-imports.md に 3 PR 分まとめてある。

設計の要点

  • Call.module: Optional[str]=None を足し、修飾呼び出しだけを区別。デフォルト None なので既存の Call 生成・ビルトイン分岐(callee == "print" 等)は無改変。member-access ノード化は却下(数十の分岐が全壊するため)。
  • AST はマージせず、sema が関数テーブルを (module, name) でキー化して統合解析。main 必須チェックは entry モジュールのみ。
  • SemaResult.call_resolution: Dict[id(Call), (module, name)] で呼び出しの実体を irgen に伝える。PR2/PR3 の別名解決もここに乗る。
  • モジュール解決は新規 rwc/loader.py に隔離(driver は配線のみ)。

変更ファイル

レイヤー ファイル 変更
lexer rwc/lexer.py DOT トークン(float と非衝突)
ast rwc/ast_nodes.py Import / Call.module / Module.imports
parser rwc/parser.py parse_importmod.func() の修飾呼び出し
loader rwc/loader.py(新規) 同一ディレクトリ相対解決・推移 import・循環検出・import 先 main 禁止
sema rwc/sema.py (module,name) 関数テーブル、analyze_programcall_resolution
irgen rwc/irgen.py rw_user_<module>_<name> シンボル、(module,name) ルックアップ
driver rwc/driver.py compile/emit-ir/emit-ast の 3 経路を loader 経由に
docs docs/specs/17-*, docs/plans/2026-06-22-* spec(3 PR 分)と PR1 plan
examples/tests examples/import_basic*, tests/* e2e + 単体

Test plan

  • 単体 206 + e2e 27 = 233 全緑uv run pytest -q
  • e2e: import_basic.rw を clang でビルド・実行し 5\n20\n を確認
  • emit-ir で rw_user_import_basic_lib_add シンボルを確認
  • ネガティブ手動確認: 存在しないモジュール / import 先の main / 循環 import / def の後の import → いずれも位置付きの明確なエラー

Non-Goals(spec 17 に明記)

パッケージ階層 pkg.sub / 再エクスポート / ワイルドカード / 可視性 / 標準ライブラリ・検索パス / 型エイリアスの import / 循環 import の解決(検出のみ)。from/as は PR2/PR3。

🤖 Generated with Claude Code

ryuichi1208 and others added 6 commits June 22, 2026 01:51
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Add Import AST node, Call.module, and Module.imports. parse_module
accepts `import foo` before any def/type; parse_atom_postfix reads
`mod.func(...)` into Call(module="mod"). `as`/`from` forms error for now.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
load_program parses the entry module and every transitively imported
module from the entry directory. Detects missing modules, import cycles,
and main defined in an imported module.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Process the whole LoadedProgram: collect signatures across all modules
keyed by (module, name), enforce main only on the entry module, and
resolve qualified calls (mod.func) against imported modules. Record each
call's resolved target in call_resolution for irgen. Add analyze_program;
analyze() now wraps a single module in a LoadedProgram.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
irgen emits every module's functions, qualifying imported symbols as
rw_user_<module>_<name> and resolving calls/spawns via call_resolution.
driver routes compile/emit-ir/emit-ast through load_program +
analyze_program. Add examples/import_basic{,_lib}.rw and e2e coverage.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant