CRusTTY:一个具有时间旅行调试能力的教学型C语言解释器。
CRusTTY: A pedagogical C interpreter with time-travel debugging capabilities

原始链接: https://github.com/aicheye/crustty

## CRusTTY:一种C语言学习工具 CRusTTY是一个用Rust构建的C语言教学解释器,旨在帮助用户理解C程序执行过程。它具有基于终端的用户界面,并提供交互式、时间旅行调试功能。用户可以逐行执行代码,在执行历史中前进和后退,并实时可视化内存(栈和堆)以及程序输出。 该解释器支持C语言的核心概念,例如数据类型(int、char、结构体、指针、数组)、控制流(if/else、循环、switch)和运算符。它包含内置函数,如`printf`、`scanf`、`malloc`和`free`。 用户界面分为多个窗格,分别显示源代码、调用栈、堆内存、终端输出和状态栏,其中包含关键绑定。CRusTTY适用于Windows、macOS和Linux。 虽然它不是一个完整的C编译器,但它通过其专注的设计和详细的执行可视化提供了一个宝贵的学习环境。它使用模块化的Rust代码库构建,强调可维护性,并包含全面的测试。

黑客新闻 新 | 过去 | 评论 | 提问 | 展示 | 招聘 | 提交 登录 CRusTTY: 一个带有时间旅行调试能力的教学型C语言解释器 (github.com/aicheye) 5 分,由 varun_ch 1小时前发布 | 隐藏 | 过去 | 收藏 | 讨论 帮助 指南 | 常见问题 | 列表 | API | 安全 | 法律 | 申请YC | 联系 搜索:
相关文章

原文

A pedagogical C interpreter with time-travel debugging capabilities, built in Rust with a terminal-based UI.

CRusTTY Screenshot

CRusTTY is an educational tool for understanding C program execution. It provides:

  • Interactive Execution: Step through C code line by line
  • Time-Travel Debugging: Step backward and forward through execution history
  • Memory Visualization: Real-time view of stack and heap memory
  • Terminal Output: See printf output as your program runs
  • Data Types: int, char, void, structs, pointers, arrays
  • Control Flow: if/else, while, for, do-while, switch/case
  • Operators: Arithmetic, logical, bitwise, comparison, ternary
  • Memory: Stack-based local variables, dynamic heap allocation via malloc/free
  • Built-ins: printf and scanf (with format specifiers), malloc, free, sizeof

The terminal interface provides multiple panes:

  • Source Code: Syntax-highlighted C code with execution line indicator
  • Stack: Call stack with local variables and their values
  • Heap: Dynamic memory allocations with type information
  • Terminal: Output from printf and input prompts from scanf
  • Status Bar: Keybindings and execution state
  • n / Space: Step forward
  • b: Step backward
  • c: Continue execution
  • r: Restart program
  • q: Quit
  • esc: Exit input mode (in scanf input prompt)
  • Arrow keys: Navigate through stack/heap panes

Precompiled binaries for the following platforms will be available in the releases section of the GitHub repository:

  • Windows (x86_64 and ARM)
  • macOS (x86_64 and ARM)
  • Linux (x86_64 and ARM)

Download the appropriate binary (.zip) for your platform, extract it, and add the directory containing the binary to your PATH.

crustty <source.c | example_name>

Examples:

# Run the bundled comprehensive example (features demo)
crustty default

# Run your own C file
crustty path/to/your/file.c
  • Rust toolchain (1.70 or later)
  • Terminal with Unicode and color support

The binary will be available at target/release/crustty.

The codebase is organized into focused modules for maintainability:

