diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-24 18:04:52 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-24 18:06:18 +0000 |
| commit | 92dc80ad6616f1fef72cfef1ae120e4fb5b41146 (patch) | |
| tree | 37cb449eaa832739ede6fe8bdc280aa995394882 /doc | |
| parent | 0900667401415a0914b8a1510543c7c7eaf32e53 (diff) | |
feat(operator): select operator overloads by the expected result type
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Diffstat (limited to 'doc')
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-operator.7.md | 8 |
1 files changed, 5 insertions, 3 deletions
diff --git a/doc/language/keyword/cpsc-keyword-operator.7.md b/doc/language/keyword/cpsc-keyword-operator.7.md index d420c21..e18a5e5 100644 --- a/doc/language/keyword/cpsc-keyword-operator.7.md +++ b/doc/language/keyword/cpsc-keyword-operator.7.md @@ -29,9 +29,11 @@ OPERATOR is a compiler extension, absent from the CIE guide. Declare unary and b Binary operators are `+ - * / DIV MOD & = <> < <= > >= AND OR`. Unary operators are `- NOT`. A global binary definition takes two parameters and a unary definition takes one; at least one parameter must be a record, class or enum. A pointer alias alone does not qualify. A member binary definition takes one explicit parameter and a unary definition takes none; this supplies the left or sole operand. PUBLIC and PRIVATE precede OVERLOAD as for other methods. -Operands match exact static types, without implicit conversions, following OVERLOAD rules. For example, an INTEGER operand does not match a REAL parameter. Visible global definitions and methods of the left operand's class participate together; multiple matching candidates are an error. The selected method must be accessible: PRIVATE never causes a public fallback. Included units provide operators using the ordinary INCLUDE visibility rules. Return types do not distinguish overloads. +Operands match exact static types, without implicit conversions, following OVERLOAD rules. For example, an INTEGER operand does not match a REAL parameter. Visible global definitions and methods of the left operand's class participate together. The selected method must be accessible: PRIVATE never causes a public fallback. Included units provide operators using the ordinary INCLUDE visibility rules. -The expression has the selected function's declared return type. Comparisons and logic may return any supported function result type: a comparison returning STRING can be printed or assigned to STRING, but cannot be implicitly used as BOOLEAN. CASE comparisons must return BOOLEAN. A VOID result may be discarded through an explicit call but cannot be used as a value. +Return types also distinguish operator overloads. When the context requires a result type (assignment, RETURN, condition, CASE comparison, subscript and similar positions), only definitions returning exactly that type match; if the operands match but no result does, the error is `No matching overload for OPERATOR +(T, U) returning R`. A cast `(R) expr` only prefers R and otherwise selects by operands before converting. Without an expected result type, such as OUTPUT or an operand of another operator, a unique operand match is selected and definitions that differ only by return type are ambiguous. + +The expression has the selected function's declared return type. Comparisons and logic may return any supported function result type: a comparison returning STRING can be printed or assigned to STRING, but a BOOLEAN context requires an overload returning BOOLEAN. CASE comparisons follow the same result-type rule and must return BOOLEAN. A VOID result may be discarded through an explicit call but cannot be used as a value. Operators keep their existing precedence, operand count and associativity. Operands are evaluated once, from left to right; overloaded AND and OR evaluate both operands. Operators are independent: defining = does not define <>, and operands are never swapped to find a match. A matching overload takes precedence over the built-in operation; otherwise the existing built-in rules apply. @@ -39,7 +41,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 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. +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 by operand type — not by an expected result, since the operator is a procedure — 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 |
