Skip to content

Repository files navigation

C# Tutor — C#コード実行の可視化ツール

Python Tutor の C# 版。C# のコードを1行ずつ実行し、変数・スタックフレーム・ヒープ上のオブジェクト・参照の矢印を可視化して、初心者がプログラムの動きを「目で見て」理解できるようにする教育用ツールです。

すべてブラウザ内で完結します(サーバー不要・静的サイトとして配布可能)。

struct と class の違いの可視化

再帰呼び出しのフレーム積み上げ

使い方

npm install
npm run dev      # 開発サーバー (http://localhost:5173)
npm test         # 意味論テスト(88件)
npm run build    # 本番ビルド(dist/ に静的ファイルを出力)
  • 左のエディタに C# コードを書き「▶ 実行して可視化」(Ctrl/⌘ + Enter
  • ◀ 前へ / 次へ ▶・スライダー・←→ キー・自動再生でステップを前後に移動
  • コードの行をクリックするとその行を実行するステップへジャンプ
  • スライダー上のタイムラインマーカー(緑=出力 / 紫=メソッド呼び出し / 赤=例外)をクリックしてイベントへ直行
  • 参照の ● やヒープのオブジェクトにマウスを載せると、関係する矢印と実体が強調表示され、「どの変数がどれを指しているか」が一目で分かる
  • 各ステップで「解説」パネルが何が起きたかを日本語で説明(参照の共有・struct のコピーも明示)
  • Console.ReadLine() は画面下の「標準入力」欄から1行ずつ読み取り
  • ヘッダーの「サンプル」から14個の教材プログラムを読み込み可能

画面の見かた

表示 意味
赤い ▶ 次に実行する行
緑の ▶ 直前に実行した行
ティール色のチップ 値型(int / double / bool / char / struct)— 変数の箱に値が直接入る
● → 矢印 参照型(配列 / List / Dictionary / クラス)— ヒープ上の実体を指す
「共有」バッジ ref / out 引数で呼び出し元と同じ変数を共有している
「実行中」バッジ スタックの最上段(現在実行中のフレーム)

※ string は C# では参照型ですが、不変であるため表示の分かりやすさを優先して値のように表示しています(凡例にも明記)。

対応している C# の構文

  • エントリポイント: トップレベル文 / class Program { static void Main() } / namespace 内の Main(どれでも可)
  • : int long double(float/decimal は double として扱う) bool char string var object、配列・ジャグ配列、List<T>Dictionary<K,V>
  • 制御構文: if/else for while do-while foreach switch(フォールスルー禁止も検査)break continue return
  • : 算術・比較・論理・ビット演算、++/--、複合代入、三項演算子、?? ??= ?.、文字列補間 $"{x:F2}"、複合書式 "{0}"、キャスト、is / as
  • メソッド: トップレベル関数・クラスメソッド、オーバーロード、デフォルト引数、ref / outout var 含む)、再帰
  • クラス / struct: フィールド、コンストラクタ(: base(...) 連鎖)、自動プロパティ、式形式プロパティ / メソッド、静的メンバー・const、オブジェクト初期化子・コレクション初期化子
  • 継承: virtual / override(object の ToString 含む)、base.、アップ/ダウンキャスト
  • 例外: try/catch/finallythrow、組み込み例外の階層(ExceptionDivideByZeroException など)、ユーザー定義例外
  • 標準ライブラリ(抜粋): Console.WriteLine/Write/ReadLineMath.*Round は偶数丸め)、string の主要メソッド、int.Parse/TryParseConvert.*Array.Sort/Reverse/IndexOfstring.Join/IsNullOrEmpty

未対応(使うと日本語エラーで案内します): LINQ、ラムダ式・デリゲート、interfaceenumabstract、async/await、ユーザー定義ジェネリック、多次元配列 [,]、null許容型 int?、パターンマッチング、本体付きプロパティアクセサ、入れ子クラス など

貼り付けへの耐性

Visual Studio や Web からのコピペをそのまま動かせるよう、次を吸収します。

  • namespace(ブロック / ファイルスコープ)・using ディレクティブ・internal などの修飾子
  • 属性 [STAThread]#region / #pragma などのプリプロセッサ指令は読み飛ばし
  • Console.ReadKey() / Console.Clear() は何もしない扱い(エラーにしない)
  • String / Int32 / Boolean などの .NET 型名エイリアス、string.FormatEnvironment.NewLine
  • 全角スペースは C# の仕様どおり空白として受理。全角記号( など)や曲がった引用符(“ ”)は直し方つきの日本語エラーで案内
  • static を忘れた Main、小文字の main、クラス定義だけの貼り付けにも、始め方をエラーメッセージで案内

C# 意味論の再現(テストで担保)

「本物の C# で動かしたら結果が違う」を避けるため、以下を vitest の意味論テスト(88件)で検証しています。

  • 整数除算の切り捨て(7 / 2 == 3-7 / 2 == -3)と 0 除算の DivideByZeroException
  • int の 32bit ラップ(int.MaxValue + 1 == int.MinValueMath.imul による乗算)
  • struct は代入・引数渡し・returnでコピーclass参照共有(structメソッドの this 書き戻しも再現)
  • ref / out は変数スロットの共有として実装(トレース上でエイリアス検出可能)
  • bool の出力は True / Falsedouble は最短ラウンドトリップ表記(2.0"2"1/0.0"∞"
  • Math.Round(2.5) == 2(偶数丸め)、Convert.ToInt32 も同様
  • foreach 中のコレクション変更で InvalidOperationException
  • 未代入ローカル変数の使用・型不一致の代入などは「C# ではコンパイルエラー」として実行時に日本語で報告
  • List の要素(struct)への直接フィールド代入はエラー(C# のコンパイルエラーを再現)

既知の簡略化: long は JS の安全整数範囲で扱う(64bitラップなし)/文字列の並び替え・比較は序数ベース/書式指定はカルチャ非依存の簡易実装/非virtualメソッドの隠蔽(new)は動的解決になる、など。

アーキテクチャ

コード文字列
  → lexer.ts   字句解析(エディタのハイライトにも共用)
  → parser.ts  再帰下降構文解析 → AST
  → interpreter.ts  ツリーウォーク実行
       各文の実行前にスナップショットを記録(Python Tutor 方式)
  → trace(自己完結なステップ配列: 行番号・スタック・ヒープ・累積stdout)
  → React UI がトレースを前後に再生するだけ(逆方向ステップが自由)
パス 役割
src/interpreter/ 字句解析・構文解析・実行エンジン・組み込みAPI・トレース型
src/interpreter/semantics.test.ts C# 意味論の回帰テスト
src/explain/explain.ts ステップ間の差分から日本語の解説文を生成
src/examples/ 教材サンプル14本(全て自動テストで実行可能性を担保)
src/ui/ エディタ・コードビュー・状態キャンバス・操作パネル

実行トレースは1ステップごとに完全な状態を持つため、UI は単なる「再生機」です。ステップ上限(既定1500)とヒープ上限で無限ループ・メモリ暴走から保護しています。

ライセンス・クレジット

  • UI・トレース形式の設計は Python Tutor(Philip Guo 氏)のアイデアに基づきます
  • 依存ライブラリ: React / Tailwind CSS / shadcn+ui(Radix UI・lucide-react ほか)(開発時: Vite / TypeScript / vitest)

About

C#コードの実行を1行ずつ可視化する教育用ツール

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages