321 lines
9.4 KiB
Markdown
321 lines
9.4 KiB
Markdown
# 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のすべての層で完全に統一された予約語・文法解釈が実現される。 |