diff options
| author | _ov4 <ov4@ov4.org> | 2026-10-17 06:05:39 +0000 |
|---|---|---|
| committer | _ov4 <ov4@ov4.org> | 2026-10-17 06:05:39 +0000 |
| commit | bc990a0917b401e16a0ab57affd868d5ef51cdec (patch) | |
| tree | bbb71176a39cb7a772b4120fcf60f1d4a297f474 | |
| parent | a99852084ff6f0491734d508a4dcd2e7d8411814 (diff) | |
docs(classes): describe member methods and this semantics
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
| -rw-r--r-- | AGENTS/ARCH.md | 4 | ||||
| -rw-r--r-- | AGENTS/CONVENTIONS.md | 8 | ||||
| -rw-r--r-- | AGENTS/PITFALLS.md | 13 | ||||
| -rw-r--r-- | AGENTS/SUBSYSTEMS.md | 21 | ||||
| -rw-r--r-- | doc/language/cpsc-language-overview.7.md | 6 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-call.7.md | 4 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-class.7.md | 41 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-function.7.md | 4 | ||||
| -rw-r--r-- | doc/language/keyword/cpsc-keyword-procedure.7.md | 4 |
9 files changed, 75 insertions, 30 deletions
diff --git a/AGENTS/ARCH.md b/AGENTS/ARCH.md index 27bb70a..1178934 100644 --- a/AGENTS/ARCH.md +++ b/AGENTS/ARCH.md @@ -289,12 +289,12 @@ do not modify the real release for local verification. | `lib/Parser/ParserExpression.cc`, `ParserControlFlow.cc` | Expressions/designators and control-flow statement parsing (including ordered CASE branches) | | `lib/Parser/ParserFunction.cc` | FUNCTION/PROCEDURE/CALL/RETURN + parameter-list parsing | | `lib/Parser/ParserFile.cc` | OPENFILE/READFILE/WRITEFILE/CLOSEFILE parsing | -| `lib/Parser/ParserType.cc` | Type names, variable/array/constant declarations, TYPE/ENDTYPE and CLASS/ENDCLASS declarations, shared field parsing, SET/DEFINE reserved stubs | +| `lib/Parser/ParserType.cc` | Type names, variable/array/constant declarations, TYPE/ENDTYPE and CLASS/ENDCLASS declarations, shared field and method parsing, SET/DEFINE reserved stubs | | `lib/CodeGen/CodeGen.cc` | Initialization, symbols, call arguments and main() compilation | | `lib/CodeGen/ExpressionGen.cc`, `StatementGen.cc`, `ControlFlowGen.cc` | Expression/statement dispatch and control-flow emission | | `lib/CodeGen/ConstantGen.cc` | Literal constants, declaration conflicts and lexical binding restoration | | `lib/CodeGen/ValueTypeGen.cc`, `OutputGen.cc`, `Builtins.h` | Expression typing, coercion/declarations, scalar output and the shared builtin table | -| `lib/CodeGen/Designator.cc`, `TypeCheckGen.cc` | TYPE pre-pass and lvalue access; type admission and user-kind binary operators | +| `lib/CodeGen/Designator.cc`, `TypeCheckGen.cc` | TYPE pre-pass, member lookup/calls and lvalue access; type admission and user-kind binary operators | | `lib/CodeGen/CTypeGen.cc` | CodeGen methods for native C scalar conversions, casts, arithmetic and input/output | | `lib/CodeGen/NativeTypeSystem.cc` | Builtin registration, native C type imports/aliases and scalar promotion | | `lib/CodeGen/MemoryHandler.cc` | Explicit raw memory allocation, resizing and release with a live-address tracking list | diff --git a/AGENTS/CONVENTIONS.md b/AGENTS/CONVENTIONS.md index 8ce9cb2..83e73e2 100644 --- a/AGENTS/CONVENTIONS.md +++ b/AGENTS/CONVENTIONS.md @@ -129,7 +129,7 @@ The parser drops a failed statement and resyncs at the next token that can start a statement or end a block (`syncToStatementStart`), then continues; the failure is always diagnosed and reflected in the exit code. -**Calls share one dispatch path.** `CodeGen::emitCall` handles expression calls, CALL statements and bare `name(args)` statements; statement calls discard results. Explicit casts may bridge C void* and nominal pseudocode pointer types. +**Calls share argument marshalling.** `CodeGen::emitCall` handles global expression calls, CALL statements and bare `name(args)` statements; `emitMemberCall` resolves member access and adds a hidden receiver address. Both use `marshalCallArgs` and FunctionGen for user calls; statement calls discard results. Explicit casts may bridge C void* and nominal pseudocode pointer types. **User calls dispatch on the declared signature.** `FunctionGen::emitPrototype` records every function's pseudocode signature (`FuncSig`: return type name + per-param `ParamSig` @@ -140,10 +140,12 @@ arguments through `emitCoercedExpr`, and dispatches whole-array arguments to `ArrayHandler::emitArrayArgument`. RETURN values go through `emitCoercedExpr` against the declared return type. Top-level prototypes are pre-registered (after the TYPE pre-pass) before statement emission, so call-before-definition is fine; a call with -no registered signature is a compile error. Function names get no mangling, so +no registered signature is a compile error. Global function names get no mangling, so `emitPrototype` rejects names that collide with runtime/libc symbols (`isReservedRuntimeName`), builtins, or enum values. Signatures retain the first -declaration spelling for LLVM lookup, independently of call-site casing. +declaration spelling for LLVM lookup, independently of call-site casing. Methods use +`Class.Method` names and a hidden leading receiver address; their FuncSig parameters +contain only explicit source parameters. Method prototypes are pre-registered too. **Parameter modes are sticky and BYREF is procedure-only (guide §8.3).** In `(BYREF a : T, b : T)` the `b` is BYREF too; unannotated parameters default to diff --git a/AGENTS/PITFALLS.md b/AGENTS/PITFALLS.md index 48b1cdb..bae6bd3 100644 --- a/AGENTS/PITFALLS.md +++ b/AGENTS/PITFALLS.md @@ -77,11 +77,16 @@ test programs. already-invalid programs can hit it). - **CLASS subset (§10).** `CLASS`/`ENDCLASS`/`PUBLIC`/`PRIVATE` are reserved. - CLASS is a top-level record-derived value type with optional per-field access + CLASS is a top-level record-derived value type with optional per-member access keywords (no DECLARE). Omitting access defaults to public, per the guide. TYPE fields cannot specify access and remain public. Private fields - cannot be accessed externally; whole-value initialization/copying is allowed. - CLASS inherits record limitations, including no array fields or empty bodies. + and methods cannot be accessed outside methods of the owning class; + whole-value initialization/copying is allowed. Methods modify the receiver; + `this` aliases the object itself, not a pointer. `this <- Other` copies a value. + Bare fields are supported, but calls to the current object's methods require + `this.Method(...)`; unqualified calls remain global. Parameters and local + declarations shadowing fields warn without failing compilation. Method-only + classes are allowed; empty classes and array fields remain unsupported. - **Exception extensions.** TRY requires exactly one parameterless CATCH and ENDTRY. Bare THROW raises a new anonymous exception even inside CATCH; there is @@ -109,7 +114,7 @@ SET types (`SET`/`DEFINE` are reserved with dedicated errors), random files (OPENFILE...FOR RANDOM/SEEK/GETRECORD/PUTRECORD — TYPE is done, so these are unblocked now; the RANDOM keyword is reserved and gives a dedicated parse error), DATE, string escape sequences, -array-typed record fields, whole-array RETURN, class methods/constructors/destructors, +array-typed record fields, whole-array RETURN, class constructors/destructors, NEW and class inheritance. Compiler fixtures now live in `tests/` (see TESTING.md). Nightly CI runs the compiler suites, packaged EMBEDDED smoke checks and existing plugin tests. The initial standard conflicts and missing diagnostic locations are fixed on diff --git a/AGENTS/SUBSYSTEMS.md b/AGENTS/SUBSYSTEMS.md index e564c1f..b21386d 100644 --- a/AGENTS/SUBSYSTEMS.md +++ b/AGENTS/SUBSYSTEMS.md @@ -62,9 +62,24 @@ Shared body/field parsing lives in `ParserType.cc`. TYPE fields always have `IsPublic = true`; CLASS fields default to public or accept an explicit PUBLIC/PRIVATE keyword and carry that flag through `defineRecord` into `RecordFieldInfo`. Both the static -designator type walk and `emitLValue` reject private field access, including -address-of, array elements and pointer dereferences. There is no class method -context or language-level inheritance yet. +designator type walk and `emitLValue` check private field access against the +current method's owning class, including address-of, array elements and pointer +dereferences. Other instances of the same class are accessible from its methods. + +Class ASTs also own their `FunctionDefAST` methods. PrototypeAST retains the owner +and access level; `getLinkName()` qualifies method symbols as `Class.Method`, while +global function names remain unmangled. CodeGen registers methods separately in +`ClassMethods` and pre-registers their prototypes after the type pre-pass. +`MemberCallExprAST` keeps an addressable receiver separate from explicit arguments; +`MemberCallStmtAST` discards its result. `emitMemberCall` checks access and prepends +the receiver address to arguments marshalled by the existing `marshalCallArgs`. +The hidden receiver is not part of FuncSig's explicit parameter list. +FunctionGen binds field aliases and `this` to the incoming receiver storage before +binding explicit parameters. CodeGen saves/restores `CurrentClass` around each +function body; unqualified calls still resolve globally. Local declarations and +parameters may shadow fields with a source-line warning; `this.Field` remains +explicit. `this` cannot be redeclared within methods. Constructors and language-level +inheritance remain unsupported. **Runtime checks** (`RuntimeCheck`): array bounds, file misuse, enum ranges, null dereferences and array-parameter bounds contracts are checked at their emit sites. diff --git a/doc/language/cpsc-language-overview.7.md b/doc/language/cpsc-language-overview.7.md index d2d3617..21fbaff 100644 --- a/doc/language/cpsc-language-overview.7.md +++ b/doc/language/cpsc-language-overview.7.md @@ -16,7 +16,7 @@ Parenthesized type casts, such as (C_INT)Number, have unary precedence. C_INT, C Literals include integers, decimal real numbers, TRUE/FALSE, strings in double quotes, and single-byte characters in single quotes. Negative numbers use unary minus. There are no string or character escape sequences. 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. +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. The compiler extensions TRY/CATCH/ENDTRY and THROW support anonymous exceptions with stack unwinding. Runtime check failures print the source line and error reason to standard output before throwing and can be caught. An uncaught exception also prints a generic termination message and returns status 1. There is no error object or what() support. @@ -41,7 +41,7 @@ The compiler extensions TRY/CATCH/ENDTRY and THROW support anonymous exceptions - [cpsc-keyword-closefile(7)](keyword/cpsc-keyword-closefile.7.md): close a text file. - [cpsc-keyword-type(7)](keyword/cpsc-keyword-type.7.md): define enumerations, pointers, and records. - [cpsc-keyword-c_type(7)](keyword/cpsc-keyword-c_type.7.md): import native C types and explicitly cast values. -- [cpsc-keyword-class(7)](keyword/cpsc-keyword-class.7.md): define a class with public and private fields. +- [cpsc-keyword-class(7)](keyword/cpsc-keyword-class.7.md): define a class with fields and methods. - [cpsc-keyword-and(7)](keyword/cpsc-keyword-and.7.md): combine conditions with logical AND. - [cpsc-keyword-or(7)](keyword/cpsc-keyword-or.7.md): combine conditions with logical OR. - [cpsc-keyword-not(7)](keyword/cpsc-keyword-not.7.md): negate a condition. @@ -70,7 +70,7 @@ Closing and auxiliary keywords are documented with their main constructs: THEN/E # UNSUPPORTED FEATURES -DATE, SET types and DEFINE, random-file operations (RANDOM/SEEK/GETRECORD/PUTRECORD), INT, RAND, string escapes, whole-array assignment or return, array fields, and class methods/constructors/destructors/inheritance (NEW/INHERITS/SUPER). +DATE, SET types and DEFINE, random-file operations (RANDOM/SEEK/GETRECORD/PUTRECORD), INT, RAND, string escapes, whole-array assignment or return, array fields, and class constructors/destructors/inheritance (NEW/INHERITS/SUPER). The individual pages note relevant differences from the Cambridge 2026 pseudocode guide. This manual describes the compiler's current support. diff --git a/doc/language/keyword/cpsc-keyword-call.7.md b/doc/language/keyword/cpsc-keyword-call.7.md index 2d7c553..fd6718f 100644 --- a/doc/language/keyword/cpsc-keyword-call.7.md +++ b/doc/language/keyword/cpsc-keyword-call.7.md @@ -14,6 +14,8 @@ CALL name(arguments) Invoke a previously declared procedure with its parameters. Empty argument lists may be written `CALL name()` or `CALL name`. Use function calls in expressions to obtain their results. As compiler extensions, CALL also accepts functions and discards their results, and `name(arguments)` may stand alone without CALL for either a function or a procedure. Built-ins use the same argument checks in expressions and statements. +Member calls accept `CALL Object.Method(arguments)` or the standalone form `Object.Method(arguments)`. With no arguments, `CALL Object.Method` is also accepted. Inside a method, use `this.Method(arguments)` for the current object; unqualified calls continue to name global functions or procedures. See [cpsc-keyword-class(7)](cpsc-keyword-class.7.md). + # EXAMPLE ```text @@ -25,4 +27,4 @@ CALL Hello() # SEE ALSO -[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-procedure(7)](cpsc-keyword-procedure.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). +[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-class(7)](cpsc-keyword-class.7.md), [cpsc-keyword-procedure(7)](cpsc-keyword-procedure.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). diff --git a/doc/language/keyword/cpsc-keyword-class.7.md b/doc/language/keyword/cpsc-keyword-class.7.md index 81276ac..faa84df 100644 --- a/doc/language/keyword/cpsc-keyword-class.7.md +++ b/doc/language/keyword/cpsc-keyword-class.7.md @@ -2,35 +2,52 @@ # NAME -cpsc-keyword-class, cpsc-keyword-public, cpsc-keyword-private, cpsc-keyword-endclass - define a class with public and private fields +cpsc-keyword-class, cpsc-keyword-public, cpsc-keyword-private, cpsc-keyword-endclass - define a class with fields and methods # SYNOPSIS ```text CLASS name - PUBLIC field : type - PRIVATE field : type + PUBLIC publicField : type + PRIVATE privateField : type + PUBLIC PROCEDURE method(parameters) + statements + ENDPROCEDURE + FUNCTION getter(parameters) RETURNS type + RETURN expression + ENDFUNCTION ENDCLASS ``` # DESCRIPTION -Declare a class at top level with at least one field. Fields are public by default; PUBLIC or PRIVATE may be specified explicitly, without DECLARE. ENDCLASS closes the declaration. +Declare a class at top level with at least one field or method. Fields and methods are public by default; PUBLIC or PRIVATE may be specified for each member. Fields do not use DECLARE. ENDCLASS closes the declaration. Fields and methods share a case-insensitive member namespace; duplicate names and method overloading are rejected. -Classes use record value semantics: zero initialization, whole-value copying, arrays, pointers, and ordinary function/procedure parameters. Only public fields can be accessed externally. PRIVATE fields still initialize and copy with the whole value. Methods, constructors, destructors, NEW, INHERITS, and array fields are unsupported. +Call methods as `Object.Method(arguments)` in expressions or as standalone statements, or use `CALL Object.Method(arguments)`. A receiver may be a variable, array element, nested field, or pointer dereference. Calls may precede definitions; methods may call later methods or recurse. Parameters and return values follow the ordinary FUNCTION and PROCEDURE rules. Access on function or method results remains unsupported. + +Within a method, bare field names refer to the current object's fields. The compiler extension `this` refers directly to the current object: use `this.Field` or `this.Method(arguments)` without pointer dereferencing. An unqualified call such as `Method(arguments)` still names a global function or procedure. PRIVATE members are accessible only from methods of the owning class, including access through another instance of that class. + +Parameters and local variables, arrays, or constants may shadow fields; this produces a warning with the source line and does not prevent compilation. The local name takes precedence; `this.Field` continues to access the field. The name `this` cannot be a class member or a method parameter or local declaration. + +Classes retain record value semantics: zero initialization, whole-value copying, arrays, pointers, and ordinary function/procedure parameters. Methods modify the receiver's storage. The object reference `this` may be read, returned, or passed as an object, including BYREF to a procedure; `this <- Other` copies Other into the current object without rebinding the reference. PRIVATE fields still initialize and copy with the whole value. Constructors, destructors, NEW, INHERITS, and array fields are unsupported. # EXAMPLE ```text -CLASS Person - PUBLIC Name : STRING - PRIVATE Age : INTEGER +CLASS Counter + PRIVATE Value : INTEGER + PUBLIC PROCEDURE Set(Number : INTEGER) + this.Value <- Number + ENDPROCEDURE + FUNCTION Get() RETURNS INTEGER + RETURN Value + ENDFUNCTION ENDCLASS -DECLARE PersonValue : Person -PersonValue.Name <- "Alice" -OUTPUT PersonValue.Name +DECLARE Item : Counter +Item.Set(3) +OUTPUT Item.Get() ``` # SEE ALSO -[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-type(7)](cpsc-keyword-type.7.md), [cpsc-keyword-declare(7)](cpsc-keyword-declare.7.md). +[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-type(7)](cpsc-keyword-type.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md), [cpsc-keyword-procedure(7)](cpsc-keyword-procedure.7.md), [cpsc-keyword-call(7)](cpsc-keyword-call.7.md). diff --git a/doc/language/keyword/cpsc-keyword-function.7.md b/doc/language/keyword/cpsc-keyword-function.7.md index 52efa90..c20bb50 100644 --- a/doc/language/keyword/cpsc-keyword-function.7.md +++ b/doc/language/keyword/cpsc-keyword-function.7.md @@ -21,6 +21,8 @@ As a compiler extension, `name(arguments)` may also be a complete statement that Parameters use `name : type`, optionally prefixed by BYVAL. BYVAL is the default; BYREF is forbidden for functions (guide section 8.3). Array parameters accept `ARRAY OF type` (one dimension) or `ARRAY[lower:upper, ...] OF type` (integer literal bounds). BYVAL arrays are copied. RETURNS, RETURN, BYVAL, and ENDFUNCTION belong here. +A FUNCTION inside CLASS defines a member function, called as `Object.Method(arguments)`. It follows the same parameter and return rules. Within a method, use `this.Method(arguments)` to call another method on the current object; see [cpsc-keyword-class(7)](cpsc-keyword-class.7.md). + # EXAMPLE ```text @@ -32,4 +34,4 @@ OUTPUT Double(4) # SEE ALSO -[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-procedure(7)](cpsc-keyword-procedure.7.md), [cpsc-keyword-call(7)](cpsc-keyword-call.7.md). +[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-class(7)](cpsc-keyword-class.7.md), [cpsc-keyword-procedure(7)](cpsc-keyword-procedure.7.md), [cpsc-keyword-call(7)](cpsc-keyword-call.7.md). diff --git a/doc/language/keyword/cpsc-keyword-procedure.7.md b/doc/language/keyword/cpsc-keyword-procedure.7.md index 74c7024..f21ef59 100644 --- a/doc/language/keyword/cpsc-keyword-procedure.7.md +++ b/doc/language/keyword/cpsc-keyword-procedure.7.md @@ -18,6 +18,8 @@ Invoke with CALL. Parameters use `name : type`, optionally prefixed by BYVAL or Arrays accept `ARRAY OF type` or `ARRAY[lower:upper, ...] OF type`; explicit bounds must be integer literals. BYVAL copies the array; BYREF shares it. Bare RETURN can exit a procedure before a block terminator; RETURN with a value is invalid. BYVAL, BYREF, RETURN, and ENDPROCEDURE belong here. Calls may precede top-level definitions. +A PROCEDURE inside CLASS defines a member procedure, called as `Object.Method(arguments)` or `CALL Object.Method(arguments)`. It follows the same parameter rules and modifies the receiver. Within a method, `this` refers directly to the current object; see [cpsc-keyword-class(7)](cpsc-keyword-class.7.md). + # EXAMPLE ```text @@ -31,4 +33,4 @@ OUTPUT Count # SEE ALSO -[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-call(7)](cpsc-keyword-call.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). +[cpsc-language-overview(7)](../cpsc-language-overview.7.md), [cpsc-keyword-class(7)](cpsc-keyword-class.7.md), [cpsc-keyword-call(7)](cpsc-keyword-call.7.md), [cpsc-keyword-function(7)](cpsc-keyword-function.7.md). |
