Files
aster/CLAUDE.md
elmma bdffe9e3c5 feat: IDE支持 — workspace拆分、LSP服务器、VS Code扩展
**Workspace 拆分**
- aster-core: 纯库,zero-dependency,包含 lexer/parser/ast/interpreter/error/analysis
- aster: REPL 二进制,薄封装 aster-core
- aster-lsp: LSP 语言服务器

**VS Code 扩展 (vscode-ext/)**
- TextMate 语法高亮 (.ast 文件)
- 语言配置 (注释切换、括号配对、自动缩进)
- LSP 客户端 (extension.js)

**LSP 服务端功能**
- Diagnostics: 实时显示 lex/parse 错误红色波浪线
- Completion: 关键字 + 内置函数 + 用户定义符号补全
- Hover: 悬停显示变量/函数信息
- Signature Help: 函数参数提示
- Goto Definition: Ctrl+Click 跳转到声明处
- Find References: 查找所有引用位置
- Rename: F2 重命名符号

**新增 analysis 模块**
- collect_symbols: AST 遍历收集符号
- find_declaration/find_all_references: Token 扫描定位声明和引用
2026-06-25 00:28:13 +08:00

96 lines
4.9 KiB
Markdown

# CLAUDE.md
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
## Build & Run
```bash
# Build entire workspace
cargo build
# Run REPL (interactive)
cargo run --bin aster
# Execute a script file
cargo run --bin aster -- aster-core/examples/script.ast
# Run tests
cargo test
```
This is a Rust workspace. `aster-core` is a pure-Rust library with no external dependencies (`edition = "2024"`).
## Project structure
```
aster/
├── Cargo.toml # workspace root (aster-core, aster, aster-lsp)
├── aster-core/ # core library — lexer, parser, AST, interpreter
├── aster/ # REPL binary (thin wrapper around aster-core)
├── aster-lsp/ # LSP server (diagnostics, etc.)
└── vscode-ext/ # VS Code extension (syntax highlighting + LSP client)
```
## VS Code Extension
The `vscode-ext/` directory contains a VS Code extension that provides syntax highlighting and language server support for `.ast` files.
### Install (development)
```bash
# 1. Build the LSP server
cargo build --bin aster-lsp
# 2. Install extension npm dependencies
npm --prefix vscode-ext install
# 3. Register the extension in VS Code
# Windows: create junction
powershell -Command "New-Item -ItemType Junction -Path '$env:USERPROFILE\.vscode\extensions\aster-lang' -Target '$PWD\vscode-ext' -Force"
# macOS / Linux: symlink
ln -s "$PWD/vscode-ext" "$HOME/.vscode/extensions/aster-lang"
```
After installation, reload VS Code (`Ctrl+Shift+P` → "Developer: Reload Window"). Open any `.ast` file — syntax errors will appear as red squiggly underlines.
**Note:** The LSP server binary must be built (`cargo build --bin aster-lsp`) before the extension will work. After making changes to `aster-lsp`, rebuild and reload the VS Code window.
## Architecture
**Aster** is a tree-walking interpreter for a custom dynamically-typed scripting language. The pipeline follows the classic compiler frontend pattern:
```
Source text → Lexer → Tokens → Parser → AST → Interpreter → Output
```
### Module map (`aster-core/src/`)
| Module | Responsibility |
|---|---|
| `lexer/` | Tokenizer. `Lexer::tokenize()` takes `&str` and returns `(Vec<Token>, Vec<RuntimeError>)`. Tokens carry `line`/`column` for error reporting. Supports `//` single-line and `/* */` block comments. |
| `parser/` | Recursive-descent parser (Pratt-style for expressions). `Parser::parse()` returns `(Vec<Stmt>, Vec<RuntimeError>)`. Uses `synchronize()` for error recovery — skips to the next statement boundary on parse failure. |
| `ast/` | AST node definitions. `Expr` (in `expr.rs`) covers literals, variables, assignment, property access/indexing, unary/binary/logical ops, calls, lambdas, and object/array literals. `Stmt` (in `stmt.rs`) covers let, expression stmts, blocks, if/while/for, functions, return/break/continue. |
| `interpreter/` | Tree-walking evaluator. `Interpreter` holds an `env: Rc<RefCell<Env>>`. `Env` is a linked-list of scopes for lexical nesting. The `Signal` enum propagates `Return`/`Break`/`Continue` through the call stack. `builtins/` registers native functions (`print`, `input`, `clock`) organized as `io` and `os` modules (also available as global functions). |
| `error/` | Three error variants: `LexError` (line+column), `ParseError` (token), `RuntimeError` (optional token). All implement `Display` and `std::error::Error`. |
| `lib.rs` | Crate root — declares public modules, re-exports key types, provides `run_file()` and `run_repl()` convenience functions. |
### Key design decisions
- **`aster-core` has no external crate dependencies.** Everything is built on Rust's stdlib. `aster-lsp` depends on `lsp-server` + `lsp-types`.
- **Rc<RefCell<>> for shared ownership.** `Env` chains, `Value::Object`, `Value::Array`, and `Value::Function` all use `Rc<RefCell<>>` for interior mutability — matching the dynamic, garbage-collected feel without a GC.
- **Error-tolerant parsing.** Both lexer and parser collect errors into a `Vec` rather than failing on the first error, so multiple diagnostics can be reported per run.
- **Closures capture by environment.** `Function` structs store the `Env` at definition time; lambda expressions (`fn(params) { body }`) work the same way.
- **Compound assignment operators** (`+=`, `-=`, `*=`, `/=`, `%=`) are parsed into `Expr::Assign`/`Set`/`IndexSet` with an `AssignOp` variant and evaluated by `apply_assign_op`.
### Language syntax overview
Variables: `let x = 42;`
Functions: `fn add(a, b) { return a + b; }`
Closures: `fn(x, y) { return x + y; }`
Control flow: `if`/`while`/`for` (C-style), `break`/`continue`, `return`
Data: objects `{ key: val }`, arrays `[1, 2, 3]`, indexing `arr[i]`, property access `obj.prop`
Operators: `+ - * / %`, `== != < > <= >=`, `&& || !`, `= += -= *= /= %=`
Builtins: `print(...)`, `input(prompt?)`, `os.clock()` (also `clock()` directly)