Skip to content

Commit 394ddaa

Browse files
authored
Overhauled AGENTS.md (#7897)
1 parent 83aa0bc commit 394ddaa

File tree

1 file changed

+207
-89
lines changed

1 file changed

+207
-89
lines changed

AGENTS.md

Lines changed: 207 additions & 89 deletions
Original file line numberDiff line numberDiff line change
@@ -1,47 +1,184 @@
1-
# CLAUDE.md
1+
# AGENTS.md
22

3-
This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
3+
This file provides guidance to AI coding assistants when working with code in this repository.
44

5-
## Project Overview
5+
## Quick Start: Essential Commands
66

7-
This is the ReScript compiler repository - a robustly typed language that compiles to efficient and human-readable JavaScript. ReScript is built using OCaml and includes a complete toolchain with compiler, build system, syntax parser, and standard library.
7+
```bash
8+
# Build and test
9+
make && make test
10+
11+
# Format and check code
12+
make format && make checkformat
13+
```
14+
15+
## ⚠️ Critical Guidelines & Common Pitfalls
16+
17+
- **We are NOT bound by OCaml compatibility** - The ReScript compiler originated as a fork of the OCaml compiler, but we maintain our own AST and can make breaking changes. Focus on what's best for ReScript's JavaScript compilation target.
18+
19+
- **Never modify `parsetree0.ml`** - Existing PPX (parser extensions) rely on this frozen v0 version. When changing `parsetree.ml`, always update the mapping modules `ast_mapper_from0.ml` and `ast_mapper_to0.ml` to maintain PPX compatibility while allowing the main parsetree to evolve
20+
21+
- **Missing test coverage** - Always add tests for syntax, lambda, and end-to-end behavior
22+
23+
- **Test early and often** - Add tests immediately after modifying each compiler layer to catch problems early, rather than waiting until all changes are complete
24+
25+
- **Use underscore patterns carefully** - Don't use `_` patterns as lazy placeholders for new language features that then get forgotten. Only use them when you're certain the value should be ignored for that specific case. Ensure all new language features are handled correctly and completely across all compiler layers
26+
27+
- **Be careful with similar constructor names across different IRs** - Note that `Lam` (Lambda IR) and `Lambda` (typed lambda) have variants with similar constructor names like `Ltrywith`, but they represent different things in different compilation phases.
28+
29+
- **Avoid warning suppressions** - Never use `[@@warning "..."]` to silence warnings. Instead, fix the underlying issue properly
30+
31+
- **Do not introduce new keywords unless absolutely necessary** - Try to find ways to implement features without reserving keywords, as seen with the "catch" implementation that avoids making it a keyword.
32+
33+
## Compiler Architecture
34+
35+
### Compilation Pipeline
36+
37+
```
38+
ReScript Source (.res)
39+
↓ (ReScript Parser - compiler/syntax/)
40+
Surface Syntax Tree
41+
↓ (Frontend transformations - compiler/frontend/)
42+
Surface Syntax Tree
43+
↓ (OCaml Type Checker - compiler/ml/)
44+
Typedtree
45+
↓ (Lambda compilation - compiler/core/lam_*)
46+
Lambda IR
47+
↓ (JS compilation - compiler/core/js_*)
48+
JS IR
49+
↓ (JS output - compiler/core/js_dump*)
50+
JavaScript Code
51+
```
52+
53+
### Key Directory Structure
54+
55+
```
56+
compiler/
57+
├── syntax/ # ReScript syntax parser (MIT licensed)
58+
├── frontend/ # AST transformations, FFI processing
59+
├── ml/ # OCaml compiler infrastructure
60+
├── core/ # Core compilation (lam_*, js_* files)
61+
├── ext/ # Extended utilities and data structures
62+
├── bsb/ # Legacy build system
63+
└── gentype/ # TypeScript generation
64+
65+
analysis/ # Language server and tooling
66+
packages/@rescript/
67+
├── runtime/ # Runtime and standard library
68+
└── <platform>/ # Platform-specific binaries
69+
70+
tests/
71+
├── syntax_tests/ # Parser/syntax layer tests
72+
├── tests/ # Runtime library tests
73+
├── build_tests/ # Integration tests
74+
└── ounit_tests/ # Compiler unit tests
75+
```
76+
77+
## Working on the Compiler
78+
79+
### Development Workflow
80+
81+
1. **Understand which layer you're working on:**
82+
- **Syntax layer** (`compiler/syntax/`): Parsing and surface syntax
83+
- **ML layer** (`compiler/ml/`): Type checking and AST transformations
84+
- **Lambda layer** (`compiler/core/lam_*`): Intermediate representation and optimizations
85+
- **JS layer** (`compiler/core/js_*`): JavaScript generation
86+
87+
2. **Always run appropriate tests:**
88+
```bash
89+
# For compiler or stdlib changes
90+
make test
91+
92+
# For syntax changes
93+
make test-syntax
94+
95+
# For specific test types
96+
make test-syntax-roundtrip
97+
make test-gentype
98+
make test-analysis
99+
```
100+
101+
3. **Test your changes thoroughly:**
102+
- Syntax tests for new language features
103+
- Integration tests for behavior changes
104+
- Unit tests for utility functions
105+
- Always check JavaScript output quality
106+
107+
### Debugging Techniques
8108

9-
## Build Commands
109+
#### View Intermediate Representations
110+
```bash
111+
# Source code (for debugging preprocessing)
112+
./cli/bsc.js -dsource myfile.res
113+
114+
# Parse tree (surface syntax after parsing)
115+
./cli/bsc.js -dparsetree myfile.res
116+
117+
# Typed tree (after type checking)
118+
./cli/bsc.js -dtypedtree myfile.res
119+
120+
# Raw lambda (unoptimized intermediate representation)
121+
./cli/bsc.js -drawlambda myfile.res
122+
123+
# Use lambda printing for debugging (add in compiler/core/lam_print.ml)
124+
```
125+
126+
#### Common Debug Scenarios
127+
- **JavaScript formatting issues**: Check `compiler/ml/pprintast.ml`
128+
- **Type checking issues**: Look in `compiler/ml/` type checker modules
129+
- **Optimization bugs**: Check `compiler/core/lam_*.ml` analysis passes
130+
- **Code generation bugs**: Look in `compiler/core/js_*.ml` modules
131+
132+
### Testing Requirements
133+
134+
#### When to Add Tests
135+
- **Always** for new language features
136+
- **Always** for bug fixes
137+
- **When modifying** analysis passes
138+
- **When changing** JavaScript generation
139+
140+
#### Test Types to Include
141+
1. **Syntax tests** (`tests/syntax_tests/`) - Parser validation
142+
2. **Integration tests** (`tests/tests/`) - End-to-end behavior
143+
3. **Unit tests** (`tests/ounit_tests/`) - Compiler functions
144+
4. **Build tests** (`tests/build_tests/`) - Error cases and edge cases
145+
5. **Type tests** (`tests/build_tests/super_errors/`) - Type checking behavior
146+
147+
## Build Commands & Development
10148

11-
### Basic Development
149+
### Essential Commands
12150
```bash
13-
# Build compiler and copy executables
151+
# Build compiler
14152
make
15153

16-
# Build in watch mode
154+
# Build compiler in watch mode
17155
make watch
18156

19-
# Build everything including standard library
157+
# Build compiler and standard library
20158
make lib
21159

160+
# Build compiler and standard library and run all tests
161+
make test
162+
22163
# Build artifacts and update artifact list
23164
make artifacts
165+
166+
# Clean build
167+
make clean
24168
```
25169

26-
### Testing
170+
### Testing Commands
27171
```bash
28-
# Run all tests
29-
make test
30-
31-
# Run specific test types
172+
# Specific test types
32173
make test-syntax # Syntax parser tests
33-
make test-syntax-roundtrip # Roundtrip syntax tests
174+
make test-syntax-roundtrip # Roundtrip syntax tests
34175
make test-gentype # GenType tests
35176
make test-analysis # Analysis tests
36177
make test-tools # Tools tests
37178
make test-rewatch # Rewatch tests
38179

39-
# Run single file test
40-
./cli/bsc.js myTestFile.res
41-
42-
# View parse/typed trees for debugging
43-
./cli/bsc.js -dparsetree myTestFile.res
44-
./cli/bsc.js -dtypedtree myTestFile.res
180+
# Single file debugging
181+
./cli/bsc.js myfile.res
45182
```
46183

47184
### Code Quality
@@ -56,84 +193,65 @@ make checkformat
56193
npm run check
57194
npm run check:all
58195

59-
# TypeScript type checking
196+
# TypeScript type checking
60197
npm run typecheck
61198
```
62199

63-
### Clean Operations
64-
```bash
65-
make clean # Clean OCaml build artifacts
66-
make clean-all # Clean everything including Rust/gentype
67-
```
68-
69-
## Compiler Architecture
70-
71-
The ReScript compiler follows this high-level pipeline:
72-
73-
```
74-
ReScript Source (.res)
75-
↓ (ReScript Parser - compiler/syntax/)
76-
Surface Syntax Tree
77-
↓ (Frontend transformations - compiler/frontend/)
78-
Surface Syntax Tree
79-
↓ (OCaml Type Checker - compiler/ml/)
80-
Typedtree
81-
↓ (Lambda compilation - compiler/core/lam_*)
82-
Lambda IR
83-
↓ (JS compilation - compiler/core/js_*)
84-
JS IR
85-
↓ (JS output - compiler/core/js_dump*)
86-
JavaScript Code
87-
```
88-
89-
### Key Directories
90200

91-
- **`compiler/syntax/`** - ReScript syntax parser (MIT licensed, separate from main LGPL)
92-
- **`compiler/frontend/`** - AST transformations, external FFI processing, built-in attributes
93-
- **`compiler/ml/`** - OCaml compiler infrastructure (type checker, typedtree, etc.)
94-
- **`compiler/core/`** - Core compilation:
95-
- `lam_*` files: Lambda IR compilation and optimization passes
96-
- `js_*` files: JavaScript IR and code generation
97-
- **`compiler/ext/`** - Extended utilities and data structures
98-
- **`compiler/bsb/`** - Build system implementation
99-
- **`compiler/gentype/`** - TypeScript generation
100-
- **`runtime/`** - ReScript standard library (written in ReScript)
101-
- **`lib/`** - Compiled JavaScript output of standard library
102-
- **`analysis/`** - Language server and tooling support
201+
## Performance Considerations
103202

104-
### Build System Components
203+
The compiler is designed for fast feedback loops and scales to large codebases:
105204

106-
- **`compiler/bsb_exe/`** - Main ReScript build tool entry point
107-
- **`compiler/bsc/`** - Compiler binary entry point
108-
- **`rewatch/`** - File watcher (written in Rust)
109-
- **`ninja/`** - Vendored Ninja build system
110-
111-
## Development Setup Notes
112-
113-
- Uses OCaml 5.3.0+ with opam for compiler development
114-
- Uses dune as build system with specific profiles (dev, release, browser)
115-
- Node.js 20+ required for JavaScript tooling
116-
- Rust toolchain needed for rewatch file watcher
117-
- Python ≤3.11 required for building ninja
205+
- **Avoid meaningless symbols** in generated JavaScript
206+
- **Maintain readable JavaScript output**
207+
- **Consider compilation speed impact** of changes
208+
- **Use appropriate optimization passes** in Lambda and JS IRs
209+
- **Profile** before and after performance-related changes
118210

119211
## Coding Conventions
120212

213+
### Naming
121214
- **OCaml code**: snake_case (e.g., `to_string`)
122215
- **ReScript code**: camelCase (e.g., `toString`)
123-
- Use DCO sign-off for all commits: `Signed-Off-By: Your Name <email>`
124-
125-
## Testing Strategy
126216

127-
- **Mocha tests** (`tests/tests/`) - Runtime library unit tests
128-
- **Build system tests** (`tests/build_tests/`) - Integration tests
129-
- **OUnit tests** (`tests/ounit_tests/`) - Compiler unit tests
130-
- **Expectation tests** - Plain `.res` files that check compilation output
131-
- Always include appropriate tests with new features/changes
217+
### Commit Standards
218+
- Use DCO sign-off: `Signed-Off-By: Your Name <email>`
219+
- Include appropriate tests with all changes
220+
- Build must pass before committing
132221

133-
## Performance Notes
134-
135-
The compiler is designed for fast feedback loops and scales to large codebases. When making changes:
136-
- Avoid introducing meaningless symbols
137-
- Maintain readable JavaScript output
138-
- Consider compilation speed impact
139-
- Use appropriate optimization passes in the Lambda and JS IRs
222+
### Code Quality
223+
- Follow existing patterns in the codebase
224+
- Prefer existing utility functions over reinventing
225+
- Comment complex algorithms and non-obvious logic
226+
- Maintain backward compatibility where possible
227+
228+
## Development Environment
229+
230+
- **OCaml**: 5.3.0+ with opam
231+
- **Build System**: dune with profiles (dev, release, browser)
232+
- **JavaScript**: Node.js 20+ for tooling
233+
- **Rust**: Toolchain needed for rewatch
234+
- **Python**: 3 required for building ninja
235+
236+
## Common Tasks
237+
238+
### Adding New Language Features
239+
1. Update parser in `compiler/syntax/`
240+
2. Update AST definitions in `compiler/ml/`
241+
3. Implement type checking in `compiler/ml/`
242+
4. Add Lambda IR handling in `compiler/core/lam_*`
243+
5. Implement JS generation in `compiler/core/js_*`
244+
6. Add comprehensive tests
245+
246+
### Debugging Compilation Issues
247+
1. Identify which compilation phase has the issue
248+
2. Use appropriate debugging flags (`-dparsetree`, `-dtypedtree`)
249+
3. Check intermediate representations
250+
4. Add debug output in relevant compiler modules
251+
5. Verify with minimal test cases
252+
253+
### Working with Lambda IR
254+
- Remember Lambda IR is the core optimization layer
255+
- All `lam_*.ml` files process this representation
256+
- Use `lam_print.ml` for debugging lambda expressions
257+
- Test both with and without optimization passes

0 commit comments

Comments
 (0)