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 扫描定位声明和引用
This commit is contained in:
2026-06-25 00:28:13 +08:00
parent 99c9e9c9bd
commit bdffe9e3c5
65 changed files with 1709 additions and 47 deletions
+46 -9
View File
@@ -5,20 +5,57 @@ This file provides guidance to Claude Code (claude.ai/code) when working with co
## Build & Run
```bash
# Build
# Build entire workspace
cargo build
# Run REPL (interactive)
cargo run
cargo run --bin aster
# Execute a script file
cargo run -- examples/script.ast
cargo run --bin aster -- aster-core/examples/script.ast
# Run tests (none yet; the project has no test/ directory)
# Run tests
cargo test
```
This is a pure-Rust project with no external dependencies (`edition = "2024"`).
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
@@ -28,20 +65,20 @@ This is a pure-Rust project with no external dependencies (`edition = "2024"`).
Source text → Lexer → Tokens → Parser → AST → Interpreter → Output
```
### Module map
### 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 comments. |
| `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`. |
| `main.rs` | Two modes: `run_file` (parse-then-execute, exits with code 65 on lex/parse errors, 70 on runtime errors) and `run_repl` (per-line evaluation with `:exit`/`:reset` commands). |
| `lib.rs` | Crate root — declares public modules, re-exports key types, provides `run_file()` and `run_repl()` convenience functions. |
### Key design decisions
- **No external crate dependencies.** Everything is built on Rust's stdlib.
- **`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.