aboutsummaryrefslogtreecommitdiff
path: root/AGENTS
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-07-26 12:11:00 +0000
committer_ov4 <ov4@ov4.org>2026-07-26 12:11:00 +0000
commitfdef2814d0d7e65573d1b666ae9bc561fa35a9f9 (patch)
tree043b9dbe477f85c82bb334d68363bc70196a9d47 /AGENTS
parent4a25b279d8f6c662fa8152cfe42e038d1ea06901 (diff)
refactor: extract ParseBlock/ParseExprList, resync-based error recovery
Seven copy-pasted statement-block loops collapse into ParseBlock(terminators); five comma-separated expression-list loops collapse into ParseExprList(close, allowEmpty), which also fixes "arr[1 2] <- x" being silently accepted as arr[1,2] on the statement path. Error recovery now lives in one place: syncToStatementStart skips to the next statement-start/block-end token, so a bad statement no longer swallows the first token of the following good one. Drop the dead -1000/-1001 token check in ParsePrototypeArgs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS')
-rw-r--r--AGENTS/CONVENTIONS.md6
-rw-r--r--AGENTS/EXTENDING.md8
-rw-r--r--AGENTS/PITFALLS.md8
3 files changed, 12 insertions, 10 deletions
diff --git a/AGENTS/CONVENTIONS.md b/AGENTS/CONVENTIONS.md
index e09b6ee..753be57 100644
--- a/AGENTS/CONVENTIONS.md
+++ b/AGENTS/CONVENTIONS.md
@@ -54,9 +54,9 @@ keep compiling.** No exceptions, no exit mid-compile. `Lexer`/`Parser`/`CodeGen`
expose `hadError()`; `CodeGen::reportError(fmt, ...)` is the helper for codegen-side
diagnostics (`ArrayHandler` reaches it through its `CodeGen &` parameter,
`FunctionGen`/`ArithmeticHandler` hold a `bool &HadError` reference). The driver exits
-non-zero when any flag is set. The parser still drops a failed statement, skips one
-token, and continues — later statements can be swallowed during recovery, but the
-failure is always diagnosed and reflected in the exit code.
+non-zero when any flag is set. The parser drops a failed statement and resyncs at the
+next token that can start a statement or end a block (`syncToStatementStart`), then
+continues; the failure is always diagnosed and reflected in the exit code.
**Calls dispatch on the declared signature.** `FunctionGen::emitPrototype` records every
function's pseudocode signature (`FuncSig`: return type name + per-param type name and
diff --git a/AGENTS/EXTENDING.md b/AGENTS/EXTENDING.md
index 3aab424..d5f9469 100644
--- a/AGENTS/EXTENDING.md
+++ b/AGENTS/EXTENDING.md
@@ -5,9 +5,11 @@ below assumes those invariants.
**New statement:** token in `Lexer.h` enum + keyword match in `Lexer.cc`'s if-chain →
node class in `AST.h` (unique_ptr children, move ctor, raw-ptr getters) → `ParseXxx` in
-`Parser.cc` + branch in `ParseStatement` (copy the existing body-loop pattern for block
-statements — terminator keyword + tok_eof guard) → `dynamic_cast` branch in
-`CodeGen::emitStmt`. Guard every fall-through branch in control-flow codegen with
+`Parser.cc` + branch in `ParseStatementImpl` (block statements parse their body with
+`ParseBlock({terminator tokens})`; comma-separated expression lists use
+`ParseExprList(close, allowEmpty)`; add the new statement's leading keyword to
+`syncToStatementStart`) → `dynamic_cast` branch in `CodeGen::emitStmt`. Guard every
+fall-through branch in control-flow codegen with
`if (!Builder->GetInsertBlock()->getTerminator())` — a RETURN in the body may have
already terminated the block.
diff --git a/AGENTS/PITFALLS.md b/AGENTS/PITFALLS.md
index 393f507..cd8cc92 100644
--- a/AGENTS/PITFALLS.md
+++ b/AGENTS/PITFALLS.md
@@ -7,10 +7,10 @@ test programs.
- **STRING `=` / `<>` compares pointer identity, not contents.** No strcmp anywhere;
two equal heap strings compare unequal.
-- **OUTPUT takes exactly one expression.** `OUTPUT a, ", ", b` silently drops everything
- after the comma — and if the dropped tail ends in an identifier, error recovery also
- swallows the first token of the *next* statement. Concatenate with `&`. Similarly
- INPUT only accepts a plain identifier — no `INPUT arr[i]`.
+- **OUTPUT takes exactly one expression.** `OUTPUT a, ", ", b` prints `a`, then the
+ stray `, ", ", b` produces parse errors (recovery resyncs at the next statement
+ start, so following statements survive; the compile still fails). Concatenate with
+ `&`. Similarly INPUT only accepts a plain identifier — no `INPUT arr[i]`.
- **Arrays cannot cross function boundaries.** `ArrayTable` is never scoped; metadata
SSA values belong to the declaring function, so referencing another function's array
produces invalid IR, and arrays can't be parameters.