← ソースコード説明書

packages/compiler - .ks コンパイラ

作成日: 2026-03-06 / 更新日: 2026-06-10

概要

TyranoScript 風の .ks スクリプトを Op[] (ランタイム命令配列) にコンパイルする。Tokenizer → Parser → Transformer → Finalizer のパイプラインで処理する。コマンドレジストリにより、新コマンドの追加が容易。

ディレクトリ構成

packages/compiler/
├── src/
│   ├── compiler/
│   │   └── Compiler.ts              # メインパイプライン
│   ├── tokenizer/
│   │   ├── Tokenizer.ts             # トークン化
│   │   └── lineClassifier.ts        # 行タイプ判別 (73行)
│   ├── parser/
│   │   ├── Parser.ts                # AST 生成
│   │   ├── KsParser.ts              # KS フォーマットパーサー
│   │   ├── KsPrinter.ts             # AST プリティプリンタ
│   │   ├── KsScanner.ts             # KS トークナイザ
│   │   ├── parseCommand.ts          # コマンド解析
│   │   ├── parseText.ts             # テキスト解析
│   │   └── parseOptionalArgs.ts     # オプション引数解析
│   ├── transformer/
│   │   └── Transformer.ts           # AST 変換 (変数展開、最適化)
│   ├── finalizer/
│   │   └── Finalizer.ts             # Op[] 生成
│   ├── validator/
│   │   └── Validator.ts             # プリコンパイルチェック
│   ├── registry/
│   │   └── commandRegistry.ts       # コマンドパーサーレジストリ (1116行)
│   ├── types/
│   │   ├── AST.ts                   # AST ノード型
│   │   ├── KsAST.ts                 # KS 固有 AST
│   │   ├── Token.ts                 # トークン型
│   │   ├── CompilerError.ts         # コンパイルエラー型
│   │   └── CompilerOptions.ts       # オプション型
│   ├── cli/
│   │   ├── cli.ts                   # CLI エントリ
│   │   └── commands/
│   │       ├── compile.ts           # compile コマンド
│   │       └── validate.ts          # validate コマンド
│   └── index.ts                     # 公開 API (26行)
├── test/
│   ├── tokenizer.test.ts
│   ├── lineClassifier.test.ts
│   ├── phase2.test.ts
│   ├── phase3.test.ts
│   ├── phase5.test.ts
│   ├── command-sync.test.ts
│   ├── validator.test.ts
│   └── integration.test.ts
├── package.json
├── tsconfig.json
└── vitest.config.ts

コンパイルパイプライン

.ks ソースコード
    ↓
[lineClassifier] → 行タイプ判別 (TEXT, COMMAND, VAR_SET, CHOICE_START, IF_START, ...)
    ↓
[Tokenizer] → Token[]
    ↓
[Parser + commandRegistry] → AST
    ↓
[Transformer] → 最適化済み AST
    ↓
[Validator] → バリデーション
    ↓
[Finalizer] → Op[]

主要ファイル

ファイル行数役割
commandRegistry.ts1116全コマンドのパーサー関数を COMMAND_PARSERS マップに登録
lineClassifier.ts73KNOWN_COMMAND_NAMES ホワイトリストで行タイプを判別
Compiler.tsパイプライン統合
Parser.tsAST ノード生成
Finalizer.tsOp[] 出力

コマンドレジストリ

commandRegistry.ts がすべてのコマンドの定義源。

登録済みコマンド

COMMAND_PARSERS には現在 約 60 種のコマンドが登録されている(カテゴリ別。Op 型は対応する代表値)。

