From d65c296a0ad8d335aa076aab48a8b198fa934a2d Mon Sep 17 00:00:00 2001 From: _ov4 Date: Sun, 26 Jul 2026 17:36:41 +0000 Subject: feat: records with designator lvalues, and pointer types (CIE 4.1/4.2) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - New CodeGen::emitLValue resolves any designator — variable, checked array element, record field chain (CreateStructGEP via the record payload), pointer deref (with the null-pointer [Fatal] check) — to an address + type name; loadFromLValue centralizes the rvalue read and the STRING null->"" guard, so zero-initialized STRING fields read as "". - Designator assignment stores through emitLValue + emitCoercedExpr; whole-record copies (r2 <- r1, array elements, BYVAL args, RETURN) are aggregate loads/stores with name-checked admission. - getExprTypeInfo walks designator chains statically (field types from the record payload, deref to the pointee), so records/pointers type correctly in every expression context. - Address-of ^x admits into a pointer target only when the designator's type name equals the declared pointee exactly (nominal, strict: the guide's own ^INTEGER-at-a-Season example is a compile error by design); ^arr[i] and ^rec.field work through the same lvalue path. - Verified: the guide's §4.2 StudentRecord example (minus DATE), nested records, arrays of records with Form[i].YearGroup writes, record BYREF/BYVAL params, NodePtr = ^Node forward reference with writes through n1.Next^.Data, unset-pointer deref dying with [Fatal]. Co-Authored-By: Claude Fable 5 --- include/cps/CodeGen.h | 11 +++++++++++ 1 file changed, 11 insertions(+) (limited to 'include') diff --git a/include/cps/CodeGen.h b/include/cps/CodeGen.h index 713d02b..c0cbeb5 100644 --- a/include/cps/CodeGen.h +++ b/include/cps/CodeGen.h @@ -68,6 +68,17 @@ class CodeGen { // TYPE-system helpers (Designator.cc). void runTypePrePass(const std::vector> &Statements); llvm::Value *emitUserKindBinaryOp(BinaryExprAST *Bin, const TypeInfo *LT, const TypeInfo *RT); + + // An addressable location and the pseudocode type stored there. + struct LValueInfo { + llvm::Value *Addr = nullptr; + std::string TypeName; + }; + // Resolves a variable / array element / field chain / deref to an address + // (emitting index and null-pointer checks along the way). + bool emitLValue(ExprAST *E, LValueInfo &Out); + // The rvalue read: load + the STRING null->"" guard. + llvm::Value *loadFromLValue(const LValueInfo &LV); bool marshalCallArgs(const std::string &Callee, const std::vector> &ArgExprs, std::vector &Out); -- cgit v1.3.1-4-g156e