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

4.9 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build & Run

# 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)

# 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)