diff options
Diffstat (limited to 'AGENTS')
| -rw-r--r-- | AGENTS/CONVENTIONS.md | 6 | ||||
| -rw-r--r-- | AGENTS/EXTENDING.md | 8 | ||||
| -rw-r--r-- | AGENTS/PITFALLS.md | 8 |
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. |
