refactor(llvm): Complete Call instruction modularization + Phase 21 organization
## LLVM Call Instruction Modularization - Moved MirInstruction::Call lowering to separate instructions/call.rs - Follows the principle of one MIR instruction per file - Call implementation was already complete, just needed modularization ## Phase 21 Documentation - Moved all Phase 21 content to private/papers/paper-f-self-parsing-db/ - Preserved AI evaluations from Gemini and Codex - Academic paper potential confirmed by both AIs - Self-parsing AST database approach validated ## Next Steps - Continue monitoring ChatGPT5's LLVM improvements - Consider creating separate nyash-llvm-compiler crate when LLVM layer is stable - This will reduce build times by isolating LLVM dependencies 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@ -0,0 +1,266 @@
|
||||
# Phase 21: Nyash自己解析アプローチ - AST直接保存
|
||||
|
||||
## 📋 概要
|
||||
|
||||
Nyashの最大の強み「自分自身をパースできる」を活かした究極にシンプルなアプローチ。
|
||||
外部パーサー不要、複雑な変換層不要。NyashのASTをそのままデータベースに保存する。
|
||||
|
||||
## 🎯 核心的なアイデア
|
||||
|
||||
```nyash
|
||||
// Nyashは自分自身を解析できる!
|
||||
NyashParser.parse(sourceCode) → AST → Database → NyashPrinter.print(AST) → sourceCode
|
||||
```
|
||||
|
||||
**重要な気づき:**
|
||||
- Nyashにはすでにパーサーがある
|
||||
- ASTから元のソースを生成する機能もある
|
||||
- だから、ASTをDBに保存すれば完全可逆!
|
||||
|
||||
## 🏗️ シンプルな実装
|
||||
|
||||
### データベース構造
|
||||
```sql
|
||||
-- ASTノードをそのまま保存
|
||||
CREATE TABLE ast_nodes (
|
||||
id INTEGER PRIMARY KEY,
|
||||
node_type TEXT, -- "Box", "Method", "Field", "Statement"等
|
||||
node_data JSON, -- ASTノードの完全な情報
|
||||
parent_id INTEGER,
|
||||
position INTEGER, -- 親ノード内での位置
|
||||
source_file TEXT, -- 元のファイルパス
|
||||
metadata JSON, -- 後から追加する解析情報
|
||||
FOREIGN KEY (parent_id) REFERENCES ast_nodes(id)
|
||||
);
|
||||
|
||||
-- インデックス
|
||||
CREATE INDEX idx_node_type ON ast_nodes(node_type);
|
||||
CREATE INDEX idx_parent ON ast_nodes(parent_id);
|
||||
CREATE INDEX idx_source ON ast_nodes(source_file);
|
||||
```
|
||||
|
||||
### 基本実装
|
||||
```nyash
|
||||
box NyashCodeDB {
|
||||
parser: NyashParser
|
||||
printer: NyashPrinter
|
||||
db: SQLiteBox
|
||||
|
||||
birth() {
|
||||
me.parser = new NyashParser()
|
||||
me.printer = new NyashPrinter()
|
||||
me.db = new SQLiteBox("code.db")
|
||||
}
|
||||
|
||||
// ファイルをDBに保存
|
||||
importFile(filePath) {
|
||||
local source = FileBox.read(filePath)
|
||||
local ast = me.parser.parse(source)
|
||||
|
||||
// ASTを再帰的にDBに保存
|
||||
me.saveAST(ast, null, filePath)
|
||||
}
|
||||
|
||||
// ASTノードを保存
|
||||
saveAST(node, parentId, sourceFile) {
|
||||
local nodeId = me.db.insert("ast_nodes", {
|
||||
node_type: node.type,
|
||||
node_data: node.toJSON(),
|
||||
parent_id: parentId,
|
||||
position: node.position,
|
||||
source_file: sourceFile
|
||||
})
|
||||
|
||||
// 子ノードも保存
|
||||
for (i, child) in node.children.enumerate() {
|
||||
child.position = i
|
||||
me.saveAST(child, nodeId, sourceFile)
|
||||
}
|
||||
|
||||
return nodeId
|
||||
}
|
||||
|
||||
// DBからソースコードを復元
|
||||
exportFile(filePath) {
|
||||
local rootNodes = me.db.query(
|
||||
"SELECT * FROM ast_nodes
|
||||
WHERE source_file = ? AND parent_id IS NULL
|
||||
ORDER BY position",
|
||||
filePath
|
||||
)
|
||||
|
||||
local source = ""
|
||||
for node in rootNodes {
|
||||
local ast = me.loadAST(node.id)
|
||||
source += me.printer.print(ast) + "\n"
|
||||
}
|
||||
|
||||
FileBox.write(filePath, source)
|
||||
}
|
||||
|
||||
// ASTを再構築
|
||||
loadAST(nodeId) {
|
||||
local node = me.db.get("ast_nodes", nodeId)
|
||||
local astNode = ASTNode.fromJSON(node.node_data)
|
||||
|
||||
// 子ノードも読み込む
|
||||
local children = me.db.query(
|
||||
"SELECT * FROM ast_nodes
|
||||
WHERE parent_id = ?
|
||||
ORDER BY position",
|
||||
nodeId
|
||||
)
|
||||
|
||||
for child in children {
|
||||
astNode.addChild(me.loadAST(child.id))
|
||||
}
|
||||
|
||||
return astNode
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 高度な機能
|
||||
|
||||
### リファクタリング
|
||||
```nyash
|
||||
box ASTRefactorer {
|
||||
db: SQLiteBox
|
||||
|
||||
// 名前変更
|
||||
renameBox(oldName, newName) {
|
||||
// Box定義を見つける
|
||||
local boxNodes = me.db.query(
|
||||
"SELECT * FROM ast_nodes
|
||||
WHERE node_type = 'Box'
|
||||
AND json_extract(node_data, '$.name') = ?",
|
||||
oldName
|
||||
)
|
||||
|
||||
for node in boxNodes {
|
||||
// AST上で名前を変更
|
||||
local data = JSON.parse(node.node_data)
|
||||
data.name = newName
|
||||
me.db.update("ast_nodes", node.id, {
|
||||
node_data: JSON.stringify(data)
|
||||
})
|
||||
}
|
||||
|
||||
// 使用箇所も更新
|
||||
me.updateReferences(oldName, newName)
|
||||
}
|
||||
|
||||
// メソッド移動
|
||||
moveMethod(methodName, fromBox, toBox) {
|
||||
// SQLで親ノードを変更するだけ!
|
||||
local fromBoxId = me.findBoxNode(fromBox)
|
||||
local toBoxId = me.findBoxNode(toBox)
|
||||
|
||||
me.db.execute(
|
||||
"UPDATE ast_nodes
|
||||
SET parent_id = ?
|
||||
WHERE parent_id = ?
|
||||
AND node_type = 'Method'
|
||||
AND json_extract(node_data, '$.name') = ?",
|
||||
[toBoxId, fromBoxId, methodName]
|
||||
)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### メタデータ解析(オンデマンド)
|
||||
```nyash
|
||||
box MetadataEngine {
|
||||
// 必要な時だけ解析
|
||||
analyzeOnDemand(nodeId) {
|
||||
local node = db.get("ast_nodes", nodeId)
|
||||
|
||||
if not node.metadata or me.isOutdated(node.metadata) {
|
||||
local metadata = {
|
||||
dependencies: me.findDependencies(node),
|
||||
complexity: me.calculateComplexity(node),
|
||||
lastAnalyzed: now()
|
||||
}
|
||||
|
||||
db.update("ast_nodes", nodeId, {
|
||||
metadata: JSON.stringify(metadata)
|
||||
})
|
||||
}
|
||||
|
||||
return JSON.parse(node.metadata)
|
||||
}
|
||||
|
||||
// 依存関係を動的に検出
|
||||
findDependencies(node) {
|
||||
local deps = []
|
||||
|
||||
// "new XXXBox" パターンを検索
|
||||
local matches = me.searchPattern(node, "NewBox")
|
||||
for match in matches {
|
||||
deps.push(match.boxType)
|
||||
}
|
||||
|
||||
// "from XXX" パターンを検索
|
||||
local inherits = me.searchPattern(node, "From")
|
||||
for inherit in inherits {
|
||||
deps.push(inherit.parentBox)
|
||||
}
|
||||
|
||||
return deps
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 利点
|
||||
|
||||
### 1. 実装の簡単さ
|
||||
- パーサーはすでにある(Nyash自身)
|
||||
- プリンターもすでにある
|
||||
- 複雑な変換層不要
|
||||
|
||||
### 2. 100%の正確性
|
||||
- Nyash公式パーサーを使うから完璧
|
||||
- ASTは言語の完全な表現
|
||||
- 情報の欠落なし
|
||||
|
||||
### 3. 柔軟性
|
||||
- メタデータは後から追加
|
||||
- 部分的な解析が可能
|
||||
- 増分更新が簡単
|
||||
|
||||
### 4. 高速性
|
||||
- ASTの一部だけ読み込み可能
|
||||
- SQLの力でクエリが高速
|
||||
- キャッシュも自然に実装
|
||||
|
||||
## 🎯 実装ステップ
|
||||
|
||||
### Phase 1: 基本機能(1週間)
|
||||
- AST保存・読み込み
|
||||
- ファイル単位のインポート・エクスポート
|
||||
- 基本的なクエリ
|
||||
|
||||
### Phase 2: リファクタリング(1週間)
|
||||
- 名前変更
|
||||
- メソッド移動
|
||||
- 依存関係追跡
|
||||
|
||||
### Phase 3: 高度な機能(2週間)
|
||||
- メタデータ解析
|
||||
- インクリメンタル更新
|
||||
- VSCode統合
|
||||
|
||||
## 🌟 まとめ
|
||||
|
||||
**「Nyashの能力をフル活用する」**
|
||||
|
||||
- 外部ツール不要
|
||||
- 複雑な実装不要
|
||||
- Nyashらしいシンプルさ
|
||||
|
||||
このアプローチなら、Phase 21は「NyashのASTをDBに入れるだけ」という
|
||||
極めてシンプルな実装で、強力な機能を実現できる!
|
||||
|
||||
---
|
||||
|
||||
> 「なぜ複雑にする?Nyashにはすでに必要なものが全部ある」 - にゃ
|
||||
Reference in New Issue
Block a user