aboutsummaryrefslogtreecommitdiff
path: root/AGENTS
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-27 14:07:24 +0000
committer_ov4 <ov4@ov4.org>2026-10-27 14:07:24 +0000
commitcaa88a9b36d9e1dfae40ecb31aee05bc2891fa17 (patch)
treed41168dc0799c6f8b033a3d6fdb2c2c72aac2b42 /AGENTS
parent5d37ebcc02f6ca2ce1ced93f803dd1daf634d866 (diff)
docs(preprocessor): document switches and library regions
Add manuals and aliases for all five PP directives, replace the retired #LIB page, and update compiler and shared-editor architecture notes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS')
-rw-r--r--AGENTS/ARCH.md4
-rw-r--r--AGENTS/ARCH/DRIVER.md3
-rw-r--r--AGENTS/ARCH/LAYOUT.md1
-rw-r--r--AGENTS/ARCH/OVERVIEW.md10
-rw-r--r--AGENTS/CONVENTIONS/EXCEPTIONS_AND_UNITS.md14
-rw-r--r--AGENTS/CONVENTIONS/LEXING.md13
-rw-r--r--AGENTS/EXTENDING.md2
-rw-r--r--AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md4
-rw-r--r--AGENTS/SUBSYSTEMS/MEMORY.md4
-rw-r--r--AGENTS/SUBSYSTEMS/STDLIB.md6
-rw-r--r--AGENTS/SUBSYSTEMS/TEMPLATES.md2
11 files changed, 42 insertions, 21 deletions
diff --git a/AGENTS/ARCH.md b/AGENTS/ARCH.md
index 1474fac..4926b52 100644
--- a/AGENTS/ARCH.md
+++ b/AGENTS/ARCH.md
@@ -5,7 +5,7 @@ This file is an index; the detail lives in `AGENTS/ARCH/`.
| File | Contents |
|---|---|
-| [OVERVIEW.md](ARCH/OVERVIEW.md) | Three-stage pipeline, fixed value representation (ABI), C interop types, pointer to language manuals |
+| [OVERVIEW.md](ARCH/OVERVIEW.md) | Preprocessing and compiler pipeline, fixed value representation (ABI), C interop types, pointer to language manuals |
| [BUILD.md](ARCH/BUILD.md) | Build and run commands, run modes, exception ABI, runtime errors, CI overview |
| [DEPENDENCIES.md](ARCH/DEPENDENCIES.md) | Local/system dependency lookup, compiler selection, MSYS2 notes, LLVM 23 pin |
| [DRIVER.md](ARCH/DRIVER.md) | `tools/driver/main.cc`: options, multi-file inputs, entry points, output and exit-code rules, PATH/NONE modes |
@@ -15,7 +15,7 @@ This file is an index; the detail lives in `AGENTS/ARCH/`.
| [NIGHTLY.md](ARCH/NIGHTLY.md) | `nightly-build.yml` jobs, Bundle packages, macOS LLD/Rust caching, publish rules, package naming |
| [LAYOUT.md](ARCH/LAYOUT.md) | Source file map (lexer, parser, codegen, CMake, installers), AST conventions |
-`#LIB` library units are described in [CONVENTIONS/EXCEPTIONS_AND_UNITS.md](CONVENTIONS/EXCEPTIONS_AND_UNITS.md);
+`PP_DEFINE __LIB` library regions are described in [CONVENTIONS/EXCEPTIONS_AND_UNITS.md](CONVENTIONS/EXCEPTIONS_AND_UNITS.md);
the embedded standard library in [SUBSYSTEMS/STDLIB.md](SUBSYSTEMS/STDLIB.md).
## Detail docs
diff --git a/AGENTS/ARCH/DRIVER.md b/AGENTS/ARCH/DRIVER.md
index ef739b2..974c0dc 100644
--- a/AGENTS/ARCH/DRIVER.md
+++ b/AGENTS/ARCH/DRIVER.md
@@ -6,7 +6,8 @@ style is in [CONVENTIONS/SYMBOLS_AND_ERRORS.md](../CONVENTIONS/SYMBOLS_AND_ERROR
- One or more source files, with optional `-S`, `-o path`, `-r`, `-no-std` and
`-fdiagnostics-color[=auto|always|never]` / `-fno-diagnostics-color`; options may appear among inputs.
- Each stream is parsed independently. INCLUDE paths are relative to the including file,
+ Each input is preprocessed independently before parsing. PP_* switches are file-local;
+ masked source retains line numbers, and SourceUnit owns the per-line __LIB map. INCLUDE paths are relative to the including file,
matched against command-line inputs with fs::equivalent. The driver rejects repeated
inputs and computes transitive symbol visibility; cycles do not copy statements.
CodeGen records owners for signatures, types and exported constants/globals and filters
diff --git a/AGENTS/ARCH/LAYOUT.md b/AGENTS/ARCH/LAYOUT.md
index c2cfee2..44a8f51 100644
--- a/AGENTS/ARCH/LAYOUT.md
+++ b/AGENTS/ARCH/LAYOUT.md
@@ -3,6 +3,7 @@
| Path | Contents |
|---|---|
| `include/cps/` | All headers, included as `"cps/Foo.h"` |
+| `lib/Lexer/Preprocessor.cc`, `include/cps/Preprocessor.h` | File-local switch preprocessing, conditional masking and original-line library metadata |
| `lib/Lexer/Lexer.cc` | Token scanning and payload-preserving lookahead; `gettok()` consumes and `peekToken`/`peekLine` inspect buffered tokens |
| `lib/Parser/Parser.cc` | Entry point, statement dispatch, assignment parsing and error recovery |
| `lib/Parser/ParserExpression.cc`, `ParserControlFlow.cc` | Expressions/designators and control-flow statement parsing (including ordered CASE branches) |
diff --git a/AGENTS/ARCH/OVERVIEW.md b/AGENTS/ARCH/OVERVIEW.md
index 820c5bb..ee3fc12 100644
--- a/AGENTS/ARCH/OVERVIEW.md
+++ b/AGENTS/ARCH/OVERVIEW.md
@@ -1,14 +1,14 @@
# Overview and value representation
-`cpsc` compiles CIE A-Level 9618 pseudocode to native executables or LLVM IR. Classic three-stage
-Kaleidoscope-style design, C++17, built with LLVM 23 and Clang 23. CMake rejects
+`cpsc` compiles CIE A-Level 9618 pseudocode to native executables or LLVM IR. A line preprocessor feeds a
+Kaleidoscope-style lexer/parser/codegen pipeline, C++17, built with LLVM 23 and Clang 23. CMake rejects
other major versions and non-Clang compilers. Execution is selected at
build time: external lli, an embedded static LLVM engine, or disabled.
```
-files ──> Lexer ──> Parser ──> vector<unique_ptr<StmtAST>> ──> CodeGen ──> LLVM IR ──> NativeCompiler (object emission + embedded LLD)
- (istream) (recursive (flat program list; (one llvm::Module "cps_module",
- descent) FunctionDefAST mixed in) entry code inside i32 main())
+files -> Preprocessor -> Lexer -> Parser -> AST statements -> CodeGen -> LLVM IR -> NativeCompiler
+ (per-file (istream) (recursive descent) (one module) (object + embedded LLD)
+ switches and source-line library metadata)
```
Fixed value representation (ABI — much code infers types backwards from these):
diff --git a/AGENTS/CONVENTIONS/EXCEPTIONS_AND_UNITS.md b/AGENTS/CONVENTIONS/EXCEPTIONS_AND_UNITS.md
index 8ee97ec..0b8a887 100644
--- a/AGENTS/CONVENTIONS/EXCEPTIONS_AND_UNITS.md
+++ b/AGENTS/CONVENTIONS/EXCEPTIONS_AND_UNITS.md
@@ -35,10 +35,16 @@ Part of [Load-bearing conventions](../CONVENTIONS.md).
through ExceptionHandler, truncates its result and retains the final uncaught
handler.
-**Library units.** Line-leading `#LIB` marks SourceUnit::IsLibrary. RuntimeCheck uses
-the externally visible i32 `__cps_user_line`; FunctionGen's shared call hook updates
-it only on non-library to library calls. Runtime helper line arguments use
-RuntimeCheck::lineValue too. Compiler diagnostics retain the owning file location.
+**Library regions.** PP_DEFINE __LIB enables library mode for subsequent source
+positions; PP_UNDEF __LIB disables it, including inside functions. SourceUnit owns
+LibraryLines and answers isLibrary(Line). RuntimeCheck queries the current unit's
+map with each original source line and uses the shared external i32 __cps_user_line
+only in enabled regions. FunctionGen's call hook updates that global for calls
+from ordinary positions, regardless of the callee's header mode: a callee can
+enable __LIB inside its body. Library calls preserve it. Runtime helper arguments
+also use RuntimeCheck::lineValue. Templates keep definition source lines and
+owning units; deferred object cleanup keeps its registration's line and unit.
+Compiler diagnostics retain the owning file location.
**Default standard library.** The driver extracts embedded std.cps, its imported units
and matching objects to a content-keyed cache (or temporary fallback) that survives
diff --git a/AGENTS/CONVENTIONS/LEXING.md b/AGENTS/CONVENTIONS/LEXING.md
index 81b01d1..654d7ae 100644
--- a/AGENTS/CONVENTIONS/LEXING.md
+++ b/AGENTS/CONVENTIONS/LEXING.md
@@ -20,7 +20,8 @@ identifier. Assignment is `<-` (ASCII only), equality is single `=`, inequality
concatenation `&` (reaches the parser as raw ASCII 38 — no token). Identifiers use
ASCII case-insensitive lookup/comparison through `IdentifierMap`, `IdentifierSet`
and `sameIdentifier`; retain source spelling in ASTs and diagnostics. This includes
-functions, types, enum values, fields and builtins, but not C_TYPE import strings.
+functions, types, enum values, fields and builtins, but not C_TYPE import strings
+or preprocessor switch names.
Integer tokens carry a checked unsigned magnitude through lookahead; the parser
applies the sign and i64 range check, including the minimum value. String/char
literals support C++17 byte escapes and Unicode escapes (UTF-8 in STRING, ASCII only
@@ -32,3 +33,13 @@ reserved in every user identifier, including EXTERN declarations.
**The lexer reads a caller-owned stream.** Construct it with `Lexer(std::istream &)`;
the stream must outlive the lexer. Lookahead, line number and error state belong to
each instance. The driver opens the source file; stdin is not used for compilation.
+
+**Preprocessing precedes lexing.** `preprocess(std::istream &)` returns masked source,
+per-line __LIB states and an error flag. PP_DEFINE/PP_UNDEF change case-sensitive,
+file-local switches; PP_IFDEF/PP_IFNDEF/PP_ENDIF maintain a nested conditional stack.
+Directives occupy a line, with optional leading whitespace and trailing // comments.
+Disabled ordinary source is never tokenized; DEFINE/UNDEF in it have no effect.
+Masking preserves byte lengths, CRLF and original source line numbers. The driver
+owns the processed stream passed to Lexer. PP_* keywords remain reserved outside
+valid directives. There is no macro expansion, value, PP_ELSE or switch propagation
+through INCLUDE; line-leading # directives are errors.
diff --git a/AGENTS/EXTENDING.md b/AGENTS/EXTENDING.md
index 358e80e..dc3be08 100644
--- a/AGENTS/EXTENDING.md
+++ b/AGENTS/EXTENDING.md
@@ -3,7 +3,7 @@
Step-by-step patterns for adding features. Read [CONVENTIONS.md](CONVENTIONS.md) first — every recipe
below assumes those invariants.
-**New statement:** token in `Lexer.h` enum + keyword match in `Lexer.cc`'s if-chain →
+**New statement:** token in `Lexer.h` enum + entry in `Lexer.cc`'s Keywords table →
node class in `AST.h` or a feature header (`FunctionAST.h`/`FileAST.h` precedent;
unique_ptr children, move ctor, raw-ptr getters) → `ParseXxx` in
the matching `Parser*.cc` file + branch in `ParseStatementImpl` (block statements parse their body with
diff --git a/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md b/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md
index 98693e5..19be0aa 100644
--- a/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md
+++ b/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md
@@ -37,7 +37,9 @@ Part of the [subsystem notes](../SUBSYSTEMS.md). Builds on [classes](CLASSES.md)
- Stack lifetimes use a per-function `StackObjects` list saved/restored around function
emission. DECLARE and BYVAL copies share ownership registration, including arrays and
records with class fields.
-- Each record retains the original address, an entry-initialized Alive flag and, for
+- Each record retains its original source line and owning unit so deferred cleanup
+ uses the correct __LIB region, even for globals from another unit. It also retains
+ the original address, an entry-initialized Alive flag and, for
arrays, a runtime element count in an entry slot. Array buffer addresses also live in
entry slots so deferred cleanup never references branch-local bound SSA values.
- Every array registers, even when its elements need no destruction: cleanup runs the
diff --git a/AGENTS/SUBSYSTEMS/MEMORY.md b/AGENTS/SUBSYSTEMS/MEMORY.md
index 40cfe9e..ab752de 100644
--- a/AGENTS/SUBSYSTEMS/MEMORY.md
+++ b/AGENTS/SUBSYSTEMS/MEMORY.md
@@ -14,8 +14,8 @@ C ABI lowering, library call-line hook and exception-aware calls.
- memory.cc owns a linked list of live allocation start addresses. Explicit
MALLOC/REALLOC and keyword NEW share it; STRING/ARRAY internals keep their own
ownership outside the list.
-- Errors print the existing reason with __cps_user_line and throw 0. The #LIB call
- hook supplies the user line, including keyword NEW/DELETE helper calls.
+- Errors print the existing reason with __cps_user_line and throw 0. The call hook
+ supplies the user line from ordinary source positions, including keyword NEW/DELETE helper calls.
- Sizes accept INTEGER and every supported C integer (including _Bool) through
ordinary overloads. Wrappers explicitly cast to unsigned long long; C++ converts
that value to native size_t, preserving the old integer conversion behavior.
diff --git a/AGENTS/SUBSYSTEMS/STDLIB.md b/AGENTS/SUBSYSTEMS/STDLIB.md
index 6c7b14c..07d0959 100644
--- a/AGENTS/SUBSYSTEMS/STDLIB.md
+++ b/AGENTS/SUBSYSTEMS/STDLIB.md
@@ -1,6 +1,6 @@
# Standard library
-Part of the [subsystem notes](../SUBSYSTEMS.md). `#LIB` library units and default
+Part of the [subsystem notes](../SUBSYSTEMS.md). `PP_DEFINE __LIB` library regions and default
import rules: [CONVENTIONS/EXCEPTIONS_AND_UNITS.md](../CONVENTIONS/EXCEPTIONS_AND_UNITS.md).
**Standard library** (`pseudocode-lib/`)
@@ -31,8 +31,8 @@ import rules: [CONVENTIONS/EXCEPTIONS_AND_UNITS.md](../CONVENTIONS/EXCEPTIONS_AN
## STRING and I/O bridging
-- STRING is a #LIB class with a public internal void* handle owning std::string. The
- _string_impl_* C ABI reports __cps_user_line and throws 0 on std::exception.
+- The STRING class is defined under PP_DEFINE __LIB. Its public internal void*
+ handle owns std::string. The _string_impl_* C ABI reports __cps_user_line and throws 0 on std::exception.
- Functions/operators use ordinary resolution; StringValueGen bridges literals, C_STR, C
conversions and file operands.
- C_STRING literals have an adjacent uppercase C suffix.
diff --git a/AGENTS/SUBSYSTEMS/TEMPLATES.md b/AGENTS/SUBSYSTEMS/TEMPLATES.md
index 95d2963..b80f7ed 100644
--- a/AGENTS/SUBSYSTEMS/TEMPLATES.md
+++ b/AGENTS/SUBSYSTEMS/TEMPLATES.md
@@ -57,7 +57,7 @@ callable lookup.
- After all units' statement loops, `drainTemplateBodies` emits queued functions and
class methods through `emitStmt`, repeating for newly requested instances until the
queue is empty. Instantiation depth is limited to 64.
-- `selectUnit` restores the template owner's file, library mode and call hook;
+- `selectUnit` restores the template owner's file, library-line lookup and call hook;
`VisibilityUnit` uses the first requester's transitive visibility, including
requester-defined operators needed by a library template.
- Each body receives the symbol snapshot from the template declaration, preserving