jit: split CraneliftBuilder to builder/cranelift.rs and hub-ify builder.rs; stabilize jit-direct (seal/fb TLS/end_function); prep for core.rs split (no behavior change)
This commit is contained in:
@ -4,12 +4,21 @@
|
||||
|
||||
Nyashの文法知識が分散している問題を解決し、AIがNyashコードを正しく書けるよう支援する包括的な文法統一化フェーズ。
|
||||
|
||||
## 🔥 核心的な問題
|
||||
|
||||
現在のNyashは各層(Tokenizer/Parser/Interpreter/MIR/VM/JIT)で予約語・文法解釈がバラバラに実装されており、これが以下の問題を引き起こしている:
|
||||
|
||||
- 同じ `me` キーワードが各層で独自解釈される
|
||||
- `+` 演算子の動作がInterpreter/VM/JITで微妙に異なる
|
||||
- 新しい予約語追加時に6箇所以上の修正が必要
|
||||
- AIが正しいコードを書けない(どの層の解釈に従うべきか不明)
|
||||
|
||||
## 🎯 フェーズの目的
|
||||
|
||||
1. **文法の一元管理**: 分散した文法知識を統一
|
||||
2. **AIエラー削減**: 文法間違いを90%以上削減
|
||||
3. **開発効率向上**: 新構文追加を簡単に
|
||||
4. **ANCP連携**: AI通信の効率化
|
||||
1. **完全統一文法エンジン**: すべての層が単一の文法定義を参照
|
||||
2. **セマンティクス一元化**: 演算子・型変換・実行規則の完全統一
|
||||
3. **AIエラー削減**: 文法間違いを90%以上削減
|
||||
4. **保守性革命**: 新機能追加が1箇所の修正で完了
|
||||
|
||||
## 📊 主要成果物
|
||||
|
||||
@ -66,7 +75,12 @@ keywords:
|
||||
|
||||
## 🔗 関連ドキュメント
|
||||
|
||||
- [統一文法アーキテクチャ設計書](unified-grammar-architecture.md) ← **🔥 核心設計**
|
||||
- [統一予約語システム仕様](unified-keyword-system.md) ← **🎯 具体的実装**
|
||||
- [AI深層考察: 統一文法アーキテクチャ](ai-deep-thoughts-unified-grammar.md) ← **💡 Gemini/Codex分析**
|
||||
- [文法統一化詳細設計](grammar-unification.txt)
|
||||
- [統一文法定義YAML](nyash-grammar-v1.yaml)
|
||||
- [実装計画](implementation-plan.txt)
|
||||
- [AI-Nyash Compact Notation Protocol](../../ideas/new-features/2025-08-29-ai-compact-notation-protocol.md)
|
||||
- [Phase 12: プラグインシステム](../phase-12/)
|
||||
|
||||
|
||||
@ -0,0 +1,146 @@
|
||||
# AI深層考察: Nyash統一文法アーキテクチャ
|
||||
|
||||
## 🎯 概要
|
||||
|
||||
GeminiとCodexに時間無制限で深く考えてもらった、Nyash統一文法アーキテクチャに関する洞察をまとめました。
|
||||
|
||||
## 🔥 Gemini先生の洞察
|
||||
|
||||
### 核心的提言: 宣言的文法定義 + ビルド時コード生成
|
||||
|
||||
```
|
||||
[ grammar.toml ] ← 宣言的SSoT(Single Source of Truth)
|
||||
↓
|
||||
[ build.rs ] ← メタプログラミング層
|
||||
↓
|
||||
├─ generated_tokens.rs
|
||||
├─ generated_keywords.rs
|
||||
├─ generated_rules.rs
|
||||
└─ generated_opcodes.rs
|
||||
```
|
||||
|
||||
### 重要ポイント
|
||||
|
||||
1. **真の分離**: `UnifiedKeyword`構造体は依然として各層を密結合させる。宣言的ファイルからコード生成する方が疎結合を保てる。
|
||||
|
||||
2. **ゼロコスト抽象化**:
|
||||
- ビルド時生成により実行時オーバーヘッドなし
|
||||
- `enum`と`match`文で高速ディスパッチ
|
||||
- `#[inline(always)]`で関数呼び出しコストなし
|
||||
|
||||
3. **コンパイラ駆動開発**:
|
||||
```rust
|
||||
// 新機能追加時、全層でコンパイルエラー発生
|
||||
// → 実装漏れがなくなる
|
||||
match token {
|
||||
TokenType::Async => // 新しく追加されたので実装必須
|
||||
_ => // ...
|
||||
}
|
||||
```
|
||||
|
||||
4. **他言語からの学び**:
|
||||
- **CPython**: `Grammar/Tokens`ファイルから生成
|
||||
- **V8**: Ignition(インタプリタ)とTurboFan(JIT)の分離
|
||||
- **rustc**: HIR→MIRという段階的表現
|
||||
|
||||
## 💡 Codex先生の洞察
|
||||
|
||||
### 核心的提言: MIRを中心とした統一セマンティクス基盤
|
||||
|
||||
```yaml
|
||||
# grammar/nyash.yml
|
||||
tokens:
|
||||
- name: ME
|
||||
literal: "me"
|
||||
soft: true
|
||||
contexts: ["expr", "pattern"]
|
||||
deprecated_aliases: ["self"]
|
||||
ai_hint: "Current object; not assignable."
|
||||
|
||||
operators:
|
||||
- symbol: "+"
|
||||
name: add
|
||||
precedence: 110
|
||||
associativity: left
|
||||
overloads:
|
||||
- types: ["i64","i64"] -> "i64"
|
||||
lower: MIR.AddI64
|
||||
- types: ["String","String"] -> "String"
|
||||
lower: MIR.Concat
|
||||
```
|
||||
|
||||
### 実装戦略
|
||||
|
||||
1. **単一仕様ファイル**: `grammar/nyash.yml`に全て定義
|
||||
- キーワード、演算子、文法、型、強制変換
|
||||
- MIRローリング、VMオペコード、JITパターン
|
||||
- 非推奨、AIヒント
|
||||
|
||||
2. **コード生成クレート**: `crates/nygrammar-gen`
|
||||
- Perfect hash関数でO(1)キーワード認識
|
||||
- Pratt/PEGパーサーテーブル生成
|
||||
- 型ディスパッチマトリックス生成
|
||||
|
||||
3. **MIRが真実の基盤**:
|
||||
```rust
|
||||
pub fn add(lhs: Value, rhs: Value) -> Result<MIRNode> {
|
||||
// 生成されたfast-pathを使用
|
||||
// 常にMIRノードを返す
|
||||
}
|
||||
```
|
||||
|
||||
4. **性能最適化**:
|
||||
- ビルド時にすべて決定(実行時検索なし)
|
||||
- インラインキャッシュで呼び出しサイト最適化
|
||||
- ソフトキーワードはパーサー状態で判定
|
||||
|
||||
### 段階的移行計画
|
||||
|
||||
- **Phase 0**: ベースラインテスト(現状記録)
|
||||
- **Phase 1**: 正準MIR定義
|
||||
- **Phase 2**: KeywordRegistry生成
|
||||
- **Phase 3**: UnifiedSemantics導入
|
||||
- **Phase 4**: パーサー統一
|
||||
- **Phase 5**: バックエンドマッピング
|
||||
- **Phase 6**: 非推奨警告
|
||||
- **Phase 7**: ツール/ドキュメント生成
|
||||
|
||||
## 🎯 統合された知見
|
||||
|
||||
両AIの提言を統合すると:
|
||||
|
||||
### 1. 宣言的定義 + コード生成が最強
|
||||
- YAML/TOMLで文法を宣言的に定義
|
||||
- build.rsでRustコードを生成
|
||||
- 実行時オーバーヘッドゼロ
|
||||
|
||||
### 2. MIRを中心とした統一
|
||||
- すべてのセマンティクスはMIRで表現
|
||||
- 各バックエンドはMIRを実行/コンパイル
|
||||
- 一貫性が自動的に保証される
|
||||
|
||||
### 3. AI友好的な設計
|
||||
- 機械可読な仕様ファイル
|
||||
- 豊富な例とエラーカタログ
|
||||
- 自動生成されるドキュメント
|
||||
|
||||
### 4. 拡張性への配慮
|
||||
- 新バックエンド追加が容易
|
||||
- プラグインによる拡張可能
|
||||
- 後方互換性の維持
|
||||
|
||||
## 📋 実装優先順位
|
||||
|
||||
1. **最優先**: `grammar/nyash.yml`の初版作成
|
||||
2. **高優先**: `build.rs`によるトークン生成
|
||||
3. **中優先**: MIR統一とUnifiedSemantics
|
||||
4. **低優先**: JIT最適化ヒント
|
||||
|
||||
## 🚀 期待される効果
|
||||
|
||||
- **保守性**: 新機能追加が1箇所の修正で完了
|
||||
- **一貫性**: 全層で同じセマンティクス保証
|
||||
- **性能**: ビルド時最適化で実行時コストなし
|
||||
- **AI対応**: LLMが正確にNyashコードを生成
|
||||
|
||||
これらの深い洞察により、Nyashの統一文法アーキテクチャは強固な基盤の上に構築されることになります。
|
||||
@ -0,0 +1,339 @@
|
||||
# Box-First統一文法アーキテクチャ再設計
|
||||
|
||||
## 🚨 現在の設計の問題点
|
||||
|
||||
### 1. 密結合の罠
|
||||
```rust
|
||||
// ❌ 現在の設計: 各層がUnifiedGrammarEngineに直接依存
|
||||
impl Tokenizer {
|
||||
fn tokenize(&mut self) {
|
||||
self.engine.is_keyword() // 直接参照!
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 根が這う実装
|
||||
```rust
|
||||
// ❌ UnifiedKeyword構造体が全層の情報を持つ
|
||||
struct UnifiedKeyword {
|
||||
token_type: TokenType, // Tokenizer層
|
||||
semantic_action: Action, // Parser層
|
||||
mir_instruction: MirOp, // MIR層
|
||||
vm_opcode: VmOp, // VM層
|
||||
jit_pattern: JitPattern, // JIT層
|
||||
// すべてが絡み合っている!
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 巨大な神オブジェクト
|
||||
```rust
|
||||
// ❌ UnifiedGrammarEngineが全てを知っている
|
||||
struct UnifiedGrammarEngine {
|
||||
keywords: KeywordRegistry,
|
||||
syntax: SyntaxRules,
|
||||
semantics: SemanticRules,
|
||||
execution: ExecutionSemantics,
|
||||
// 責任が多すぎる!
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 Box-First再設計
|
||||
|
||||
### 核心思想: 「箱に入れて、箱同士をつなぐ」
|
||||
|
||||
```
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ GrammarBox │ │ TokenBox │ │ ParserBox │
|
||||
│ (定義のみ) │ --> │ (Token化) │ --> │ (構文解析) │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
| |
|
||||
v v
|
||||
┌─────────────┐ ┌─────────────┐
|
||||
│ SemanticBox │ <---------------------- │ ASTBox │
|
||||
│ (意味解釈) │ │ (構文木) │
|
||||
└─────────────┘ └─────────────┘
|
||||
|
|
||||
v
|
||||
┌─────────────┐ ┌─────────────┐ ┌─────────────┐
|
||||
│ MIRBox │ --> │ VMBox │ │ JITBox │
|
||||
│ (中間表現) │ │ (実行) │ │ (コンパイル) │
|
||||
└─────────────┘ └─────────────┘ └─────────────┘
|
||||
```
|
||||
|
||||
## 📦 各箱の責任と境界
|
||||
|
||||
### 1. GrammarBox - 純粋な定義の箱
|
||||
```rust
|
||||
// 定義だけを持つ、実装を持たない
|
||||
box GrammarBox {
|
||||
init { definitions }
|
||||
|
||||
// キーワード定義を返すだけ
|
||||
getKeywordDef(word) {
|
||||
return me.definitions.keywords.get(word)
|
||||
}
|
||||
|
||||
// 演算子定義を返すだけ
|
||||
getOperatorDef(symbol) {
|
||||
return me.definitions.operators.get(symbol)
|
||||
}
|
||||
}
|
||||
|
||||
// キーワード定義は純粋なデータ
|
||||
box KeywordDef {
|
||||
init { literal, category, aliases }
|
||||
// 実装なし、データのみ
|
||||
}
|
||||
```
|
||||
|
||||
### 2. TokenBox - トークン化だけの責任
|
||||
```rust
|
||||
box TokenBox {
|
||||
init { grammarBox } // 定義への参照のみ
|
||||
|
||||
tokenize(text) {
|
||||
local tokens = []
|
||||
// GrammarBoxに聞くだけ、自分では判断しない
|
||||
loop(text.hasMore()) {
|
||||
local word = text.readWord()
|
||||
local def = me.grammarBox.getKeywordDef(word)
|
||||
if def {
|
||||
tokens.push(new Token(def.category, word))
|
||||
} else {
|
||||
tokens.push(new Token("IDENTIFIER", word))
|
||||
}
|
||||
}
|
||||
return tokens
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. SemanticBox - 意味解釈の箱
|
||||
```rust
|
||||
box SemanticBox {
|
||||
init { } // 他の箱に依存しない!
|
||||
|
||||
// 純粋関数として実装
|
||||
add(left, right) {
|
||||
// String + String
|
||||
if left.isString() and right.isString() {
|
||||
return new StringBox(left.value + right.value)
|
||||
}
|
||||
// Number + Number
|
||||
if left.isNumber() and right.isNumber() {
|
||||
return new IntegerBox(left.value + right.value)
|
||||
}
|
||||
// エラー
|
||||
return new ErrorBox("Type mismatch")
|
||||
}
|
||||
|
||||
coerceToString(value) {
|
||||
// 各型の変換ロジック
|
||||
if value.isString() { return value }
|
||||
if value.isNumber() { return new StringBox(value.toString()) }
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 4. MIRBuilderBox - AST→MIR変換の箱
|
||||
```rust
|
||||
box MIRBuilderBox {
|
||||
init { semanticBox } // セマンティクスへの参照のみ
|
||||
|
||||
buildFromAST(ast) {
|
||||
// ASTの種類に応じてMIRを生成
|
||||
if ast.type == "BinaryOp" {
|
||||
return me.buildBinaryOp(ast)
|
||||
}
|
||||
// ...
|
||||
}
|
||||
|
||||
buildBinaryOp(ast) {
|
||||
local left = me.buildFromAST(ast.left)
|
||||
local right = me.buildFromAST(ast.right)
|
||||
|
||||
// セマンティクスに聞いて、適切なMIR命令を選択
|
||||
if ast.op == "+" {
|
||||
// SemanticBoxに型情報を聞く
|
||||
local mirOp = me.selectAddInstruction(left.type, right.type)
|
||||
return new MIRNode(mirOp, left, right)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 疎結合の実現方法
|
||||
|
||||
### 1. インターフェース(契約)による結合
|
||||
```rust
|
||||
// 各箱は最小限のインターフェースだけを公開
|
||||
trait TokenProvider {
|
||||
fn next_token(&mut self) -> Option<Token>;
|
||||
}
|
||||
|
||||
trait SemanticProvider {
|
||||
fn apply_operator(&self, op: &str, args: &[Value]) -> Result<Value>;
|
||||
}
|
||||
|
||||
trait MIRProvider {
|
||||
fn get_instruction(&self, index: usize) -> &MIRInstruction;
|
||||
}
|
||||
```
|
||||
|
||||
### 2. メッセージパッシング
|
||||
```rust
|
||||
// 箱同士は直接呼び出さず、メッセージで通信
|
||||
box ParserBox {
|
||||
parseExpression() {
|
||||
// TokenBoxにメッセージを送る
|
||||
local token = me.sendMessage(me.tokenBox, "nextToken")
|
||||
|
||||
// 結果を処理
|
||||
if token.type == "NUMBER" {
|
||||
return new NumberNode(token.value)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 3. イベント駆動
|
||||
```rust
|
||||
// 文法変更時の通知システム
|
||||
box GrammarBox {
|
||||
updateKeyword(word, newDef) {
|
||||
me.definitions.keywords.set(word, newDef)
|
||||
// 変更を通知(購読者に伝える)
|
||||
me.notify("keyword_changed", word)
|
||||
}
|
||||
}
|
||||
|
||||
box TokenBox {
|
||||
init { grammarBox }
|
||||
|
||||
constructor() {
|
||||
// 文法変更を購読
|
||||
me.grammarBox.subscribe("keyword_changed", me.onKeywordChanged)
|
||||
}
|
||||
|
||||
onKeywordChanged(word) {
|
||||
// キャッシュをクリア
|
||||
me.clearCache()
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📐 ビルド時生成の箱化
|
||||
|
||||
### GeneratorBox - コード生成も箱
|
||||
```rust
|
||||
box GeneratorBox {
|
||||
init { grammarBox, outputPath }
|
||||
|
||||
generate() {
|
||||
local grammar = me.grammarBox.getDefinitions()
|
||||
|
||||
// 各層向けのコードを生成
|
||||
me.generateTokens(grammar.keywords)
|
||||
me.generateParseTables(grammar.syntax)
|
||||
me.generateSemanticTables(grammar.operators)
|
||||
}
|
||||
|
||||
generateTokens(keywords) {
|
||||
local code = "pub enum Token {\n"
|
||||
keywords.forEach((name, def) => {
|
||||
code += " " + name + ",\n"
|
||||
})
|
||||
code += "}\n"
|
||||
|
||||
me.writeFile("generated/tokens.rs", code)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 密結合を避ける設計原則
|
||||
|
||||
### 1. 単一責任の原則
|
||||
- GrammarBox: 定義の管理のみ
|
||||
- TokenBox: トークン化のみ
|
||||
- ParserBox: 構文解析のみ
|
||||
- SemanticBox: 意味解釈のみ
|
||||
|
||||
### 2. 依存関係の逆転
|
||||
```rust
|
||||
// ❌ 悪い例: 具象に依存
|
||||
box VMBox {
|
||||
init { mirBuilder: MIRBuilderBox } // 具象型に依存
|
||||
}
|
||||
|
||||
// ✅ 良い例: 抽象に依存
|
||||
box VMBox {
|
||||
init { mirProvider: MIRProvider } // インターフェースに依存
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Open/Closed原則
|
||||
```rust
|
||||
// 新しい演算子の追加が既存コードを変更しない
|
||||
box OperatorRegistry {
|
||||
init { operators }
|
||||
|
||||
register(symbol, handler) {
|
||||
me.operators.set(symbol, handler)
|
||||
}
|
||||
|
||||
apply(symbol, args) {
|
||||
local handler = me.operators.get(symbol)
|
||||
if handler {
|
||||
return handler.apply(args)
|
||||
}
|
||||
return new ErrorBox("Unknown operator")
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 段階的移行(箱単位)
|
||||
|
||||
### Phase 1: GrammarBox導入
|
||||
- grammar.yamlをGrammarBoxでラップ
|
||||
- 既存コードはGrammarBox経由でアクセス
|
||||
|
||||
### Phase 2: TokenBox分離
|
||||
- Tokenizerの機能をTokenBoxに移動
|
||||
- GrammarBoxへの依存を最小化
|
||||
|
||||
### Phase 3: SemanticBox独立
|
||||
- 演算子実装をSemanticBoxに集約
|
||||
- 純粋関数として実装
|
||||
|
||||
### Phase 4: 箱間通信の確立
|
||||
- メッセージパッシング導入
|
||||
- イベントシステム構築
|
||||
|
||||
## 📊 疎結合度の測定
|
||||
|
||||
### 1. 依存関係グラフ
|
||||
```
|
||||
GrammarBox (依存なし)
|
||||
↓
|
||||
TokenBox → GrammarBox (1依存)
|
||||
ParserBox → TokenBox (1依存)
|
||||
SemanticBox (依存なし)
|
||||
MIRBox → SemanticBox (1依存)
|
||||
VMBox → MIRBox (1依存)
|
||||
JITBox → MIRBox (1依存)
|
||||
```
|
||||
|
||||
### 2. 変更影響範囲
|
||||
- 新キーワード追加: GrammarBoxのみ
|
||||
- 新演算子追加: GrammarBox + SemanticBoxのみ
|
||||
- 新バックエンド追加: 既存箱への変更なし
|
||||
|
||||
## 🚀 期待される効果
|
||||
|
||||
1. **真の疎結合**: 各箱が独立して開発・テスト可能
|
||||
2. **容易な拡張**: 新しい箱の追加が既存を壊さない
|
||||
3. **明確な境界**: 責任の所在が明確
|
||||
4. **並行開発**: チームが独立して各箱を開発可能
|
||||
|
||||
これで「Everything is Box」哲学に忠実な、真に疎結合な統一文法アーキテクチャが実現されます。
|
||||
@ -0,0 +1,297 @@
|
||||
# 根切り文法アーキテクチャ - 真の疎結合設計
|
||||
|
||||
## 🌳 「根が這う」問題の本質
|
||||
|
||||
### 現在の設計の根本的な問題
|
||||
```rust
|
||||
// 🌳 根が這っている例: 一つの変更が全体に波及
|
||||
struct Keyword {
|
||||
name: String,
|
||||
token_type: TokenType, // Tokenizer層の型
|
||||
parser_rule: ParserRule, // Parser層の型
|
||||
mir_op: MIROpcode, // MIR層の型
|
||||
vm_handler: VMHandler, // VM層の型
|
||||
// → 一つのstructが全層の型を知っている!
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 根切り設計: レイヤー完全分離
|
||||
|
||||
### 核心思想: 「各層は自分の関心事だけを知る」
|
||||
|
||||
```
|
||||
【Tokenizer層】 【Parser層】 【Semantic層】
|
||||
"me" → Token::Me → SelfReference
|
||||
知識:文字列のみ 知識:トークンのみ 知識:意味のみ
|
||||
|
||||
【MIR層】 【VM層】 【JIT層】
|
||||
LoadLocal(0) → OP_LOAD_0 → mov rax, [rbp]
|
||||
知識:MIRのみ 知識:オペコードのみ 知識:機械語のみ
|
||||
```
|
||||
|
||||
## 📦 真の箱化: 変換箱(TransformerBox)パターン
|
||||
|
||||
### 1. 各層は純粋な箱
|
||||
```rust
|
||||
// Tokenizer層: 文字列→トークンの変換のみ
|
||||
box StringToTokenBox {
|
||||
init { } // 依存なし!
|
||||
|
||||
transform(text: String) -> TokenStream {
|
||||
// 純粋な文字列処理
|
||||
local tokens = []
|
||||
local chars = text.chars()
|
||||
|
||||
loop(chars.hasNext()) {
|
||||
local ch = chars.next()
|
||||
if ch.isLetter() {
|
||||
local word = me.readWord(chars, ch)
|
||||
tokens.push(me.classifyWord(word))
|
||||
}
|
||||
// ...
|
||||
}
|
||||
return TokenStream(tokens)
|
||||
}
|
||||
|
||||
classifyWord(word: String) -> Token {
|
||||
// ローカルな判定のみ
|
||||
match word {
|
||||
"me" => Token::Me,
|
||||
"from" => Token::From,
|
||||
"loop" => Token::Loop,
|
||||
_ => Token::Identifier(word)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 層間の変換も箱
|
||||
```rust
|
||||
// Token→AST変換箱
|
||||
box TokenToASTBox {
|
||||
init { } // 依存なし!
|
||||
|
||||
transform(tokens: TokenStream) -> AST {
|
||||
local parser = PrattParser()
|
||||
return parser.parse(tokens)
|
||||
}
|
||||
}
|
||||
|
||||
// AST→MIR変換箱
|
||||
box ASTToMIRBox {
|
||||
init { } // 依存なし!
|
||||
|
||||
transform(ast: AST) -> MIR {
|
||||
match ast {
|
||||
AST::BinaryOp(op, left, right) => {
|
||||
local leftMIR = me.transform(left)
|
||||
local rightMIR = me.transform(right)
|
||||
return me.selectMIROp(op, leftMIR, rightMIR)
|
||||
}
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
selectMIROp(op: String, left: MIR, right: MIR) -> MIR {
|
||||
// ローカルな判断のみ
|
||||
if op == "+" {
|
||||
if left.type == "String" and right.type == "String" {
|
||||
return MIR::StringConcat(left, right)
|
||||
}
|
||||
if left.type == "Integer" and right.type == "Integer" {
|
||||
return MIR::AddI64(left, right)
|
||||
}
|
||||
}
|
||||
// ...
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 パイプライン: 箱の連鎖
|
||||
|
||||
### 純粋関数的パイプライン
|
||||
```rust
|
||||
// 各箱は前の箱の出力を入力として受け取るだけ
|
||||
box NyashPipeline {
|
||||
init { }
|
||||
|
||||
compile(source: String) -> ExecutableCode {
|
||||
// 各変換箱を順番に適用
|
||||
local tokens = StringToTokenBox().transform(source)
|
||||
local ast = TokenToASTBox().transform(tokens)
|
||||
local mir = ASTToMIRBox().transform(ast)
|
||||
local bytecode = MIRToVMBox().transform(mir)
|
||||
return bytecode
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 📐 設定の分離: ConfigBox
|
||||
|
||||
### 文法定義も実行時から分離
|
||||
```rust
|
||||
// ビルド時のみ使用される設定箱
|
||||
box GrammarConfigBox {
|
||||
init { yamlPath }
|
||||
|
||||
load() -> GrammarConfig {
|
||||
// YAMLを読み込んで設定オブジェクトを返す
|
||||
return YAML.parse(File.read(me.yamlPath))
|
||||
}
|
||||
}
|
||||
|
||||
// ビルド時コード生成箱
|
||||
box CodeGeneratorBox {
|
||||
init { config }
|
||||
|
||||
generate() {
|
||||
// 設定から各層のコードを生成
|
||||
me.generateTokenizerTable(me.config.keywords)
|
||||
me.generateParserTable(me.config.syntax)
|
||||
me.generateMIRTable(me.config.semantics)
|
||||
}
|
||||
|
||||
generateTokenizerTable(keywords) {
|
||||
// キーワードマッチング用の完全ハッシュ関数生成
|
||||
local code = "fn classify_keyword(s: &str) -> Token {\n"
|
||||
code += " match s {\n"
|
||||
keywords.forEach((word, info) => {
|
||||
code += ' "' + word + '" => Token::' + info.token + ',\n'
|
||||
})
|
||||
code += " _ => Token::Identifier(s.to_string())\n"
|
||||
code += " }\n"
|
||||
code += "}\n"
|
||||
File.write("src/generated/keywords.rs", code)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 セマンティクスの分離
|
||||
|
||||
### セマンティクスも変換箱として実装
|
||||
```rust
|
||||
// 型強制変換箱
|
||||
box TypeCoercionBox {
|
||||
init { } // 依存なし!
|
||||
|
||||
coerceToString(value: Value) -> StringValue {
|
||||
match value {
|
||||
Value::String(s) => StringValue(s),
|
||||
Value::Integer(i) => StringValue(i.toString()),
|
||||
Value::Float(f) => StringValue(f.toString()),
|
||||
Value::Bool(b) => StringValue(b ? "true" : "false"),
|
||||
_ => panic("Cannot coerce to string")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 演算子実行箱
|
||||
box OperatorExecutorBox {
|
||||
init { coercionBox }
|
||||
|
||||
executeAdd(left: Value, right: Value) -> Value {
|
||||
// ローカルな判断
|
||||
match (left, right) {
|
||||
(Value::String(s1), Value::String(s2)) => {
|
||||
Value::String(s1 + s2)
|
||||
}
|
||||
(Value::String(s), other) => {
|
||||
local s2 = me.coercionBox.coerceToString(other)
|
||||
Value::String(s + s2.value)
|
||||
}
|
||||
(Value::Integer(i1), Value::Integer(i2)) => {
|
||||
Value::Integer(i1 + i2)
|
||||
}
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔧 テスト可能性の向上
|
||||
|
||||
### 各箱が独立してテスト可能
|
||||
```rust
|
||||
// StringToTokenBoxのテスト
|
||||
test "tokenize keywords" {
|
||||
local box = StringToTokenBox()
|
||||
local tokens = box.transform("me loop from")
|
||||
assert tokens == [Token::Me, Token::Loop, Token::From]
|
||||
}
|
||||
|
||||
// ASTToMIRBoxのテスト
|
||||
test "binary op to MIR" {
|
||||
local box = ASTToMIRBox()
|
||||
local ast = AST::BinaryOp("+",
|
||||
AST::Literal(Value::Integer(1)),
|
||||
AST::Literal(Value::Integer(2))
|
||||
)
|
||||
local mir = box.transform(ast)
|
||||
assert mir == MIR::AddI64(
|
||||
MIR::Const(Value::Integer(1)),
|
||||
MIR::Const(Value::Integer(2))
|
||||
)
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 依存グラフ: 完全なDAG(有向非巡環グラフ)
|
||||
|
||||
```
|
||||
StringToTokenBox (依存: 0)
|
||||
↓
|
||||
TokenToASTBox (依存: 0)
|
||||
↓
|
||||
ASTToMIRBox (依存: 0)
|
||||
↓ ↓
|
||||
MIRToVMBox (依存: 0) MIRToJITBox (依存: 0)
|
||||
|
||||
TypeCoercionBox (依存: 0)
|
||||
↓
|
||||
OperatorExecutorBox (依存: 1)
|
||||
```
|
||||
|
||||
## 🚀 この設計の利点
|
||||
|
||||
### 1. 真の疎結合
|
||||
- 各箱は入力と出力の型だけを知る
|
||||
- 他の箱の実装を一切知らない
|
||||
- インターフェースすら不要(型だけで十分)
|
||||
|
||||
### 2. 並行開発可能
|
||||
- チームAがTokenizer開発
|
||||
- チームBがParser開発
|
||||
- チームCがMIR開発
|
||||
- 全員が独立して作業可能
|
||||
|
||||
### 3. 差し替え可能
|
||||
```rust
|
||||
// 別実装への差し替えが容易
|
||||
local pipeline = NyashPipeline()
|
||||
pipeline.tokenizer = OptimizedStringToTokenBox() // 高速版
|
||||
pipeline.parser = ErrorRecoveringTokenToASTBox() // エラー回復版
|
||||
```
|
||||
|
||||
### 4. 段階的最適化
|
||||
```rust
|
||||
// 最適化も箱として追加
|
||||
box MIROptimizerBox {
|
||||
transform(mir: MIR) -> MIR {
|
||||
// 定数畳み込み、死んだコード除去など
|
||||
return optimized
|
||||
}
|
||||
}
|
||||
|
||||
// パイプラインに挿入
|
||||
local mir = ASTToMIRBox().transform(ast)
|
||||
mir = MIROptimizerBox().transform(mir) // 追加
|
||||
local bytecode = MIRToVMBox().transform(mir)
|
||||
```
|
||||
|
||||
## 🎯 まとめ: 根を完全に切る
|
||||
|
||||
1. **データ中心設計**: 各層は入力データを出力データに変換するだけ
|
||||
2. **状態を持たない**: すべての箱が純粋関数的
|
||||
3. **設定と実装の分離**: ビルド時と実行時を明確に分離
|
||||
4. **変換の連鎖**: パイプラインで箱をつなぐ
|
||||
|
||||
これにより、真に「根が這わない」アーキテクチャが実現されます。
|
||||
@ -0,0 +1,344 @@
|
||||
# Phase 11.9: 統一文法アーキテクチャ設計書
|
||||
|
||||
## 🔴 現在の根本的問題
|
||||
|
||||
現在のNyashは、各層で予約語・文法解釈がバラバラに実装されている:
|
||||
|
||||
### 1. Tokenizer層での分散
|
||||
```rust
|
||||
// src/tokenizer.rs
|
||||
match word.as_str() {
|
||||
"me" => TokenType::ME, // ハードコード
|
||||
"from" => TokenType::FROM, // ハードコード
|
||||
"loop" => TokenType::LOOP, // ハードコード
|
||||
// ... 各予約語が個別定義
|
||||
}
|
||||
```
|
||||
|
||||
### 2. Parser層での独自解釈
|
||||
```rust
|
||||
// src/parser/mod.rs
|
||||
fn parse_loop(&mut self) {
|
||||
// loop構文の独自解釈
|
||||
// while/forとの混同を個別チェック
|
||||
}
|
||||
```
|
||||
|
||||
### 3. Interpreter層での独自実行
|
||||
```rust
|
||||
// src/interpreter/expressions.rs
|
||||
fn execute_from_call(&mut self) {
|
||||
// fromの独自解釈
|
||||
// デリゲーションロジックが埋め込み
|
||||
}
|
||||
```
|
||||
|
||||
### 4. MIR Builder層での独自変換
|
||||
```rust
|
||||
// src/mir/builder.rs
|
||||
fn build_loop(&mut self) {
|
||||
// loop → MIRへの独自変換
|
||||
// セーフポイント挿入も個別判断
|
||||
}
|
||||
```
|
||||
|
||||
### 5. VM/JIT層での独自実行
|
||||
- VM: 独自のセマンティクス実装
|
||||
- JIT: 独自のコード生成戦略
|
||||
|
||||
## 🎯 統一文法アーキテクチャの設計
|
||||
|
||||
### 核心コンセプト: "Grammar as THE Source of Truth"
|
||||
|
||||
```
|
||||
┌─────────────────────────────────────────────┐
|
||||
│ Unified Grammar Engine │
|
||||
│ (単一の文法定義・解釈・実行エンジン) │
|
||||
├─────────────────────────────────────────────┤
|
||||
│ - Keyword Registry (予約語レジストリ) │
|
||||
│ - Syntax Rules (構文規則) │
|
||||
│ - Semantic Rules (意味規則) │
|
||||
│ - Execution Semantics (実行セマンティクス) │
|
||||
└─────────────────────────────────────────────┘
|
||||
↓
|
||||
┌──────────┬──────────┬──────────┬──────────┐
|
||||
│Tokenizer │ Parser │Interpreter│MIR/VM/JIT│
|
||||
│ (利用) │ (利用) │ (利用) │ (利用) │
|
||||
└──────────┴──────────┴──────────┴──────────┘
|
||||
```
|
||||
|
||||
## 📐 統一文法エンジンの実装設計
|
||||
|
||||
### 1. コア構造体
|
||||
```rust
|
||||
// src/grammar/engine.rs
|
||||
pub struct UnifiedGrammarEngine {
|
||||
// 予約語の統一定義
|
||||
keywords: KeywordRegistry,
|
||||
|
||||
// 構文規則の統一定義
|
||||
syntax: SyntaxRuleEngine,
|
||||
|
||||
// 意味規則の統一定義
|
||||
semantics: SemanticRuleEngine,
|
||||
|
||||
// 実行セマンティクスの統一定義
|
||||
execution: ExecutionSemantics,
|
||||
}
|
||||
|
||||
impl UnifiedGrammarEngine {
|
||||
/// 単一のソースから全情報を読み込み
|
||||
pub fn load() -> Self {
|
||||
// YAML/TOML/Rustコードから読み込み
|
||||
let config = include_str!("../../../grammar/unified-grammar.toml");
|
||||
Self::from_config(config)
|
||||
}
|
||||
|
||||
/// Tokenizerが使う統一API
|
||||
pub fn is_keyword(&self, word: &str) -> Option<TokenType> {
|
||||
self.keywords.lookup(word)
|
||||
}
|
||||
|
||||
/// Parserが使う統一API
|
||||
pub fn parse_rule(&self, rule_name: &str) -> &SyntaxRule {
|
||||
self.syntax.get_rule(rule_name)
|
||||
}
|
||||
|
||||
/// Interpreter/VM/JITが使う統一API
|
||||
pub fn execute_semantic(&self, op: &str, args: &[Value]) -> Value {
|
||||
self.execution.apply(op, args)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### 2. 予約語レジストリ
|
||||
```rust
|
||||
pub struct KeywordRegistry {
|
||||
// 正規形マップ
|
||||
canonical: HashMap<String, KeywordDef>,
|
||||
|
||||
// エイリアスマップ(非推奨含む)
|
||||
aliases: HashMap<String, String>,
|
||||
|
||||
// コンテキスト別解釈
|
||||
contextual: HashMap<(String, Context), KeywordDef>,
|
||||
}
|
||||
|
||||
pub struct KeywordDef {
|
||||
pub token: TokenType,
|
||||
pub category: KeywordCategory,
|
||||
pub semantic_action: SemanticAction,
|
||||
pub mir_opcode: Option<MirOpcode>,
|
||||
pub vm_handler: Option<VmHandler>,
|
||||
pub jit_lowering: Option<JitLowering>,
|
||||
}
|
||||
```
|
||||
|
||||
### 3. 構文規則エンジン
|
||||
```rust
|
||||
pub struct SyntaxRuleEngine {
|
||||
rules: HashMap<String, SyntaxRule>,
|
||||
}
|
||||
|
||||
pub struct SyntaxRule {
|
||||
pub pattern: Pattern,
|
||||
pub precedence: i32,
|
||||
pub associativity: Associativity,
|
||||
pub semantic_transform: Box<dyn Fn(&AST) -> MIR>,
|
||||
}
|
||||
```
|
||||
|
||||
### 4. 実行セマンティクス統一
|
||||
```rust
|
||||
pub struct ExecutionSemantics {
|
||||
// 演算子の統一実装
|
||||
operators: HashMap<String, OperatorSemantics>,
|
||||
|
||||
// 型変換の統一ルール
|
||||
coercions: CoercionRules,
|
||||
|
||||
// エラー処理の統一
|
||||
error_handling: ErrorSemantics,
|
||||
}
|
||||
|
||||
impl ExecutionSemantics {
|
||||
/// すべてのバックエンドが使う統一演算
|
||||
pub fn add(&self, left: Value, right: Value) -> Value {
|
||||
// Interpreter/VM/JIT すべて同じロジック
|
||||
match (&left, &right) {
|
||||
(Value::String(s1), Value::String(s2)) => {
|
||||
Value::String(s1.clone() + s2)
|
||||
}
|
||||
(Value::Integer(i1), Value::Integer(i2)) => {
|
||||
Value::Integer(i1 + i2)
|
||||
}
|
||||
_ => self.coerce_and_add(left, right)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 統一化の実装手順
|
||||
|
||||
### Phase 1: 基盤構築
|
||||
1. `src/grammar/engine.rs` - 統一エンジン本体
|
||||
2. `grammar/unified-grammar.toml` - 統一定義ファイル
|
||||
3. 既存コードとの並行実行(デバッグ用)
|
||||
|
||||
### Phase 2: Tokenizer統合
|
||||
```rust
|
||||
impl NyashTokenizer {
|
||||
fn new() -> Self {
|
||||
Self {
|
||||
engine: UnifiedGrammarEngine::load(),
|
||||
// ...
|
||||
}
|
||||
}
|
||||
|
||||
fn read_keyword_or_identifier(&mut self) -> TokenType {
|
||||
let word = self.read_word();
|
||||
// 統一エンジンに委譲
|
||||
self.engine.is_keyword(&word)
|
||||
.unwrap_or(TokenType::IDENTIFIER(word))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 3: Parser統合
|
||||
```rust
|
||||
impl Parser {
|
||||
fn parse_statement(&mut self) -> Result<ASTNode> {
|
||||
// 統一エンジンから構文規則を取得
|
||||
let rule = self.engine.get_syntax_rule("statement");
|
||||
rule.parse(self)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Phase 4: セマンティクス統合
|
||||
```rust
|
||||
// Interpreter
|
||||
impl Interpreter {
|
||||
fn execute_binop(&mut self, op: &str, left: Value, right: Value) -> Value {
|
||||
// 統一エンジンに委譲
|
||||
self.engine.execute_semantic(op, &[left, right])
|
||||
}
|
||||
}
|
||||
|
||||
// VM
|
||||
impl VM {
|
||||
fn execute_add(&mut self) -> Result<()> {
|
||||
let right = self.pop()?;
|
||||
let left = self.pop()?;
|
||||
// 統一エンジンに委譲
|
||||
let result = self.engine.execute_semantic("add", &[left, right]);
|
||||
self.push(result)
|
||||
}
|
||||
}
|
||||
|
||||
// JIT
|
||||
impl JitBuilder {
|
||||
fn lower_add(&mut self, left: Value, right: Value) {
|
||||
// 統一エンジンから最適化ヒントを取得
|
||||
let strategy = self.engine.get_jit_strategy("add", &left, &right);
|
||||
strategy.emit(self, left, right)
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 統一定義ファイルの例
|
||||
|
||||
```toml
|
||||
# grammar/unified-grammar.toml
|
||||
|
||||
[keywords.me]
|
||||
token = "ME"
|
||||
category = "self_reference"
|
||||
deprecated_aliases = ["this", "self", "@"]
|
||||
semantic_action = "load_self"
|
||||
mir_opcode = "LoadSelf"
|
||||
vm_handler = "OP_LOAD_ME"
|
||||
jit_lowering = "emit_load_local(0)"
|
||||
|
||||
[keywords.from]
|
||||
token = "FROM"
|
||||
category = "delegation"
|
||||
contexts = [
|
||||
{ context = "class_decl", meaning = "inheritance" },
|
||||
{ context = "method_call", meaning = "delegation_call" }
|
||||
]
|
||||
semantic_action = "delegate"
|
||||
mir_opcode = "DelegateCall"
|
||||
|
||||
[keywords.loop]
|
||||
token = "LOOP"
|
||||
category = "control_flow"
|
||||
deprecated_aliases = ["while", "for"]
|
||||
semantic_action = "loop_construct"
|
||||
mir_opcode = "Loop"
|
||||
safepoint_insertion = true
|
||||
|
||||
[operators.add]
|
||||
symbol = "+"
|
||||
precedence = 10
|
||||
associativity = "left"
|
||||
type_rules = [
|
||||
{ left = "String", right = "String", result = "String", action = "concat" },
|
||||
{ left = "Integer", right = "Integer", result = "Integer", action = "add_i64" },
|
||||
{ left = "Float", right = "Float", result = "Float", action = "add_f64" },
|
||||
]
|
||||
coercion_strategy = "string_priority" # String + anything = String
|
||||
|
||||
[semantics.string_concat]
|
||||
interpreter = "rust:concatenate_strings"
|
||||
vm = "CONCAT_STRINGS"
|
||||
jit = "call @nyash.string.concat_hh"
|
||||
```
|
||||
|
||||
## 🚀 期待される効果
|
||||
|
||||
1. **完全な一貫性**
|
||||
- すべての層が同じ予約語定義を使用
|
||||
- すべての層が同じ文法解釈を実行
|
||||
- すべての層が同じセマンティクスを適用
|
||||
|
||||
2. **保守性の劇的向上**
|
||||
- 新しい予約語/演算子の追加が1箇所
|
||||
- 文法変更が全層に自動反映
|
||||
- バグの削減(解釈の不一致がなくなる)
|
||||
|
||||
3. **AI開発の簡素化**
|
||||
- 単一の文法定義をAIに学習させる
|
||||
- 正しいNyashコードの生成率向上
|
||||
- エラーメッセージの一貫性
|
||||
|
||||
4. **性能最適化の余地**
|
||||
- 統一エンジンでの最適化が全層に効果
|
||||
- JITヒントの統一管理
|
||||
- キャッシュ戦略の一元化
|
||||
|
||||
## 📊 実装優先度
|
||||
|
||||
1. **最優先**: 予約語レジストリ(すぐ効果が出る)
|
||||
2. **高優先**: セマンティクス統一(バグ削減効果大)
|
||||
3. **中優先**: 構文規則エンジン(段階的移行可能)
|
||||
4. **低優先**: JIT最適化ヒント(性能向上は後回し)
|
||||
|
||||
## 🔧 移行戦略
|
||||
|
||||
1. **並行実行期間**
|
||||
- 新旧両方の実装を維持
|
||||
- デバッグモードで差分検出
|
||||
- 段階的に新実装に切り替え
|
||||
|
||||
2. **テスト駆動**
|
||||
- 各層の動作一致を自動テスト
|
||||
- スナップショットテストで回帰防止
|
||||
- ファズテストで edge case 発見
|
||||
|
||||
3. **ドキュメント駆動**
|
||||
- 統一文法仕様書を先に作成
|
||||
- 実装は仕様書に従う
|
||||
- AIトレーニングデータも同時生成
|
||||
|
||||
これにより、Nyashの全層で完全に統一された文法解釈と実行が実現される。
|
||||
@ -0,0 +1,321 @@
|
||||
# Nyash統一予約語システム仕様
|
||||
|
||||
## 🎯 目的
|
||||
|
||||
Nyashの全実行層(Script/MIR/VM/JIT)で完全に同一の予約語・文法解釈を実現する。
|
||||
|
||||
## 📊 現状の予約語分散状況
|
||||
|
||||
### Tokenizer層 (src/tokenizer.rs)
|
||||
```rust
|
||||
// 現在: ハードコードされた予約語
|
||||
match word.as_str() {
|
||||
"box" => TokenType::BOX,
|
||||
"me" => TokenType::ME,
|
||||
"from" => TokenType::FROM,
|
||||
"loop" => TokenType::LOOP,
|
||||
"if" => TokenType::IF,
|
||||
"else" => TokenType::ELSE,
|
||||
"local" => TokenType::LOCAL,
|
||||
"return" => TokenType::RETURN,
|
||||
"new" => TokenType::NEW,
|
||||
"static" => TokenType::STATIC,
|
||||
"init" => TokenType::INIT,
|
||||
"birth" => TokenType::BIRTH,
|
||||
"pack" => TokenType::PACK,
|
||||
"override" => TokenType::OVERRIDE,
|
||||
"and" => TokenType::AND,
|
||||
"or" => TokenType::OR,
|
||||
"not" => TokenType::NOT,
|
||||
_ => TokenType::IDENTIFIER(word)
|
||||
}
|
||||
```
|
||||
|
||||
### MIR Builder層での独自解釈
|
||||
```rust
|
||||
// 現在: MIR生成時の独自判断
|
||||
fn build_from_call(&mut self) {
|
||||
// "from"の解釈がTokenizerと異なる可能性
|
||||
}
|
||||
```
|
||||
|
||||
### VM/JIT層での実行差異
|
||||
```rust
|
||||
// VM: 文字列連結の独自実装
|
||||
VMValue::String(s1) + VMValue::String(s2) => concat
|
||||
|
||||
// JIT: 異なる最適化戦略
|
||||
emit_call("nyash.string.concat_hh")
|
||||
```
|
||||
|
||||
## 🏗️ 統一予約語システムの設計
|
||||
|
||||
### 1. 中央予約語レジストリ
|
||||
```rust
|
||||
// src/grammar/keyword_registry.rs
|
||||
pub struct UnifiedKeywordRegistry {
|
||||
keywords: HashMap<&'static str, UnifiedKeyword>,
|
||||
}
|
||||
|
||||
pub struct UnifiedKeyword {
|
||||
// トークン情報
|
||||
pub token_type: TokenType,
|
||||
pub literal: &'static str,
|
||||
|
||||
// 文法情報
|
||||
pub category: KeywordCategory,
|
||||
pub precedence: Option<i32>,
|
||||
|
||||
// セマンティクス情報
|
||||
pub semantic_action: SemanticAction,
|
||||
pub mir_instruction: Option<MirInstruction>,
|
||||
pub vm_opcode: Option<VmOpcode>,
|
||||
pub jit_pattern: Option<JitPattern>,
|
||||
|
||||
// メタ情報
|
||||
pub deprecated_aliases: Vec<&'static str>,
|
||||
pub ai_hint: &'static str,
|
||||
}
|
||||
|
||||
// 静的に初期化される単一インスタンス
|
||||
pub static KEYWORDS: Lazy<UnifiedKeywordRegistry> = Lazy::new(|| {
|
||||
let mut registry = UnifiedKeywordRegistry::new();
|
||||
|
||||
// "me" - 自己参照
|
||||
registry.register(UnifiedKeyword {
|
||||
token_type: TokenType::ME,
|
||||
literal: "me",
|
||||
category: KeywordCategory::SelfReference,
|
||||
semantic_action: SemanticAction::LoadSelf,
|
||||
mir_instruction: Some(MirInstruction::LoadLocal(0)),
|
||||
vm_opcode: Some(VmOpcode::LOAD_ME),
|
||||
jit_pattern: Some(JitPattern::LoadFirstParam),
|
||||
deprecated_aliases: vec!["this", "self", "@"],
|
||||
ai_hint: "Always use 'me' for self-reference",
|
||||
precedence: None,
|
||||
});
|
||||
|
||||
// "from" - デリゲーション
|
||||
registry.register(UnifiedKeyword {
|
||||
token_type: TokenType::FROM,
|
||||
literal: "from",
|
||||
category: KeywordCategory::Delegation,
|
||||
semantic_action: SemanticAction::DelegateCall,
|
||||
mir_instruction: Some(MirInstruction::Call),
|
||||
vm_opcode: Some(VmOpcode::DELEGATE_CALL),
|
||||
jit_pattern: Some(JitPattern::VirtualCall),
|
||||
deprecated_aliases: vec!["super", "parent", "base"],
|
||||
ai_hint: "Use 'from' for parent method calls",
|
||||
precedence: None,
|
||||
});
|
||||
|
||||
// "loop" - 制御フロー
|
||||
registry.register(UnifiedKeyword {
|
||||
token_type: TokenType::LOOP,
|
||||
literal: "loop",
|
||||
category: KeywordCategory::ControlFlow,
|
||||
semantic_action: SemanticAction::Loop,
|
||||
mir_instruction: Some(MirInstruction::Branch),
|
||||
vm_opcode: Some(VmOpcode::LOOP_START),
|
||||
jit_pattern: Some(JitPattern::LoopWithSafepoint),
|
||||
deprecated_aliases: vec!["while", "for", "repeat"],
|
||||
ai_hint: "Only 'loop' exists for iteration",
|
||||
precedence: None,
|
||||
});
|
||||
|
||||
// 演算子も統一管理
|
||||
registry.register(UnifiedKeyword {
|
||||
token_type: TokenType::PLUS,
|
||||
literal: "+",
|
||||
category: KeywordCategory::BinaryOperator,
|
||||
precedence: Some(10),
|
||||
semantic_action: SemanticAction::Add,
|
||||
mir_instruction: Some(MirInstruction::BinOp(BinOpKind::Add)),
|
||||
vm_opcode: Some(VmOpcode::ADD),
|
||||
jit_pattern: Some(JitPattern::PolymorphicAdd),
|
||||
deprecated_aliases: vec![],
|
||||
ai_hint: "String + String = concat, Number + Number = add",
|
||||
});
|
||||
|
||||
registry
|
||||
});
|
||||
```
|
||||
|
||||
### 2. 各層での統一API使用
|
||||
|
||||
#### Tokenizer統合
|
||||
```rust
|
||||
impl NyashTokenizer {
|
||||
fn tokenize_word(&mut self, word: String) -> TokenType {
|
||||
// 統一レジストリを参照
|
||||
KEYWORDS.lookup(&word)
|
||||
.map(|kw| kw.token_type.clone())
|
||||
.unwrap_or(TokenType::IDENTIFIER(word))
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### Parser統合
|
||||
```rust
|
||||
impl Parser {
|
||||
fn parse_keyword(&mut self, token: &Token) -> Result<ASTNode> {
|
||||
if let Some(keyword) = KEYWORDS.get_by_token(&token.token_type) {
|
||||
// 統一されたセマンティクスアクションを実行
|
||||
match keyword.semantic_action {
|
||||
SemanticAction::Loop => self.parse_loop_unified(keyword),
|
||||
SemanticAction::DelegateCall => self.parse_from_unified(keyword),
|
||||
// ...
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### MIR Builder統合
|
||||
```rust
|
||||
impl MirBuilder {
|
||||
fn build_keyword(&mut self, keyword: &UnifiedKeyword, args: Vec<MirValue>) -> MirValue {
|
||||
// 統一されたMIR命令を生成
|
||||
if let Some(mir_inst) = &keyword.mir_instruction {
|
||||
self.emit_unified(mir_inst.clone(), args)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### VM統合
|
||||
```rust
|
||||
impl VM {
|
||||
fn execute_keyword(&mut self, keyword: &UnifiedKeyword) -> Result<()> {
|
||||
// 統一されたVMオペコードを実行
|
||||
if let Some(opcode) = &keyword.vm_opcode {
|
||||
self.execute_unified_opcode(opcode)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
#### JIT統合
|
||||
```rust
|
||||
impl JitBuilder {
|
||||
fn compile_keyword(&mut self, keyword: &UnifiedKeyword, args: &[Value]) {
|
||||
// 統一されたJITパターンを適用
|
||||
if let Some(pattern) = &keyword.jit_pattern {
|
||||
self.emit_unified_pattern(pattern, args)
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## 🔄 セマンティクス統一の例
|
||||
|
||||
### 現在の問題: "+" 演算子の挙動差異
|
||||
|
||||
```rust
|
||||
// Interpreter: 独自の型変換ロジック
|
||||
fn execute_add(&mut self, left: Value, right: Value) -> Value {
|
||||
// 複雑な型変換ロジック
|
||||
}
|
||||
|
||||
// VM: 異なる型変換ロジック
|
||||
fn vm_add(&mut self) {
|
||||
// 別の型変換ロジック
|
||||
}
|
||||
|
||||
// JIT: さらに異なる最適化
|
||||
fn jit_add(&mut self) {
|
||||
// JIT独自の最適化
|
||||
}
|
||||
```
|
||||
|
||||
### 統一後: 単一のセマンティクス定義
|
||||
|
||||
```rust
|
||||
// src/grammar/unified_semantics.rs
|
||||
pub struct UnifiedSemantics;
|
||||
|
||||
impl UnifiedSemantics {
|
||||
/// すべての層が使用する統一Add実装
|
||||
pub fn add(left: &Value, right: &Value) -> Result<Value> {
|
||||
use Value::*;
|
||||
match (left, right) {
|
||||
// String優先(Nyashの仕様)
|
||||
(String(s1), String(s2)) => Ok(String(s1.clone() + s2)),
|
||||
(String(s), other) | (other, String(s)) => {
|
||||
Ok(String(s.clone() + &Self::coerce_to_string(other)?))
|
||||
}
|
||||
// 数値演算
|
||||
(Integer(i1), Integer(i2)) => Ok(Integer(i1 + i2)),
|
||||
(Float(f1), Float(f2)) => Ok(Float(f1 + f2)),
|
||||
(Integer(i), Float(f)) | (Float(f), Integer(i)) => {
|
||||
Ok(Float(*i as f64 + f))
|
||||
}
|
||||
// その他はエラー
|
||||
_ => Err(Error::TypeMismatch)
|
||||
}
|
||||
}
|
||||
|
||||
/// 統一された文字列変換
|
||||
pub fn coerce_to_string(value: &Value) -> Result<String> {
|
||||
match value {
|
||||
Value::String(s) => Ok(s.clone()),
|
||||
Value::Integer(i) => Ok(i.to_string()),
|
||||
Value::Float(f) => Ok(f.to_string()),
|
||||
Value::Bool(b) => Ok(b.to_string()),
|
||||
Value::Null => Ok("null".to_string()),
|
||||
_ => Err(Error::CannotCoerceToString)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 各層での使用
|
||||
// Interpreter
|
||||
left_value = UnifiedSemantics::add(&left, &right)?;
|
||||
|
||||
// VM
|
||||
let result = UnifiedSemantics::add(&self.pop()?, &self.pop()?)?;
|
||||
self.push(result);
|
||||
|
||||
// JIT
|
||||
self.emit_call("UnifiedSemantics::add", args);
|
||||
```
|
||||
|
||||
## 📋 実装チェックリスト
|
||||
|
||||
- [ ] `src/grammar/keyword_registry.rs` - 統一予約語レジストリ
|
||||
- [ ] `src/grammar/unified_semantics.rs` - 統一セマンティクス
|
||||
- [ ] `src/grammar/mod.rs` - モジュール統合
|
||||
- [ ] Tokenizer修正 - 統一レジストリ参照
|
||||
- [ ] Parser修正 - 統一セマンティクス使用
|
||||
- [ ] MIR Builder修正 - 統一MIR生成
|
||||
- [ ] VM修正 - 統一実行
|
||||
- [ ] JIT修正 - 統一コード生成
|
||||
- [ ] テストスイート - 全層の一致確認
|
||||
- [ ] ドキュメント - 統一仕様書
|
||||
|
||||
## 🎯 成功基準
|
||||
|
||||
1. **完全一致**: すべての層で同じ入力が同じ出力を生成
|
||||
2. **単一修正**: 新予約語追加が1ファイルの修正で完了
|
||||
3. **AI正確性**: AIが生成するコードのエラー率90%削減
|
||||
4. **性能維持**: 統一化による性能劣化5%以内
|
||||
|
||||
## 🚀 移行計画
|
||||
|
||||
### Phase 1: 基盤構築(1週間)
|
||||
- 統一レジストリ実装
|
||||
- 既存コードとの並行動作
|
||||
|
||||
### Phase 2: Tokenizer/Parser統合(1週間)
|
||||
- 段階的切り替え
|
||||
- 差分検出とログ
|
||||
|
||||
### Phase 3: 実行層統合(2週間)
|
||||
- MIR/VM/JIT の統一
|
||||
- 包括的テスト
|
||||
|
||||
### Phase 4: 完全移行(1週間)
|
||||
- 旧コード削除
|
||||
- ドキュメント完成
|
||||
|
||||
これにより、Nyashのすべての層で完全に統一された予約語・文法解釈が実現される。
|
||||
Reference in New Issue
Block a user