Keyboard shortcuts

Press or to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

Call / Jump

シーンからシーンへ――話の流れを操る術を授けますわ。 Pasta は ifwhile も持たない宣言的な言語ですけれど、ご心配なく。 シーン定義と Call だけで、十分に豊かな会話の分岐が描けますのよ。


Pasta DSL は宣言的言語であり、命令型の制御構文(if / while 等)を持たない。制御フローはシーン定義Call / >)で実現する。Call は指定したシーンを呼び出し、実行後に元の場所へ戻る。

Call の基本

Call 行はインデントした行頭に (または >)を置き、呼び出すターゲットを続ける。

メイン
    ぱすた:自己紹介を始めます
    >自己紹介
    ぱすた:自己紹介が終わりました

    自己紹介
        ぱすた:私はぱすたです

Call ターゲットの形式

Call は 2 つのターゲット形式をサポートする。

形式構文説明
シーン参照>シーン名スコープから見えるローカル/グローバルシーンを前方一致検索して呼び出す
動的ターゲット>$変数名変数の値をシーン名として解決して呼び出す
スタート
    >次のステップ          # シーン参照

    次のステップ
        ぱすた:次のステップに来ました
動的呼び出し
    target:挨拶朝
    >$target             # 変数値「挨拶朝」をシーン名として解決

前方一致によるターゲット解決

Call のターゲット解決は前方一致で候補を列挙する。次のシーンがあるとき:

挨拶朝
挨拶昼
  • >挨拶 → 「挨拶朝」「挨拶昼」の両方が候補
  • >挨拶朝 → 「挨拶朝」のみが候補

候補が複数あれば、そこからランダムに 1 つが選択される。これにより、毎回同じにならない自然な会話を作れる。

スコープ解決アルゴリズム

Call 文と単語参照()は同一のスコープ解決アルゴリズムを使う。Call にスコープ修飾子は不要である。

  1. ローカル検索: 現在のグローバルシーンスコープ内のローカルシーンを、指定プレフィックスで前方一致検索
  2. グローバル検索: すべてのグローバルシーンを、指定プレフィックスで前方一致検索
  3. マージ: 両検索結果を結合して候補リストを生成
  4. 選択: 候補リストからランダムに 1 つを選択(キャッシュベースの順次消費)

異なるグローバルシーンスコープでは、同じシーン名でも見えるローカルシーンが異なるため、検索結果が変わり得る。

重要: Call()はシーン辞書のみを検索し、単語辞書は参照しない。逆に単語参照()はシーン辞書を参照しない。両者は同じスコープ解決アルゴリズムを共有するが、検索対象の辞書は分離されている。

条件分岐の実現

条件分岐は Lua ブロック内で実装し、act:call() で分岐先を選ぶ。

メイン
    スコア:75

```lua
function SCENE.分岐判定(act)
    local save, var = act:init_scene(SCENE)
    local スコア = var.スコア
    local label
    if スコア >= 90 then
        label = "優秀"
    elseif スコア >= 50 then
        label = "合格"
    else
        label = "不合格"
    end
    return act:call(SCENE.__global_name__, label, {})
end
```

    >@分岐判定

    優秀
        ぱすた:優秀です!
    合格
        ぱすた:合格です
    不合格
        ぱすた:不合格です

フィルター(将来変更あり)

Call ターゲットの後ろに &key=value 形式のフィルターを付けて、属性で候補を絞り込む構文が予約されている。

>シーン名&author=Alice&genre=comedy

フィルターは比較・条件判定のため、コロンではなく比較演算子( など)を使う。

将来変更あり: フィルター機能は将来用に宣言されているだけで、現状では無視される。比較演算子ベース(&score>50 など)への拡張も将来予定である。

引数リスト

Call や関数呼び出しには、括弧で名前付き引数を渡せる。引数どうしは空白で区切る。

calculate(x:10 y:20)

実装状態: 引数リストは AST レベルで解釈されるが、トランスパイラ層以降の処理は順次対応予定である。


これで会話に「流れ」と「分岐」が生まれますわ。 シーンを呼び合うだけで物語が動く――なかなか痛快でしょう? 次は値の正体「リテラル型」へ。

権威的仕様: Call の厳密な定義は doc/spec/04-call-spec.md を参照。スコープ解決の共通仕様は doc/spec/10-words.md も参照。