aboutsummaryrefslogtreecommitdiff
path: root/AGENTS/EXTENDING.md
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-07-26 11:15:57 +0000
committer_ov4 <ov4@ov4.org>2026-07-26 11:15:57 +0000
commit0b4cdf7b28b3855d2dee18d91e9319d66a8ec25f (patch)
tree5b82182df4a08833f6c08065c70a7de2bdaba969 /AGENTS/EXTENDING.md
parent6d0165fd586739db2042b01be8301bdcb907091d (diff)
docs: add AGENTS/ architecture docs for AI-assisted development
ARCH.md holds the overview (pipeline, build/run, layout); details are split into CONVENTIONS.md, EXTENDING.md, SUBSYSTEMS.md and PITFALLS.md. All claims were verified against the source, most also empirically by compiling and running test programs. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS/EXTENDING.md')
-rw-r--r--AGENTS/EXTENDING.md37
1 files changed, 37 insertions, 0 deletions
diff --git a/AGENTS/EXTENDING.md b/AGENTS/EXTENDING.md
new file mode 100644
index 0000000..62cdf40
--- /dev/null
+++ b/AGENTS/EXTENDING.md
@@ -0,0 +1,37 @@
+# Extension recipes
+
+Step-by-step patterns for adding features. Read `CONVENTIONS.md` first — every recipe
+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
+`if (!Builder->GetInsertBlock()->getTerminator())` — a RETURN in the body may have
+already terminated the block.
+
+**New builtin function:** implement IR emission as a method on the fitting handler
+(String/Char/StringConversion), add the name intercept in `emitExpr`'s CallExprAST
+section with an arg-count check, **and** add the name to `getExprTypeInfo`'s table.
+Identifier-shaped names need nothing in lexer/parser.
+
+**New binary operator:** token (if multi-char) → one line in `BinopPrecedence`
+(Parser ctor; levels: OR=3, AND=5, comparisons=10, `+ - &`=20, `* / DIV MOD`=40;
+precedence must be > 0) → branch in `ArithmeticHandler::emitBinaryOp`, which owns *all*
+binary ops and dispatches on raw LLVM operand types.
+
+**New type:** register in `TypeSystem::registerBuiltins` (correct `ElementSize` —
+arrays malloc `count * ElementSize`) + `TypeKind` case + `getZeroValue` +
+`coerceValueToType` + `emitOutputValue` + INPUT branch in CodeGen + lexer keyword +
+`ParseTypeName` case.
+
+**New runtime check:** message global + `emitXxxCheck` in `RuntimeCheck` (build an i1
+fail-condition, call `emitErrorAndExit` — it splits the block and leaves the builder at
+the continuation), then call it from the emit site with the AST node's `getLine()`.
+Precedent: `emitIndexCheck`, called per-dimension from ArrayHandler. Note that failure
+messages print to **stdout** (`[Fatal] line %d: ...`) and `exit(1)`.
+
+**New libc dependency:** declare via `getOrInsertFunction` in the owning component's
+`setupExternalFunctions()` (re-declaring the same symbol in two handlers is fine — it
+dedupes by name).