aboutsummaryrefslogtreecommitdiff
path: root/doc
diff options
context:
space:
mode:
author_ov4 <ov4@ov4.org>2026-10-20 12:02:09 +0000
committer_ov4 <ov4@ov4.org>2026-10-20 12:02:09 +0000
commit5a54ecdade484168846b8db83a7f41c5275059c0 (patch)
treef3ce7fd6c81e8a747b9a2e19b94588c307bef243 /doc
parentbe964b4df4db9f42e0b7d615c1cbfa6cf268e646 (diff)
docs(strings): document the embedded standard library and STRING values
Describe -no-std, C_STRING literals, library function semantics and owning string lifetimes in the manuals and contributor guidance. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
-rw-r--r--doc/cpsc.1.md11
-rw-r--r--doc/language/cpsc-language-overview.7.md11
-rw-r--r--doc/language/function/cpsc-function-asc.7.md4
-rw-r--r--doc/language/function/cpsc-function-chr.7.md4
-rw-r--r--doc/language/function/cpsc-function-is_num.7.md2
-rw-r--r--doc/language/function/cpsc-function-lcase.7.md5
-rw-r--r--doc/language/function/cpsc-function-left.7.md2
-rw-r--r--doc/language/function/cpsc-function-length.7.md4
-rw-r--r--doc/language/function/cpsc-function-mid.7.md2
-rw-r--r--doc/language/function/cpsc-function-num_to_str.7.md2
-rw-r--r--doc/language/function/cpsc-function-right.7.md2
-rw-r--r--doc/language/function/cpsc-function-str_to_num.7.md4
-rw-r--r--doc/language/function/cpsc-function-ucase.7.md5
-rw-r--r--doc/language/keyword/cpsc-keyword-c_type.7.md4
-rw-r--r--doc/language/keyword/cpsc-keyword-class.7.md2
-rw-r--r--doc/language/keyword/cpsc-keyword-constant.7.md2
-rw-r--r--doc/language/keyword/cpsc-keyword-declare.7.md2
-rw-r--r--doc/language/keyword/cpsc-keyword-global.7.md4
-rw-r--r--doc/language/keyword/cpsc-keyword-input.7.md2
-rw-r--r--doc/language/keyword/cpsc-keyword-operator.7.md2
-rw-r--r--doc/language/keyword/cpsc-keyword-output.7.md2
21 files changed, 56 insertions, 22 deletions
diff --git a/doc/cpsc.1.md b/doc/cpsc.1.md
index 566e3a1..8359a25 100644
--- a/doc/cpsc.1.md
+++ b/doc/cpsc.1.md
@@ -6,7 +6,7 @@ cpsc - compile and run CIE pseudocode
# SYNOPSIS
-**cpsc** [**-r**] [**-S**] [**-o** *output*] *source* [*source* ...]
+**cpsc** [**-r**] [**-S**] [**-no-std**] [**-o** *output*] *source* [*source* ...]
**cpsc** **-h**
@@ -20,6 +20,8 @@ Each input is a compilation unit. Use top-level `INCLUDE "lib.cps"` to import an
Exactly one file may contain top-level executable statements (including top-level DECLARE). Alternatively, define a parameterless `FUNCTION MAIN RETURNS INTEGER` in one file and have no top-level executable statements anywhere. Builds containing only definitions and no MAIN fail with `error: no main program`. GLOBAL blocks declare shared primitive variables. INCLUDE, GLOBAL and MAIN entry points are compiler extensions beyond the Cambridge guide.
+The embedded standard library is loaded and linked automatically. Its std.cps imports string.cps, which defines the STRING class and ordinary string functions. No extra files are needed for default compilation. With **-no-std**, supply any required library inputs explicitly; ordinary string literals require a visible STRING class. A literal with an adjacent uppercase C suffix, such as `"hello"C`, has type C_STRING and does not require that class.
+
# OPTIONS
**-h**
@@ -29,11 +31,14 @@ Exactly one file may contain top-level executable statements (including top-leve
: Save to the specified path. Without **-S**, save a native executable; with **-S**, save LLVM IR. Use the path exactly as given; its extension does not select the output format. May be specified only once. With **-r**, keep this file even if execution fails.
**-S**
-: Save textual LLVM IR instead of a native executable. Without **-o**, use the entry source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program.
+: Save textual LLVM IR instead of a native executable. Without **-o**, use the entry source filename with a `.ll` extension beside the source file. May be combined with **-r** to save IR and run the program. Manually linking saved IR that uses the standard library requires the matching string.o and C++ runtime; native output and **-r** supply them automatically.
**-r**
: Run the compiled program with the runner selected at build time (see EXECUTION MODES). Save output first when **-S** or **-o** is also present; otherwise do not save a file. The program inherits stdin, stdout and stderr; `INPUT` can read terminal or piped input.
+**-no-std**
+: Disable automatic standard-library loading and linking. Explicit INCLUDE and INCLUDE_OBJ inputs still work.
+
# NATIVE COMPILATION
Native compilation uses LLVM, the Clang driver and LLD embedded in `cpsc`. Required startup objects, runtime archives and system-library link inputs are embedded too and unpacked temporarily when linking. No external compiler, linker or development SDK is needed. Generate programs for the compiler's own operating system and CPU architecture; cross-compilation is not supported.
@@ -120,4 +125,4 @@ Generated IR uses the C++ exception ABI. Native binaries need the C++ runtime; E
# SEE ALSO
-[cpsc-language-overview(7)](language/cpsc-language-overview.7.md) describes supported syntax and links to the keyword and built-in function manuals.
+[cpsc-language-overview(7)](language/cpsc-language-overview.7.md) describes supported syntax and links to the keyword, builtin and standard-library function manuals.
diff --git a/doc/language/cpsc-language-overview.7.md b/doc/language/cpsc-language-overview.7.md
index f04e044..1256e43 100644
--- a/doc/language/cpsc-language-overview.7.md
+++ b/doc/language/cpsc-language-overview.7.md
@@ -8,7 +8,7 @@ cpsc-language-overview - supported cpsc pseudocode syntax
Keywords are uppercase and case-sensitive. Identifiers, including built-in function names, are case insensitive. Indentation is for readability; blocks use explicit closing keywords. Identifiers begin with a letter or underscore and continue with letters, digits, or underscores.
-Assign with ASCII `<-`: `Count <- Count + 1`. Compare with `=`, `<>`, `<`, `>`, `<=`, and `>=`. Built-in STRING comparisons compare contents, case-sensitively. Use `+`, `-`, `*`, and `/` for arithmetic; built-in `/` always returns REAL. Use `&` to join strings.
+Assign with ASCII `<-`: `Count <- Count + 1`. Compare with `=`, `<>`, `<`, `>`, `<=`, and `>=`. Standard-library STRING comparisons compare contents, case-sensitively. Use `+`, `-`, `*`, and `/` for arithmetic; built-in `/` always returns REAL. Use `&` to join strings.
User-defined types can overload operators with OVERLOAD FUNCTION OPERATOR; expressions then use the declared result type. See [cpsc-keyword-operator(7)](keyword/cpsc-keyword-operator.7.md). STRING cannot be implicitly converted to BOOLEAN.
@@ -16,7 +16,7 @@ Precedence, from highest to lowest: unary operators, `* / DIV MOD`, `+ - &`, com
Parenthesized type casts, such as (C_INT)Number, have unary precedence. C_INT, C_CHAR, C_STRING and C_DOUBLE are native C aliases; TYPE name = C_TYPE("...") imports other supported C base types and pointers. Conversions between C and pseudocode types must be explicit. These are compiler extensions; see [cpsc-keyword-c_type(7)](keyword/cpsc-keyword-c_type.7.md). EXTERN "C" declares C functions from objects named with INCLUDE_OBJ; see [cpsc-keyword-extern(7)](keyword/cpsc-keyword-extern.7.md).
-Literals include integers, decimal real numbers, TRUE/FALSE, strings in double quotes, and single-byte characters in single quotes. Negative numbers use unary minus. String and character literals support C++17 simple escapes (`\' \" \? \\ \a \b \f \n \r \t \v`), one to three octal digits, and `\x` followed by hexadecimal digits (byte values only). Unicode escapes `\uXXXX` and `\UXXXXXXXX` encode valid Unicode scalar values as UTF-8 in strings; in CHAR they must be ASCII. Unknown escapes are errors. Built-in STRING is NUL-terminated, so `"a\0b"` is observed as `"a"`. Comments begin with `//` and continue to the end of the line.
+Literals include integers, decimal real numbers, TRUE/FALSE, strings in double quotes, and single-byte characters in single quotes. Negative numbers use unary minus. String and character literals support C++17 simple escapes (`\' \" \? \\ \a \b \f \n \r \t \v`), one to three octal digits, and `\x` followed by hexadecimal digits (byte values only). Unicode escapes `\uXXXX` and `\UXXXXXXXX` encode valid Unicode scalar values as UTF-8 in strings; in CHAR they must be ASCII. Unknown escapes are errors. Ordinary STRING literals retain NUL truncation, so `"a\0b"` is observed as `"a"`. An adjacent uppercase C suffix, as in `"text"C`, produces C_STRING directly. Comments begin with `//` and continue to the end of the line.
Declare variables before use. See DECLARE for built-in types and arrays, TYPE for records/enumerations/pointers, and CLASS for public/private fields and methods.
@@ -63,7 +63,9 @@ Multi-file builds use the compiler extensions INCLUDE and GLOBAL. Pass every sou
Closing and auxiliary keywords are documented with their main constructs: THEN/ELSE/ENDIF with IF; OF/OTHERWISE/ENDCASE with CASE; CATCH/ENDTRY/THROW with TRY; ENDWHILE with WHILE; UNTIL with REPEAT; TO/STEP/NEXT with FOR; RETURN/RETURNS/BYVAL/BYREF and function/procedure closing keywords with FUNCTION/PROCEDURE; READ/WRITE/APPEND with OPENFILE; ARRAY/OF and INTEGER/REAL/BOOLEAN/CHAR/STRING with DECLARE; ENDGLOBAL with GLOBAL; ENDTYPE with TYPE; EXTERN_FUNCTION/EXTERN_PROCEDURE with EXTERN; PUBLIC/PRIVATE/ENDCLASS with CLASS. TRUE/FALSE are BOOLEAN literals.
-# BUILT-IN FUNCTIONS
+# STRING LIBRARY FUNCTIONS
+
+These ordinary functions and the STRING class come from the embedded standard library, loaded and linked automatically unless **-no-std** is given. Ordinary string literals require a visible STRING class.
- [cpsc-function-length(7)](function/cpsc-function-length.7.md): find a string's length.
- [cpsc-function-mid(7)](function/cpsc-function-mid.7.md): extract part of a string.
@@ -76,6 +78,9 @@ Closing and auxiliary keywords are documented with their main constructs: THEN/E
- [cpsc-function-is_num(7)](function/cpsc-function-is_num.7.md): test whether text represents a number.
- [cpsc-function-num_to_str(7)](function/cpsc-function-num_to_str.7.md): convert a number to text.
- [cpsc-function-str_to_num(7)](function/cpsc-function-str_to_num.7.md): convert text to a real number.
+
+# BUILT-IN FUNCTIONS
+
- [cpsc-function-eof(7)](function/cpsc-function-eof.7.md): test for the end of a text file.
- [cpsc-function-malloc(7)](function/cpsc-function-malloc.7.md): allocate raw memory.
- [cpsc-function-realloc(7)](function/cpsc-function-realloc.7.md): resize an explicit allocation.
diff --git a/doc/language/function/cpsc-function-asc.7.md b/doc/language/function/cpsc-function-asc.7.md
index 17ba8fe..6cc8cb6 100644
--- a/doc/language/function/cpsc-function-asc.7.md
+++ b/doc/language/function/cpsc-function-asc.7.md
@@ -13,7 +13,9 @@ ASC(text : STRING) RETURNS INTEGER
# DESCRIPTION
-Return the unsigned byte code of the character, or of the first byte of a string. Use a nonempty string; for ASCII characters this is the ASCII code.
+Provided by the standard string library, loaded and linked by default.
+
+Return the unsigned byte code of the character, or of the first byte of a string. An empty string returns zero; for ASCII characters this is the ASCII code.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-chr.7.md b/doc/language/function/cpsc-function-chr.7.md
index 1eab413..cc471a5 100644
--- a/doc/language/function/cpsc-function-chr.7.md
+++ b/doc/language/function/cpsc-function-chr.7.md
@@ -12,7 +12,9 @@ CHR(code : INTEGER) RETURNS STRING
# DESCRIPTION
-Convert the low eight bits of code to a one-byte string. The result is STRING, not CHAR. Use ASCII codes 1 to 127 for ordinary text; code 0 produces an empty string.
+Provided by the standard string library, loaded and linked by default.
+
+Convert the low eight bits of code to a one-byte string. The result is STRING, not CHAR. Use ASCII codes 1 to 127 for ordinary text; code 0 produces one NUL byte, so LENGTH(CHR(0)) is 1.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-is_num.7.md b/doc/language/function/cpsc-function-is_num.7.md
index a1fe34e..efb5f1a 100644
--- a/doc/language/function/cpsc-function-is_num.7.md
+++ b/doc/language/function/cpsc-function-is_num.7.md
@@ -12,6 +12,8 @@ IS_NUM(text : STRING) RETURNS BOOLEAN
# DESCRIPTION
+Provided by the standard string library, loaded and linked by default.
+
Return true for a nonempty string fully consumed by the runtime's numeric conversion. Leading whitespace is accepted; trailing whitespace or other trailing text is rejected.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-lcase.7.md b/doc/language/function/cpsc-function-lcase.7.md
index a2cbf44..0d542be 100644
--- a/doc/language/function/cpsc-function-lcase.7.md
+++ b/doc/language/function/cpsc-function-lcase.7.md
@@ -7,12 +7,15 @@ cpsc-function-lcase - convert text to lower case
# SYNOPSIS
```text
+LCASE(character : CHAR) RETURNS CHAR
LCASE(text : STRING) RETURNS STRING
```
# DESCRIPTION
-Return a copy with letters converted to lower case. Unlike guide section 5.5's CHAR-to-CHAR signature, cpsc accepts text and returns STRING. Use ASCII text for predictable character conversion.
+Provided by the standard string library, loaded and linked by default.
+
+Return a copy with letters converted to lower case. The CHAR overload follows guide section 5.5; the STRING overload is a compatibility extension. Use ASCII text for predictable character conversion.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-left.7.md b/doc/language/function/cpsc-function-left.7.md
index 8f27e24..5bb5002 100644
--- a/doc/language/function/cpsc-function-left.7.md
+++ b/doc/language/function/cpsc-function-left.7.md
@@ -12,6 +12,8 @@ LEFT(text : STRING, count : INTEGER) RETURNS STRING
# DESCRIPTION
+Provided by the standard string library, loaded and linked by default.
+
Return up to count bytes from the beginning. Counts larger than the string length return the whole string; negative counts return an empty string.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-length.7.md b/doc/language/function/cpsc-function-length.7.md
index fcdc47a..470b975 100644
--- a/doc/language/function/cpsc-function-length.7.md
+++ b/doc/language/function/cpsc-function-length.7.md
@@ -12,7 +12,9 @@ LENGTH(text : STRING) RETURNS INTEGER
# DESCRIPTION
-Return the number of bytes before the string terminator. String operations are byte-based, so this is not a Unicode character count.
+Provided by the standard string library, loaded and linked by default.
+
+Return the number of bytes in the owning string, including embedded NUL bytes. String operations are byte-based, so this is not a Unicode character count.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-mid.7.md b/doc/language/function/cpsc-function-mid.7.md
index 0956b43..e033543 100644
--- a/doc/language/function/cpsc-function-mid.7.md
+++ b/doc/language/function/cpsc-function-mid.7.md
@@ -12,6 +12,8 @@ MID(text : STRING, start : INTEGER, count : INTEGER) RETURNS STRING
# DESCRIPTION
+Provided by the standard string library, loaded and linked by default.
+
Return up to count bytes starting at the one-based position start. Positions below 1 clamp to 1; positions beyond the end return an empty string. The count clamps to the available bytes; negative counts return an empty string.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-num_to_str.7.md b/doc/language/function/cpsc-function-num_to_str.7.md
index fb8e6fd..39b6890 100644
--- a/doc/language/function/cpsc-function-num_to_str.7.md
+++ b/doc/language/function/cpsc-function-num_to_str.7.md
@@ -12,6 +12,8 @@ NUM_TO_STR(number : INTEGER or REAL) RETURNS STRING
# DESCRIPTION
+Provided by the standard string library, loaded and linked by default.
+
Format INTEGER as signed decimal text and REAL with six digits after the decimal point.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-right.7.md b/doc/language/function/cpsc-function-right.7.md
index 2f70fbd..89e58af 100644
--- a/doc/language/function/cpsc-function-right.7.md
+++ b/doc/language/function/cpsc-function-right.7.md
@@ -12,6 +12,8 @@ RIGHT(text : STRING, count : INTEGER) RETURNS STRING
# DESCRIPTION
+Provided by the standard string library, loaded and linked by default.
+
Return up to count bytes from the end. Use a nonnegative count. Counts larger than the string length return the whole string.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-str_to_num.7.md b/doc/language/function/cpsc-function-str_to_num.7.md
index b0ceef2..acdf60b 100644
--- a/doc/language/function/cpsc-function-str_to_num.7.md
+++ b/doc/language/function/cpsc-function-str_to_num.7.md
@@ -12,7 +12,9 @@ STR_TO_NUM(text : STRING) RETURNS REAL
# DESCRIPTION
-Return REAL, including for integer-looking text. Conversion can stop at trailing text; invalid text returns zero. Use IS_NUM first when the whole string must be a valid number.
+Provided by the standard string library, loaded and linked by default.
+
+Return REAL, including for integer-looking text. The whole string must be consumed. Invalid text, trailing junk and values outside the REAL range throw a catchable exception. Use IS_NUM first to check numeric text without throwing for invalid input.
# EXAMPLE
diff --git a/doc/language/function/cpsc-function-ucase.7.md b/doc/language/function/cpsc-function-ucase.7.md
index 728ae14..868c448 100644
--- a/doc/language/function/cpsc-function-ucase.7.md
+++ b/doc/language/function/cpsc-function-ucase.7.md
@@ -7,12 +7,15 @@ cpsc-function-ucase - convert text to upper case
# SYNOPSIS
```text
+UCASE(character : CHAR) RETURNS CHAR
UCASE(text : STRING) RETURNS STRING
```
# DESCRIPTION
-Return a copy with letters converted to upper case. Unlike guide section 5.5's CHAR-to-CHAR signature, cpsc accepts text and returns STRING. Use ASCII text for predictable character conversion.
+Provided by the standard string library, loaded and linked by default.
+
+Return a copy with letters converted to upper case. The CHAR overload follows guide section 5.5; the STRING overload is a compatibility extension. Use ASCII text for predictable character conversion.
# EXAMPLE
diff --git a/doc/language/keyword/cpsc-keyword-c_type.7.md b/doc/language/keyword/cpsc-keyword-c_type.7.md
index 4ac4141..beff643 100644
--- a/doc/language/keyword/cpsc-keyword-c_type.7.md
+++ b/doc/language/keyword/cpsc-keyword-c_type.7.md
@@ -23,7 +23,7 @@ A cast has unary precedence and converts its following operand. Declare a type a
C/pseudocode assignment, argument passing and mixed arithmetic require an explicit cast, including ordinary literals: use n <- (C_INT)1 and n + (C_INT)1. Different C scalar types use C++ numeric conversions, integer promotions and usual arithmetic conversions. BYREF requires the same type and performs no conversion. Comparisons and logical operations return BOOLEAN. The / operator always performs real division and returns REAL, including with two C integer operands; DIV and MOD accept C integers after promotion. C values used directly as IF/WHILE conditions need a cast to BOOLEAN.
-C scalar values support INPUT and OUTPUT. Plain char prints and reads a character; signed char and unsigned char use numeric input/output. _Bool uses the existing TRUE/FALSE output and numeric input. C pointers start null and support prefix ^ for address-of, suffix ^ for dereference, and = or <> between the same C pointer type. Dereferencing null throws; void pointers cannot be dereferenced. Pointer arithmetic and direct pointer INPUT/OUTPUT are unsupported. To print a C string, cast it to STRING. STRING/char* casts share the original buffer without allocation; a null char* becomes an empty STRING. Pointer validity and writable storage remain the caller's responsibility.
+C scalar values support INPUT and OUTPUT. Plain char prints and reads a character; signed char and unsigned char use numeric input/output. _Bool uses the existing TRUE/FALSE output and numeric input. C pointers start null and support prefix ^ for address-of, suffix ^ for dereference, and = or <> between the same C pointer type. Dereferencing null throws; void pointers cannot be dereferenced. Pointer arithmetic and direct pointer INPUT/OUTPUT are unsupported. To print a C string, cast it to STRING. Casting char* to STRING constructs an owning copy; a null char* becomes empty. Casting STRING to char* borrows its buffer until the string changes or is destroyed. A literal such as `"text"C` has type C_STRING without constructing STRING. Pointer validity and writable storage remain the caller's responsibility.
# EXAMPLE
@@ -36,7 +36,7 @@ DECLARE Text : C_STRING
Number <- (C_INT)42
Pointer <- ^Number
Pointer^ <- Number + (C_INT)1
-Text <- (C_STRING)"Result"
+Text <- "Result"C
OUTPUT (STRING)Text, ": ", Number
OUTPUT Number / (C_INT)2
```
diff --git a/doc/language/keyword/cpsc-keyword-class.7.md b/doc/language/keyword/cpsc-keyword-class.7.md
index c17f3ef..139f97e 100644
--- a/doc/language/keyword/cpsc-keyword-class.7.md
+++ b/doc/language/keyword/cpsc-keyword-class.7.md
@@ -40,7 +40,7 @@ A constructor is a PROCEDURE named NEW, following guide section 10.2. It may be
`DECLARE Object : ClassName`, `DECLARE Object : ClassName()` and `DECLARE Object : ClassName(arguments)` zero the object's storage, construct its fields recursively in declaration order, then call its NEW procedure. These automatic DECLARE, field and array calls are compiler extensions. Array elements and class-valued fields in records or classes use parameterless construction, before the enclosing constructor runs. A required constructor argument cannot be omitted; supplying arguments to a class without NEW is an error. Empty parentheses are allowed for a class without NEW. Constructor arguments after ARRAY OF are unsupported. A declaration executed again, such as inside a loop, first destroys its previous live incarnation, then zeroes and constructs its original storage again.
-An `OVERLOAD PROCEDURE NEW(BYREF Other : ClassName)` defines a copy constructor. BYVAL class lvalue arguments and RETURN of class lvalues invoke it; a same-class BYVAL constructor is rejected. Classes without one retain bitwise copying. Whole records and BYVAL arrays still copy their class fields or elements shallowly. Class results transfer ownership directly into BYVAL arguments, RETURN and ordinary assignment without an assignment overload. Discarded results and temporary receivers live until the statement ends, including exception exits. Ordinary user BYREF calls still require bare variables; constructor calls can bind temporaries.
+An `OVERLOAD PROCEDURE NEW(BYREF Other : ClassName)` defines a copy constructor. BYVAL class lvalue arguments and RETURN of class lvalues invoke it; a same-class BYVAL constructor is rejected. Classes without one retain bitwise copying for fields without STRING ownership. Records and BYVAL arrays recursively clone STRING-bearing fields or elements. Other owning class fields retain the existing shallow-copy limitations. Class results transfer ownership directly into BYVAL arguments, RETURN and ordinary assignment without an assignment overload. Discarded results and temporary receivers live until the statement ends, including exception exits. Ordinary user BYREF calls still require bare variables; constructor calls can bind temporaries.
The keyword NEW is allowed only as the complete right side of assignment: `Target <- NEW ClassName`, `Target <- NEW ClassName()` or `Target <- NEW ClassName(arguments)`. Target must have exactly the named class type. NEW uses the checked MALLOC allocation path, zeroes storage and constructs fields before calling NEW. A method-only class receives at least one byte of heap storage so its object address is non-null. Allocation failure reports a runtime error and throws; constructor exceptions also propagate to TRY/CATCH. Private constructor access and argument checks follow ordinary member-call rules.
diff --git a/doc/language/keyword/cpsc-keyword-constant.7.md b/doc/language/keyword/cpsc-keyword-constant.7.md
index abc39cf..55960c5 100644
--- a/doc/language/keyword/cpsc-keyword-constant.7.md
+++ b/doc/language/keyword/cpsc-keyword-constant.7.md
@@ -12,7 +12,7 @@ CONSTANT identifier = literal
# DESCRIPTION
-Declare a read-only value whose type is inferred from its literal: INTEGER, REAL, BOOLEAN, CHAR, or STRING. A negative integer or real literal is allowed. As required by the Cambridge guide, variables, other constants, expressions, casts, and function calls cannot initialize a CONSTANT.
+Declare a read-only value whose type is inferred from its literal: INTEGER, REAL, BOOLEAN, CHAR, STRING, or C_STRING for a literal with the C suffix. A negative integer or real literal is allowed. As required by the Cambridge guide, variables, other constants, expressions, casts, and function calls cannot initialize a CONSTANT.
A constant is visible from its declaration to the end of its enclosing block. A top-level constant is also available in functions and procedures defined after its declaration. Functions do not inherit constants from another function or from an enclosing statement block.
diff --git a/doc/language/keyword/cpsc-keyword-declare.7.md b/doc/language/keyword/cpsc-keyword-declare.7.md
index 428a934..6138916 100644
--- a/doc/language/keyword/cpsc-keyword-declare.7.md
+++ b/doc/language/keyword/cpsc-keyword-declare.7.md
@@ -13,7 +13,7 @@ DECLARE name : ARRAY[lower:upper, ...] OF type
# DESCRIPTION
-Declare one variable per statement. Built-in types are INTEGER (signed 64-bit), REAL, BOOLEAN, CHAR (one byte), and STRING. User-defined TYPE and CLASS names are also accepted. Variables start with zero, FALSE, an empty string, or a zero-initialized user-defined value.
+Declare one variable per statement. Built-in types are INTEGER (signed 64-bit), REAL, BOOLEAN, and CHAR (one byte). STRING is an owning class supplied by the default standard library. User-defined TYPE and CLASS names are also accepted. Variables start with zero, FALSE, an empty string, or a zero-initialized user-defined value.
C_INT, C_CHAR, C_STRING and C_DOUBLE are native C aliases for int, char, char* and double. C_TYPE can introduce aliases for other supported C base types and pointers. C values start with zero or null; assignment from pseudocode types requires an explicit cast. See [cpsc-keyword-c_type(7)](cpsc-keyword-c_type.7.md).
diff --git a/doc/language/keyword/cpsc-keyword-global.7.md b/doc/language/keyword/cpsc-keyword-global.7.md
index 643e0bb..652b9ff 100644
--- a/doc/language/keyword/cpsc-keyword-global.7.md
+++ b/doc/language/keyword/cpsc-keyword-global.7.md
@@ -15,9 +15,9 @@ ENDGLOBAL
# DESCRIPTION
-GLOBAL and ENDGLOBAL are compiler extensions. Any number of GLOBAL blocks may appear at top level. Their bodies allow only DECLARE of INTEGER, REAL, CHAR, STRING or BOOLEAN variables and literal assignments to declared global variables. Negative numeric literals are allowed. Arrays, records, classes, C aliases, constructor arguments, calls, NEW and computed expressions are unsupported.
+GLOBAL and ENDGLOBAL are compiler extensions. Any number of GLOBAL blocks may appear at top level. Their bodies allow only DECLARE of INTEGER, REAL, CHAR, STRING or BOOLEAN variables and literal assignments to declared global variables. Negative numeric literals are allowed. Arrays, records, other classes, C aliases, constructor arguments, calls, NEW and computed expressions are unsupported.
-Global variables have program lifetime and shared writable storage. They are visible throughout their own source file and in files importing them with INCLUDE, including inside functions and methods. Local variables and parameters may shadow them. Initializers are constants established before entry; omitted initializers use zero, FALSE or null, with null STRING values read as empty strings. A STRING literal initializes a pointer to shared literal storage.
+Global variables have program lifetime and shared writable storage. They are visible throughout their own source file and in files importing them with INCLUDE, including inside functions and methods. Local variables and parameters may shadow them. Literal initializers are established before user code runs. Omitted initializers use zero or FALSE; STRING globals construct empty owning values, and STRING literal assignments copy their contents.
A GLOBAL block does not count as top-level executable code. A build still requires top-level executable statements in exactly one file, or a parameterless FUNCTION MAIN returning INTEGER.
diff --git a/doc/language/keyword/cpsc-keyword-input.7.md b/doc/language/keyword/cpsc-keyword-input.7.md
index 4c6c309..2b4da57 100644
--- a/doc/language/keyword/cpsc-keyword-input.7.md
+++ b/doc/language/keyword/cpsc-keyword-input.7.md
@@ -16,7 +16,7 @@ Read into an INTEGER, REAL, BOOLEAN, CHAR, or STRING location: a previously decl
Native C scalar targets are also supported, using their actual widths and signedness. Plain C char reads a character; signed/unsigned char read numbers. C _Bool reads a number and stores whether it is nonzero. C pointers, including C_STRING, cannot be INPUT targets. See [cpsc-keyword-c_type(7)](cpsc-keyword-c_type.7.md).
-The target address is evaluated once per INPUT execution, before reading the value. Array bounds, unset pointers and private fields are checked as for assignment. Constants, whole arrays, whole records/classes, enums and pointer values cannot be INPUT targets. A dereferenced pointer may select a supported target type.
+The target address is evaluated once per INPUT execution, before reading the value. Array bounds, unset pointers and private fields are checked as for assignment. Constants, whole arrays, other whole records/classes, enums and pointer values cannot be INPUT targets. A dereferenced pointer may select a supported target type.
# EXAMPLE
diff --git a/doc/language/keyword/cpsc-keyword-operator.7.md b/doc/language/keyword/cpsc-keyword-operator.7.md
index 0673416..d420c21 100644
--- a/doc/language/keyword/cpsc-keyword-operator.7.md
+++ b/doc/language/keyword/cpsc-keyword-operator.7.md
@@ -39,7 +39,7 @@ Member operators on variables, fields, array elements and pointer dereferences m
Explicit calls use `OPERATOR+(A, B)` for global definitions and `A.OPERATOR+(B)` for members. They also work as statements, optionally prefixed with CALL, to discard results. Class-valued call results support explicit member operator calls, such as `Make().OPERATOR+(B)`. Indexing, function-call, address-of and dereference operators cannot be overloaded.
-A class may define `OVERLOAD PROCEDURE OPERATOR<-(BYREF Other : ClassName)` or an overload taking another exact static type. Assignment to a class lvalue selects this member before falling back to same-class bitwise assignment. The procedure takes exactly one explicit parameter; BYREF may bind a designator or materialized temporary. Keyword NEW assignment retains its allocation behavior. Self-assignment handling belongs to the operator body.
+A class may define `OVERLOAD PROCEDURE OPERATOR<-(BYREF Other : ClassName)` or an overload taking another exact static type. Assignment to a class lvalue selects this member before falling back to same-class assignment; STRING-bearing aggregates copy their owned string fields, while other fields retain their existing copy behavior. The procedure takes exactly one explicit parameter; BYREF may bind a designator or materialized temporary. Keyword NEW assignment retains its allocation behavior. Self-assignment handling belongs to the operator body.
# EXAMPLE
diff --git a/doc/language/keyword/cpsc-keyword-output.7.md b/doc/language/keyword/cpsc-keyword-output.7.md
index 3f90959..06d9910 100644
--- a/doc/language/keyword/cpsc-keyword-output.7.md
+++ b/doc/language/keyword/cpsc-keyword-output.7.md
@@ -12,7 +12,7 @@ OUTPUT expression, ...
# DESCRIPTION
-Print expressions from left to right without automatic separators, then add a newline. Strings print their contents; BOOLEAN prints TRUE or FALSE. Whole arrays and partially indexed arrays print their elements one per line; a final array adds no extra newline. Records, classes, and pointers cannot be printed directly.
+Print expressions from left to right without automatic separators, then add a newline. Strings print their contents; BOOLEAN prints TRUE or FALSE. Whole arrays and partially indexed arrays print their elements one per line; a final array adds no extra newline. Other records, classes, and pointers cannot be printed directly.
C scalars print with their native type's format and C argument promotions. Plain char prints a character, other C integers print numbers, and _Bool prints TRUE or FALSE. C_STRING is a pointer: cast it to STRING to print its contents. See [cpsc-keyword-c_type(7)](cpsc-keyword-c_type.7.md).