aboutsummaryrefslogtreecommitdiff
path: root/AGENTS/CONVENTIONS/STRINGS.md
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-30 14:33:33 +0000
committer_ov4 <ov4@ov4.org>2026-10-30 14:33:33 +0000
commit9b2d82dadbb465de71985a8db3aa8df454579b72 (patch)
tree686703c7f74565baad63f368b90124f8577c4616 /AGENTS/CONVENTIONS/STRINGS.md
parent0cf54b4f77ccf8376341950b02ceb7c1d1268ed7 (diff)
docs(types): explain implicit constructors and raw text literalsHEADmain
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS/CONVENTIONS/STRINGS.md')
-rw-r--r--AGENTS/CONVENTIONS/STRINGS.md51
1 files changed, 28 insertions, 23 deletions
diff --git a/AGENTS/CONVENTIONS/STRINGS.md b/AGENTS/CONVENTIONS/STRINGS.md
index d07c217..d036fb4 100644
--- a/AGENTS/CONVENTIONS/STRINGS.md
+++ b/AGENTS/CONVENTIONS/STRINGS.md
@@ -2,29 +2,34 @@
Part of [Load-bearing conventions](../CONVENTIONS.md).
-**STRING values use the class machinery.** `string.cps` owns a std::string through an
-internal handle. Ordinary literals construct STRING through NEW(C_STRING); suffixed
-`"text"C` literals produce C_STRING directly. Ordinary literals retain legacy NUL
-truncation. `StringValueGen.cc` bridges construction, C_STR access and file operands;
-INPUT calls READ_INPUT. String functions and all concatenation/comparison operators
-are ordinary library definitions, with exact overload selection. Comparisons use
-case-sensitive byte ordering. A missing STRING class or required bridge method is a
-compile error.
+**Literals are raw C_STRING values.** Both ordinary and C-suffixed double-quoted
+literals emit global text pointers; CONSTANT keeps the same raw type and read-only
+binding. Text operations retain legacy NUL truncation. Single quotes remain CHAR.
+An exact C_STRING overload wins over conversion to STRING.
-**CHAR and STRING convert implicitly.** `emitCoercedExpr` turns a CHAR into a
-one-character STRING (`emitStringFromChar`, STRING.NEW(1, ch)) and a STRING into a CHAR
-(`emitCharFromString`, via the `_LENGTH()` and `C_STR()` bridge methods), so assignment,
-parameter passing and RETURN need no special cases; a length other than 1 is a runtime
-error. `resolveOperator` and `resolveCall` fall back to the STRING overload when an
-exact match is missing and a CHAR is involved (`'a' & 'b'`, `"a" = 'a'`); two CHAR
-operands still compare as CHARs, and CASE converts the CHAR side itself. A converted
-value is a fresh temporary, so `emitAssignment` copies its source (CopySource) only when
-the source type equals the target type. CHAR with INTEGER or BOOLEAN never converts.
+**Automatic construction is opt-in.** `string.cps` owns a std::string through an
+internal handle and declares IMPLICIT NEW(C_STRING) and IMPLICIT NEW(CHAR).
+`TypeCheckGen.cc` shares direct constructor lookup, conversion ranking and emission
+with calls, operators and captured CASE values. Never automatically invoke an
+unmarked constructor, including in a replacement STRING class under -no-std.
+Explicit casts may still use unmarked NEW(C_STRING).
+
+**CHAR compatibility remains.** STRING -> CHAR uses `_LENGTH()` and `C_STR()` and
+checks length 1 at runtime. C_STRING -> CHAR first uses the marked STRING constructor;
+this compatibility bridge ranks below a direct STRING parameter, preserving string
+function selection. Two CHARs compare directly. No path may chain two IMPLICIT NEWs.
+
+**I/O bridges retain STRING behavior.** OUTPUT and file operands convert C_STRING
+through its marked STRING constructor, then use C_STR. INPUT calls READ_INPUT.
+String functions, concatenation and comparisons are ordinary library definitions;
+comparisons use case-sensitive byte ordering. Missing classes or methods diagnose.
**Ownership follows value copies.** STRING constructors/assignment prevent shared
-handles. Records and BYVAL arrays containing STRING recursively copy their
-string-bearing fields/elements; RETURN and temporary cleanup preserve ownership.
-C_STRING casts borrow a STRING buffer or construct an owning STRING copy in the other
-direction. FileHandler owns copied open-file names and frees them on close; READFILE
-buffers are copied into STRING and released. Explicit memory-library allocations remain
-separate from these internal objects.
+handles. Records and BYVAL arrays containing STRING recursively clone owned string
+fields/elements. Converted arguments stay Alive until ownership transfers to the
+callee; failed later arguments release pending values. Converted lvalues are fresh
+objects, never copy sources of a different type. RETURN, discarded values and
+statement temporaries use ordinary class cleanup, including exception exits.
+Explicit C_STRING casts borrow a STRING buffer or construct an owning copy in the
+other direction. FileHandler copies open-file names and releases them on close;
+READFILE copies and releases its buffer. Explicit memory allocations remain separate.