diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-18 08:16:01 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-18 08:16:01 +0000 |
| commit | 14c03b7c26ff06835fca631eed6a3e308946321a (patch) | |
| tree | 33965d73902f019f2f778046e7f097ff26f35f01 /AGENTS | |
| parent | 0b1c500e9cbc7837dbef5fb24be21dc4f6078714 (diff) | |
feat(lib): add experimental _EXP_STRING backed by std::string
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS')
| -rw-r--r-- | AGENTS/CONVENTIONS.md | 2 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS.md | 4 | ||||
| -rw-r--r-- | AGENTS/TESTING.md | 2 |
3 files changed, 6 insertions, 2 deletions
diff --git a/AGENTS/CONVENTIONS.md b/AGENTS/CONVENTIONS.md index f72cb86..76f67c1 100644 --- a/AGENTS/CONVENTIONS.md +++ b/AGENTS/CONVENTIONS.md @@ -85,7 +85,7 @@ before ArithmeticHandler. Ordering is case-sensitive byte lexicographic order; mixed STRING/non-STRING comparisons are errors. Whole-array comparisons remain unsupported; records/classes require an explicit operator overload for comparisons. -**Strings are malloc'd and never freed — by design.** Every string-producing operation +**Built-in strings are malloc'd and never freed — by design.** Every string-producing operation (`&`, MID/LEFT/RIGHT/LCASE/UCASE, NUM_TO_STR, CHR, READFILE, CHAR/number→STRING coercion) mallocs a fresh buffer; string literals and BOOLEAN→STRING coercion instead return pointers to shared module globals, so a STRING value may alias a global. `MemoryHandler` declares `free` for explicit user memory only; it must never free internal STRING buffers. Don't "fix" leaks piecemeal; it's a global design decision. diff --git a/AGENTS/SUBSYSTEMS.md b/AGENTS/SUBSYSTEMS.md index 427fc45..08301a3 100644 --- a/AGENTS/SUBSYSTEMS.md +++ b/AGENTS/SUBSYSTEMS.md @@ -126,7 +126,7 @@ class parameters; `symbolAddress` loads their current object address for all val lvalue, address-of, receiver and BYREF paths. Field aliases, this and BYREF parameters bind addresses directly. Assignment-only `NewExprAST` uses checked MemoryHandler allocation (at least one byte for method-only classes), zero initialization and -construction, then rebinds reference slots or copies into other destinations. Ordinary assignment always copies. Heap objects require explicit keyword DELETE; INHERITS/SUPER remain unsupported. +construction, then rebinds reference slots or copies into other destinations. Ordinary assignment invokes an exact member OPERATOR<- when available, otherwise it copies. Heap objects require explicit keyword DELETE; INHERITS/SUPER remain unsupported. `ConstructorGen.cc` also owns `typeNeedsDestruction` and recursive `emitDestroy`: ordinary DELETE method first, then fields in reverse declaration order. Explicit @@ -196,3 +196,5 @@ Builder (RuntimeCheck emits through the same one), saving/restoring the insert b **Explicit memory** (`MemoryHandler`): lazily emits internal allocation/find/release/resize helpers and a linked list of live allocation start addresses. Explicit MALLOC/REALLOC and keyword NEW allocations enter the list; STRING/ARRAY internals retain their existing ownership. `emitValidate` always calls the find helper, including for null, so keyword DELETE validates before running destructors. FREE validates non-null addresses, unlinks and frees the tracking node, releases the block and returns the original address. Zero-byte allocation returns null. REALLOC validates non-null addresses before its zero-size release path; null behaves as MALLOC. Positive-size resizing updates the node only after success, leaving the old block and record intact on failure. Node allocation precedes the user allocation; if the latter fails, its node is freed before the diagnostic and anonymous throw. Helpers use RuntimeCheck and ExceptionHandler, including source-line arguments and per-function unwind preparation. Sizes accept INTEGER and C integers and convert to native size_t. Address reuse can make stale aliases indistinguishable from current allocations; dereferences are not checked against this list. **Class copies and temporaries.** Callers construct BYVAL class arguments with a same-class BYREF OVERLOAD NEW; the callee's RegisterCopy hook takes ownership. emitOwnedValue constructs lvalue copies and keeps pending arguments Alive until marshalling succeeds. RETURN copies lvalues and transfers rvalues. StackObject::Temporary uses statement cleanup and deferred temporary-only cleanup before local handlers, while ordinary objects remain function-scoped. Function-result method receivers are materialized by the same path as operator receivers. + +**Experimental library** (`pseudocode-lib/`): the default build compiles each .cc with the host compiler into build/pseudocode-lib/*.o and copies .cps units beside them. `_EXP_STRING` is a #LIB class with a single public internal void* handle owning std::string. The `_exp_string_impl_*` C ABI uses checked operations that print __cps_user_line and throw 0 on std::exception. Class copy/assignment methods prevent handle sharing; functions accept BYVAL copies. OUTPUT uses C stdout buffers. Install/release do not yet ship these artifacts. diff --git a/AGENTS/TESTING.md b/AGENTS/TESTING.md index 2d7685a..af66e93 100644 --- a/AGENTS/TESTING.md +++ b/AGENTS/TESTING.md @@ -23,3 +23,5 @@ All commands run without a shell and retain their exact argv, working directory, Perl generators use Random.pm's SHA-256 sequence with explicit big-endian extraction, fixed group identity and decimal counter. `generator-vectors.json` pins 100 records plus boundaries using the all-zero 40-character seed; update a vector only when deliberately changing a generator, and verify repeatability and a different seed. C++ references must avoid undefined behavior and implement the specification independently. Use arithmetic closed forms or standard containers where they provide an independent oracle. Record platform-dependent C behavior as such; never call it CIE behavior. Before committing a test change, build the affected references and run the affected CTest cases. Compiler defects may fail: inspect retained diagnostics and document the failure accurately. Before committing workflow changes, run actionlint and retain the existing release API simulation/package smoke checks without contacting the real release. No compiler implementation changes belong in a tests-only task. + +The `_EXP_STRING` integration fixture lives in `tests/library/exp-string`. CMake copies it to the build tree as `test-cases/i/exp-string`, where relative source paths reach the built library and its object file. It uses the ordinary native/runner harness and appears as `i/exp-string` in CTest. |
