diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-30 14:33:33 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-30 14:33:33 +0000 |
| commit | 9b2d82dadbb465de71985a8db3aa8df454579b72 (patch) | |
| tree | 686703c7f74565baad63f368b90124f8577c4616 /AGENTS | |
| parent | 0cf54b4f77ccf8376341950b02ceb7c1d1268ed7 (diff) | |
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'AGENTS')
| -rw-r--r-- | AGENTS/ARCH/OVERVIEW.md | 3 | ||||
| -rw-r--r-- | AGENTS/CONVENTIONS/STRINGS.md | 51 | ||||
| -rw-r--r-- | AGENTS/CONVENTIONS/SYMBOLS_AND_ERRORS.md | 4 | ||||
| -rw-r--r-- | AGENTS/CONVENTIONS/TEMPLATES_AND_OPERATORS.md | 9 | ||||
| -rw-r--r-- | AGENTS/CONVENTIONS/TYPES.md | 3 | ||||
| -rw-r--r-- | AGENTS/EXTENDING.md | 2 | ||||
| -rw-r--r-- | AGENTS/PITFALLS/exceptions-and-c-interop.md | 6 | ||||
| -rw-r--r-- | AGENTS/PITFALLS/modules-and-stdlib.md | 3 | ||||
| -rw-r--r-- | AGENTS/PITFALLS/overload-template-operator.md | 11 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md | 7 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS/FUNCTIONS.md | 7 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS/STDLIB.md | 7 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS/TEMPLATES.md | 8 |
13 files changed, 71 insertions, 50 deletions
diff --git a/AGENTS/ARCH/OVERVIEW.md b/AGENTS/ARCH/OVERVIEW.md index ee3fc12..4f2278c 100644 --- a/AGENTS/ARCH/OVERVIEW.md +++ b/AGENTS/ARCH/OVERVIEW.md @@ -26,7 +26,8 @@ come from numeric_limits (long double size alone is insufficient). Programs use the compiler's build ABI; cross-target emission is not implemented. EXTERN "C" declarations call C functions from INCLUDE_OBJ objects (see [SUBSYSTEMS/EXTERN.md](../SUBSYSTEMS/EXTERN.md)). CTypeGen handles typed numeric conversions, casts, native arithmetic and I/O. -Crossing C/pseudocode domains requires a cast, including literals. C arithmetic +Crossing C/pseudocode domains requires a cast, including numeric literals, except +for marked IMPLICIT class constructors and the documented text bridges. C arithmetic uses C++ promotions, except that / always returns pseudocode REAL. ## Language manuals 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. diff --git a/AGENTS/CONVENTIONS/SYMBOLS_AND_ERRORS.md b/AGENTS/CONVENTIONS/SYMBOLS_AND_ERRORS.md index e21bed1..f382b61 100644 --- a/AGENTS/CONVENTIONS/SYMBOLS_AND_ERRORS.md +++ b/AGENTS/CONVENTIONS/SYMBOLS_AND_ERRORS.md @@ -8,8 +8,8 @@ only symbol table. - Use `symbolAddress` for an object address: class variables and BYVAL class parameters store their current object address in a reference slot (`IsReference`). -- Use SymbolInfo::isConstant() for constant checks: scalar literals use - ConstantValue; owning STRING constants use ReadOnly plus Storage. +- Use SymbolInfo::isConstant() for constant checks: literals, including raw + C_STRING text constants, use ConstantValue and have no writable storage. - Read values through emitExpr. Writable/address-taking paths reject constants through requireWritable; internal STRING copy/assignment source bindings may read their storage. diff --git a/AGENTS/CONVENTIONS/TEMPLATES_AND_OPERATORS.md b/AGENTS/CONVENTIONS/TEMPLATES_AND_OPERATORS.md index 79f1a88..675ea3e 100644 --- a/AGENTS/CONVENTIONS/TEMPLATES_AND_OPERATORS.md +++ b/AGENTS/CONVENTIONS/TEMPLATES_AND_OPERATORS.md @@ -22,11 +22,13 @@ Part of [Load-bearing conventions](../CONVENTIONS.md). Basic call resolution is - When multiple definitions share a function/procedure name, every ordinary and template definition must specify OVERLOAD. - `resolveCall` computes static argument types/ranks once, then tries exact ordinary, - non-variadic template and variadic template tiers; an expected result type filters + non-variadic template and variadic template tiers, then repeats with permitted + BYVAL conversions; an expected result type filters ordinary candidates, while template tiers still match parameters only. Same-tier ties are errors. - Candidate checking must stay silent and must not instantiate speculative class - types. Explicit arguments pre-bind types without allowing conversions. + types. Explicit arguments pre-bind types; substituted scalar BYVAL parameters + may then use permitted conversions. - Instances keep the template owner for diagnostics/library behavior and the first requester in `VisibilityUnit` for lookup (`value_or(CurrentUnit)`). - Deferred bodies use the symbol snapshot at the template declaration to preserve @@ -40,7 +42,8 @@ Part of [Load-bearing conventions](../CONVENTIONS.md). Basic call resolution is token on PrototypeAST. Canonical names contain a space (`OPERATOR +`, `Class.OPERATOR AND`) to avoid collisions with ordinary identifiers. - `OperatorGen.cc` probes visible global and left-class member signatures without - emitting diagnostics or evaluating operands. Matching is exact; member/global ties + emitting diagnostics or evaluating operands. Exact operands and directly supported + builtins precede converted overloads; member/global ties are ambiguous and access is checked only after selection. - Both getExprTypeInfo and emission must consult this resolver with the expression's result context before hardcoded builtin result types. A strict context requires the diff --git a/AGENTS/CONVENTIONS/TYPES.md b/AGENTS/CONVENTIONS/TYPES.md index 7349ab1..d13773b 100644 --- a/AGENTS/CONVENTIONS/TYPES.md +++ b/AGENTS/CONVENTIONS/TYPES.md @@ -18,7 +18,8 @@ C base type and pointer levels independently of the alias `Name`. Use `sameType` for storage compatibility (including BYREF and array arguments); never equate C types just because their LLVM types or widths match. CScalar/CPointer values are handled by CTypeGen, not the legacy representation coercions. Cross-domain -assignments, arguments and operators require explicit casts, including literals. +assignments, arguments and operators require explicit casts, including numeric literals, +except for marked IMPLICIT class constructors and the documented text bridges. Plain C char uses native signedness; pseudocode CHAR stays unsigned. Numeric conversions use source signedness, and native floating formats use numeric_limits. Allocation sizes still use LLVM sizeof; native C type widths use build-compiler diff --git a/AGENTS/EXTENDING.md b/AGENTS/EXTENDING.md index dc3be08..a7aeeb0 100644 --- a/AGENTS/EXTENDING.md +++ b/AGENTS/EXTENDING.md @@ -80,4 +80,4 @@ also be registered in EmbeddedRunner for static-runtime JIT symbol lookup. `setupExternalFunctions()` (re-declaring the same symbol in two handlers is fine — it dedupes by name). -**Standard-library functions:** define ordinary functions/operators in the appropriate pseudocode-lib/*.cps unit with C ABI helpers in the matching .cc as needed. std.cps imports all public library units. CMake rebuilds and embeds source/object changes; do not add standard-library functions to Builtins.h. Memory allocation functions live in memory.cps/memory.cc; only keyword NEW/DELETE need the MemoryGen bridge. Ordinary string literals need STRING.NEW(C_STRING); the compiler bridges OUTPUT/casts/files through C_STR(), INPUT through READ_INPUT(), and READFILE through assignment from C_STRING. +**Standard-library functions:** define ordinary functions/operators in the appropriate pseudocode-lib/*.cps unit with C ABI helpers in the matching .cc as needed. std.cps imports all public library units. CMake rebuilds and embeds source/object changes; do not add standard-library functions to Builtins.h. Memory allocation functions live in memory.cps/memory.cc; only keyword NEW/DELETE need the MemoryGen bridge. Double-quoted literals produce C_STRING; STRING contexts require marked IMPLICIT NEW(C_STRING), while CHAR uses marked IMPLICIT NEW(CHAR); the compiler bridges OUTPUT/casts/files through C_STR(), INPUT through READ_INPUT(), and READFILE through assignment from C_STRING. diff --git a/AGENTS/PITFALLS/exceptions-and-c-interop.md b/AGENTS/PITFALLS/exceptions-and-c-interop.md index b057d18..0d0f89d 100644 --- a/AGENTS/PITFALLS/exceptions-and-c-interop.md +++ b/AGENTS/PITFALLS/exceptions-and-c-interop.md @@ -19,11 +19,11 @@ Part of the [pitfalls index](../PITFALLS.md). ## C type extensions -- C_STRING is a raw char pointer, not a STRING: explicitly cast to STRING for - printing or string-library calls. +- C_STRING is a raw char pointer. A visible IMPLICIT STRING.NEW(C_STRING) + permits string-library calls, OUTPUT and file text; an explicit cast also works. - C aliases share canonical CIdentity; do not use LLVM widths to recover signedness or nominal type identity. Plain char's signedness is native, unlike pseudocode CHAR. -- C/pseudocode conversions require casts even for literals. C scalar arithmetic uses +- Other C/pseudocode conversions require casts, including numeric literals. C scalar arithmetic uses native promotions, but / always returns REAL. - Cast aliases must precede their use. - long double may have padding; sizeof does not identify its floating-point format. diff --git a/AGENTS/PITFALLS/modules-and-stdlib.md b/AGENTS/PITFALLS/modules-and-stdlib.md index 5394d78..e43bb78 100644 --- a/AGENTS/PITFALLS/modules-and-stdlib.md +++ b/AGENTS/PITFALLS/modules-and-stdlib.md @@ -17,7 +17,8 @@ Part of the [pitfalls index](../PITFALLS.md). and automatically linked. - Use -no-std before explicitly supplying a replacement STRING class/library; otherwise duplicate definitions fail. - - Ordinary literals require a visible STRING class with NEW(C_STRING). + - Double-quoted literals are raw C_STRING. STRING contexts, OUTPUT and file text + require a visible STRING class with IMPLICIT NEW(C_STRING), including under -no-std. - C_TYPE/INCLUDE/EXTERN syntax strings are parser metadata and do not construct STRING. - Keyword NEW/DELETE and MALLOC/REALLOC/FREE require memory.cps; -no-std users diff --git a/AGENTS/PITFALLS/overload-template-operator.md b/AGENTS/PITFALLS/overload-template-operator.md index 909e5f7..56247ff 100644 --- a/AGENTS/PITFALLS/overload-template-operator.md +++ b/AGENTS/PITFALLS/overload-template-operator.md @@ -9,8 +9,9 @@ Part of the [pitfalls index](../PITFALLS.md). - Count, canonical parameter types, array rank and (for non-VOID definitions) return type distinguish signatures; a PROCEDURE counts as VOID. BYREF/BYVAL and array bounds do not. -- Calls match exact static types, even for a single OVERLOAD definition; ordinary - functions still coerce arguments. A known expected result type (assignment, BYVAL +- Calls prefer exact static types, then marked IMPLICIT construction and the + existing CHAR/STRING bridge for scalar BYVAL parameters; ordinary functions + retain their existing numeric coercions. A known expected result type (assignment, BYVAL argument, RETURN, condition, subscript, CASE comparison) must match the overload's return type exactly; `(T) x` only prefers T and otherwise converts. Without a context, return-only-distinct candidates need one DEFAULT return or remain ambiguous. @@ -28,7 +29,8 @@ Part of the [pitfalls index](../PITFALLS.md). - Top-level FUNCTION/PROCEDURE/CLASS only; all template parameters are types, with at most one final pack. -- Exact types are required even with explicit arguments (`Max<REAL>(1, 2.5)` fails). +- Substituted BYVAL parameters allow marked constructors and CHAR/STRING bridges, + but numeric widening still fails (`Max<REAL>(1, 2.5)` fails). Deduction recognizes T and array element T, never the T inside Box<T>. - When multiple ordinary/template functions share a name, every definition must specify OVERLOAD; exact ordinary definitions win, then non-variadic templates, then @@ -55,7 +57,8 @@ Part of the [pitfalls index](../PITFALLS.md). - Unary/binary operators require OVERLOAD FUNCTION, with supported arity and at least one record/class/enum operand. Pointer aliases alone do not qualify. -- Exact matching considers visible globals and left-class members together, and the +- Exact-first matching considers visible globals and left-class members together, + with marked BYVAL construction after directly supported builtins. The result type joins the match when the context supplies one; ties are errors, including private/public ties. Without a context, return-only-distinct candidates need a unique DEFAULT return or remain ambiguous; defaults do not resolve diff --git a/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md b/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md index 19be0aa..0b12ea1 100644 --- a/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md +++ b/AGENTS/SUBSYSTEMS/CLASS_LIFETIME.md @@ -21,8 +21,9 @@ Part of the [subsystem notes](../SUBSYSTEMS.md). Builds on [classes](CLASSES.md) - Assignment-only `NewExprAST` uses checked memory-library allocation (at least one byte for method-only classes), zero initialization and construction, then rebinds reference slots or copies into other destinations. -- Ordinary assignment invokes an exact member OPERATOR<- when available, otherwise it - copies. +- Ordinary assignment prefers an exact member OPERATOR<-, then permitted BYVAL + conversions. Without an operator, a marked converting NEW produces a fresh value; + replacing a non-STRING class this way releases its previous value before transfer. - Heap objects require explicit keyword DELETE; INHERITS/SUPER remain unsupported. ## Destruction @@ -65,7 +66,7 @@ Part of the [subsystem notes](../SUBSYSTEMS.md). Builds on [classes](CLASSES.md) before local handlers, while ordinary objects remain function-scoped. - Function-result method receivers are materialized by the same path as operator receivers. -- Assignment first selects an exact member OPERATOR<-; without one, STRING-bearing +- Assignment first selects a member OPERATOR<- with exact parameters preferred; without one, STRING-bearing aggregate assignment clones string fields from lvalues or transfers them from rvalues, releasing the target's old string fields without invoking the enclosing class destructor; other classes are assigned bitwise. diff --git a/AGENTS/SUBSYSTEMS/FUNCTIONS.md b/AGENTS/SUBSYSTEMS/FUNCTIONS.md index 9555f1d..222d4da 100644 --- a/AGENTS/SUBSYSTEMS/FUNCTIONS.md +++ b/AGENTS/SUBSYSTEMS/FUNCTIONS.md @@ -27,7 +27,9 @@ internal __cps_main). - `emitPrototype` records each function's pseudocode signature in a `FuncSig` overload-set map (`FunctionGen::getOverloads`, filtered by unit visibility). -- `resolveCall` selects exact static parameter types/ranks for OVERLOAD. When the call +- `resolveCall` prefers exact static parameter types/ranks for OVERLOAD, then + marked constructor conversions for scalar BYVAL parameters. BYREF and arrays + remain exact; a single call never chains IMPLICIT constructors. When the call site has an expected result type, the candidate must also return exactly that type; a cast only prefers it. Without a context, return-only-distinct candidates use the unique DEFAULT return, otherwise they are ambiguous. A single ordinary definition keeps implicit conversions. @@ -57,7 +59,8 @@ internal __cps_main). - PrototypeAST retains the operator token; FunctionGen validates operand count and requires a record/class/enum operand. -- Global signatures and left-class methods share exact-type selection, used by +- Global signatures and left-class methods share exact-first selection with + marked BYVAL construction as fallback, used by ValueTypeGen and ExpressionGen before builtin operations and filtered by an expected result type where present. A strict context whose operands match but whose result does not sets `WrongResult`. Missing candidates leave builtin rules intact; ties are diff --git a/AGENTS/SUBSYSTEMS/STDLIB.md b/AGENTS/SUBSYSTEMS/STDLIB.md index 07d0959..138b076 100644 --- a/AGENTS/SUBSYSTEMS/STDLIB.md +++ b/AGENTS/SUBSYSTEMS/STDLIB.md @@ -33,8 +33,9 @@ import rules: [CONVENTIONS/EXCEPTIONS_AND_UNITS.md](../CONVENTIONS/EXCEPTIONS_AN - 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. +- Functions/operators use ordinary resolution and marked IMPLICIT NEW(C_STRING) + and NEW(CHAR). StringValueGen bridges C_STR, explicit casts, CHAR checks and files. +- All double-quoted literals are C_STRING; the adjacent uppercase C suffix remains + accepted. OUTPUT and file text use the marked STRING constructor. - STRING INPUT delegates to READ_INPUT (rest of the line, throws at end of input), OUTPUT uses C stdout buffers, and READFILE invokes assignment from C_STRING then frees its temporary buffer. diff --git a/AGENTS/SUBSYSTEMS/TEMPLATES.md b/AGENTS/SUBSYSTEMS/TEMPLATES.md index b80f7ed..ffa011a 100644 --- a/AGENTS/SUBSYSTEMS/TEMPLATES.md +++ b/AGENTS/SUBSYSTEMS/TEMPLATES.md @@ -17,12 +17,14 @@ callable lookup. - `CodeGen::resolveCall` retains ordinary fast paths when no templates exist. Otherwise it computes static argument types and whole-array ranks once, selecting exact ordinary definitions (including an expected result type when present) before non-variadic - templates and then variadic templates. Templates still match only substituted - parameter types; result contexts do not filter them. + templates and then variadic templates, then repeats these tiers with permitted + BYVAL conversions. Templates match substituted parameter types; result contexts + do not filter them. - Explicit type arguments pre-bind positional parameters and constrain a pack prefix; deduction from `T` or array element `T` fills remaining bindings. Composite types such as `Box<T>` are checked after substitution but do not deduce T. -- Every position must match exactly and every non-pack type must be bound. Candidate +- Every non-pack type must be bound; substituted BYVAL positions may use the + shared conversion ranks. BYREF and arrays still match exactly. Candidate failures stay silent; only the final no-match or ambiguity is diagnosed. - `hasCallable` keeps CALL statement re-resolution aware of templates. |