src/
├── main.rs                     # Entry point and CLI argument handling
├── lib.rs                      # Library root and public API
│
├── parser/                     # C parser (source → AST)
│   ├── mod.rs                  # Module overview
│   ├── lexer.rs                # Tokenizer: source text → Token stream
│   ├── parse.rs                # Parser entry point (Parser struct)
│   ├── declarations.rs         # Struct/function declaration parsing
│   ├── statements.rs           # Statement parsing
│   ├── expressions.rs          # Expression parsing with precedence climbing
│   └── ast.rs                  # AST node type definitions
│
├── interpreter/                # C interpreter (AST → execution)
│   ├── mod.rs                  # Module overview and execution model docs
│   ├── engine.rs               # Interpreter struct, run(), rewind(), snapshots
│   ├── statements.rs           # Statement dispatch (if, while, decl, …)
│   ├── expressions.rs          # Expression evaluation (largest file)
│   ├── builtins.rs             # Built-in functions (printf, scanf, malloc, free)
│   ├── type_system.rs          # Type inference helpers
│   ├── loops.rs                # while / do-while / for loop execution
│   ├── jumps.rs                # return / switch execution
│   ├── heap_serial.rs          # Value ↔ heap byte serialization
│   ├── errors.rs               # RuntimeError enum
│   ├── constants.rs            # Address-space constants
│   └── ops/                    # Operator implementations (impl Interpreter)
│       ├── mod.rs              # Submodule declarations
│       ├── binary.rs           # Arithmetic, comparison, bitwise, compound-assign
│       ├── unary.rs            # Negation, NOT, increment/decrement
│       ├── assign.rs           # Assignment to lvalues
│       ├── access.rs           # Reading lvalues and resolving addresses
│       └── structs.rs          # Struct initialization and field-offset helpers
│
├── memory/                     # Runtime memory model
│   ├── mod.rs                  # sizeof, pointer arithmetic helpers
│   ├── stack.rs                # Call frames and local variables
│   ├── heap.rs                 # First-fit heap allocator
│   └── value.rs                # Value enum (Int, Char, Pointer, Struct, …)
│
├── snapshot/                   # Time-travel debugging
│   └── mod.rs                  # Snapshot, SnapshotManager, MockTerminal
│
└── ui/                         # Terminal UI (ratatui + crossterm)
    ├── mod.rs                  # Module re-exports
    ├── app.rs                  # App struct, event loop, pane focus, scanf input
    ├── theme.rs                # Color palette (DEFAULT_THEME)
    └── panes/                  # Stateless pane render functions
        ├── mod.rs              # Re-exports for all pane modules
        ├── source.rs           # Syntax-highlighted source code pane
        ├── stack.rs            # Call stack visualization pane
        ├── heap.rs             # Heap block visualization pane
        ├── terminal.rs         # printf / scanf terminal output pane
        ├── status.rs           # Status bar (keybindings, step counter)
        └── utils/              # Shared rendering helpers
            ├── mod.rs          # Re-exports from submodules
            ├── formatting.rs   # Value/address formatting
            ├── memory.rs       # Stack/heap data extraction helpers
            └── rendering.rs    # Low-level ratatui span/line builders

Hand-written recursive descent parser with:

  • Precedence climbing for binary operators
  • Comprehensive error reporting with source locations
  • Full AST representation of program structure

Executes the AST with:

  • Stack-based execution with call frames
  • Heap memory allocator with block tracking
  • Snapshot system capturing execution state after each statement
  • Specific error types for clear diagnostics

The interpreter code is split across focused submodules: engine.rs owns the core loop and public API; operator evaluation lives under ops/; loop control flow in loops.rs; jump-style control flow (return, switch) in jumps.rs; and heap serialization in heap_serial.rs.

  • Stack: Local variables, function parameters, return addresses
    • Address space: 0x0000_0004 and up (sequential variable IDs per frame)
  • Heap: Dynamic allocations via malloc
    • Address space: 0x7fff_0000 and up
    • First-fit allocation strategy

The two regions occupy non-overlapping address ranges so the TUI can distinguish stack and heap pointers without type annotation, and pointer arithmetic can be range-checked cheaply.

The interpreter maintains a history of execution snapshots, each containing:

  • Complete stack state
  • Complete heap state
  • Terminal output
  • Current source location

This enables stepping backward through execution to any previous point.

Performance Optimizations

Recent optimizations include:

  • Inline Hints: Hot-path functions marked with #[inline]
  • Field Caching: Struct field offsets cached to avoid recomputation
  • Fast Hashing: FxHashMap used for non-cryptographic hashing needs
# Unit tests
cargo test --lib

# Integration tests
cargo test --test '*'

# All tests
cargo test
# Format code
cargo fmt

# Run linter
cargo clippy -- -D warnings

# Check build
cargo check
  • rustfmt.toml: Code formatting rules
  • Cargo.toml: Dependencies and build configuration

This is NOT a production C interpreter:

  • Subset of C (no preprocessor, typedefs, unions, enums, function pointers)
  • No optimization or JIT compilation
  • Limited standard library (only built-in functions)
  • No file I/O or external system interaction
  • Fixed memory sizes

MIT License. See LICENSE.md file for details.

联系我们 contact @ memedata.com