Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
107 changes: 107 additions & 0 deletions .github/copilot-instructions.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
# Copilot Instructions for TRLC (Starter)

Use these instructions for any work in this repository.

## Project profile

- Repository: TRLC (Treat Requirements Like Code), Python reference
implementation plus docs and Bazel integration.
- Priorities: language correctness, deterministic behavior, and keeping spec/docs/tests aligned.
- Runtime constraints: Python 3.8–3.14 supported.

## Default workflow

1. Read nearby docs before changing behavior:
- `documentation/architecture.md`
- `documentation/dev_setup.md`
- `documentation/LRM.md` and `language-reference-manual/` for language-level changes
2. Prefer small, focused patches that solve root causes.
3. Prefer the target style below, even when surrounding code uses older patterns.
4. Introduce style migration incrementally in touched areas; avoid
broad no-op rewrites.

## Target style migration policy

Adopt the following style over time in production code:

- No `assert` statements for runtime behavior checks in production
paths; use explicit validation and errors.
- Prefer f-strings over `%` formatting and `.format(...)` for string interpolation.
- Do not use horizontal alignment for assignments, dict colons, or
similar layout; use regular Python spacing instead.
- Prefer smaller files and split toward one file per class where practical.
- Format code according to Black-compatible conventions.
- Class names shall no longer follow the Ada naming convention, but
shall be in PascalCase (e.g., `MyClass`).
- Function and method names shall be in snake_case (e.g., `my_function`).

Legacy TRLC code used runtime `assert` checks heavily; migrate away
incrementally by replacing them with explicit validation and proper
error handling in touched code.

When changing existing code, apply these rules in the edited scope where safe.
Old code may remain in legacy style until it is touched for other reasons.

## Environment and commands

Repo is migrating Make→Bazel: prefer Bazel; use Make only if no Bazel target exists.

## Change policy by area

### Python implementation (`trlc/`, `trlc.py`, utilities)

- Add or update tests for behavior changes (unit and/or system tests as appropriate).
- Preserve existing public API and CLI semantics unless task explicitly
requires a breaking change.
- Keep error messages and diagnostics stable where feasible (many tests assert exact output).

### Problem signaling with Message_Handler

- Use `Message_Handler` for all user-visible diagnostics in parser, lexer,
checker, and related tooling code. Do not introduce ad-hoc `print(...)`
based error/warning output.
- Prefer the dedicated API methods:
- `mh.error(location, message, explanation=None, fatal=True, user=False)`
for errors. Use `fatal=False` only when recovery is intentional.
- `mh.warning(location, message, explanation=None, user=False)` for
non-fatal warnings.
- `mh.check(location, message, check, explanation=None)` for lint/check
style findings that need a check category.
- `mh.lex_error(location, message)` for lexer-originated fatal errors.
- `mh.ice_loc(location, message)` only for internal-compiler-error paths.
- For user-facing diagnostics, do not leave `explanation` as `None` unless
there is truly no actionable guidance possible.
- Prefer explanations that help users fix the issue: describe what went
wrong, why it is invalid in this context, and the concrete next step.
- Keep explanations specific and stable (avoid vague text like "invalid"
without remediation guidance).
- Always pass a precise `Location` so diagnostics include source context.
- When an issue originates elsewhere, include
`mh.cross_file_reference(other_location)` in the explanation text to add
traceable cross-file context.
- Keep diagnostic wording concise and stable; many tests assert exact output.
- Count semantics are handled by `Message_Handler` (`warnings`, `errors`,
`suppressed`); do not duplicate manual counters in new code.

### Language and checker behavior

- If language semantics change, update both:
- language reference/manual sources in `language-reference-manual/` and/or `documentation/`
- relevant tests and expected outputs
- Keep code, docs, and traceability artifacts logically in sync in the same change.

## Guardrails

- Do not edit generated artifacts unless explicitly requested (for
example `docs/` HTML output files).
- Do not introduce new dependencies unless necessary; if added, update
the appropriate requirements files.
- Avoid broad renames/moves unless the task specifically asks for structural changes.
- Keep commits/patches atomic: code + tests + docs that belong to the
same behavior change.

## Expected Copilot output style

- Explain assumptions briefly when requirements are ambiguous.
- Propose the smallest safe implementation first.
- After edits, run the narrowest relevant checks first, then broader checks if needed.
21 changes: 7 additions & 14 deletions documentation/architecture.md
Original file line number Diff line number Diff line change
Expand Up @@ -14,26 +14,19 @@ is a good place to start.
Most of these are checked with `make lint`. Generally normal Python,
with some changes:

* Class names follow Ada naming convention (e.g. LASER_Is_An_Acronym)
* Methods are lowercase with underscores (e.g. eat_potato)
* Just use simple `%` string formatting
* Horizontal alignment where reasonable, for example
* Use regular Python spacing (no horizontal alignment), for example

```python
x = {
"potatos" : 12,
"cats" : 3,
"potatos": 12,
"cats": 3,
}
```

* Asserts for the types of all parameters (except self), for all
functions or methods, all the time, e.g:

```python
def do_something(self, other, thing=None):
assert isinstance(thing, str) or thing is None
assert isinstance(other, Some_Object)
```
* Do not use `assert` statements for runtime behavior checks in
production code paths. Use explicit validation and proper error
handling through the existing TRLC error/message interfaces, or
raise exceptions.

* Never assume anything in conditions, always deal with all cases. In
practice this means the final else clause in an if statement that
Expand Down
Loading