カテゴリコマンド → Op
背景@bg→BG_SET(引数なしで BG_CLEAR)
キャラ(2D 立ち絵)@ch→CH_SET, @ch_anim→CH_ANIM, @ch_hide→CH_HIDE, @ch_clear→CH_CLEAR, @ch_move→CH_MOVE
キャラ表現(3系統共通)@ch_expr→CH_EXPR, @ch_lip→CH_LIP, @ch_motion→CH_MOTION, @ch_param→CH_PARAM, @ch_state→CH_STATE
Live2D@live2d→LIVE2D_SET, @live2d_hide→LIVE2D_HIDE, @live2d_motion→LIVE2D_MOTION, @live2d_expression→LIVE2D_EXPRESSION
VRM / 3D@sceneMode→SCENE_MODE, @vrmShow→VRM_SHOW, @vrmHide→VRM_HIDE, @vrmExpression→VRM_EXPRESSION, @vrmPose→VRM_POSE
音声@bgm→BGM_PLAY, @bgm_stop→BGM_STOP, @se→SE_PLAY, @voice→VOICE_PLAY, @wait_voice_end→WAIT_VOICE_END
待機@wait→WAIT_MS
オーバーレイ@overlay→OVERLAY_SET, @overlay_hide→OVERLAY_HIDE
演出・フィルター@filter(別名 @screenFilter)→SCREEN_FILTER, @filter_clear(別名 @screenFilterClear)→SCREEN_FILTER_CLEAR, @filter_mix→FILTER_MIX, @color_adjust→COLOR_ADJUST, @camera→CAMERA_SET, @shake→SHAKE, @flash→FLASH, @fade_black→FADE_BLACK, @fade_white→FADE_WHITE, @black_in→BLACK_IN, @white_in→WHITE_IN, @particle→PARTICLE_EMIT, @particle_stop→PARTICLE_STOP, @effect→EFFECT_PLAY, @slash→SLASH_EMIT, @scroll_text→SCROLL_TEXT, @text_style→TEXT_STYLE, @timeline_play→TIMELINE_PLAY
制御フロー@jump→JUMP, @call→CALL, @return→RETURN, @call_template→CALL_TEMPLATE, @layout_set→LAYOUT_SET
RPG(開発中・未公開)@battle→BATTLE_START, @map_load→MAP_LOAD, @map_exit→MAP_EXIT, @player_move→PLAYER_MOVE, @event_move→EVENT_MOVE, @item_add→ITEM_ADD, @item_remove→ITEM_REMOVE
スタンドアロン(テキスト内可)@l→WAIT_CLICK, @p→PAGE, @r→TEXT_NL(STANDALONE_PARSERS

補足: 選択肢・条件分岐・変数代入は @command ではなく行/ブロック構文で扱う。選択肢は choice { ... }(CHOICE op)、条件分岐は if (...) { ... }(JUMP_IF op)、変数代入は 名前 = 値 / += / -=(VAR_SET / VAR_ADD / VAR_SUB op)。@show @hide @move @fade @set @if といったコマンドは存在しない。

新コマンド追加手順

  1. commandRegistry.ts にパーサー関数を追加(COMMAND_PARSERS に登録。KNOWN_COMMAND_NAMES はここから自動導出)
  2. packages/core/src/types/Op.ts に Op 型を追加
  3. packages/web の OpHandler/OpRunner に実装を追加
  4. npm test -w @kaedevn/compiler で同期テスト確認

依存関係

内部パッケージ

  • @kaedevn/core (Op 型)

外部ライブラリ

  • commander (CLI)
  • ulid (ID 生成)

テスト

ファイル内容
tokenizer.test.tsトークン化テスト
lineClassifier.test.ts行タイプ判別テスト
phase2.test.tsパーサーテスト
phase3.test.tsトランスフォーマーテスト
phase5.test.tsファイナライザーテスト
command-sync.test.tsレジストリと lineClassifier の同期確認
validator.test.tsバリデーションテスト
integration.test.tsE2E コンパイルテスト

既知の注意点

  • lineClassifier.tsKNOWN_COMMANDS ホワイトリストがあり、新コマンドはここに追加しないと TEXT として分類される
  • テキストとコマンドが同じ行にある場合(例: テキスト@l)は別々のコマンドに分割される
  • インラインコマンド (@l, @c, @r) はテキスト内に埋め込まれる特殊形式
Ad: stickyBottom (728x90)
kaedevn - ノベルゲームを作れるプラットフォーム