This document summarizes the implementation of two new record operations in the Cure programming language:
record.fieldRecord{base | field: value}2025-10-31
src/parser/cure_ast.hrl)Added two new expression record types:
%% Field access expressions (record.field)
-record(field_access_expr, {
record, % Expression evaluating to a record
field, % Atom: field name
location
}).
%% Record update expressions (Record{old | field: value})
-record(record_update_expr, {
name, % Record type name
base, % Expression for the base record
fields, % List of #field_expr{} records
location
}).
Updated the expr() type definition to include these new types.
src/parser/cure_parser.erl)parsepostfixoperators/2 function to handle postfix operators like .fieldparsebinaryexpression/2 to call postfix operator parsingModule.function()) and field access (record.field)parseidentifieror_call/1 to detect the | pipe operator in record constructionRecord{field: value} (construction) and Record{base | field: value} (update)isidentifiertoken/1 to check if a token is an identifiergetexprlocation/1 to handle new expression typessrc/types/cure_typechecker.erl)infer_expr({field_access_expr, RecordExpr, FieldName, Location}, Env) ->
% Infer record type, look up field type from record definition
% Return field type or error if field doesn't exist
infer_expr({record_update_expr, RecordName, BaseExpr, Fields, Location}, Env) ->
% Check base expression matches record type
% Validate updated fields exist and have correct types
% Return updated record type
convertexprto_tuple/1 for the new expression typessrc/codegen/cure_codegen.erl)compile_record_expr(#field_access_expr{...}, State) ->
% Generate: maps:get(FieldName, Record)
compile_record_expr(#record_update_expr{...}, State) ->
% Generate: BaseRecord#{field1 := Value1, field2 := Value2, ...}
Added dispatch cases in compile_expression/2 for the new expression types.
src/codegen/curebeamcompiler.erl)recordfieldaccess: Compiles to maps:get(Field, Record)record_update: Compiles to map update syntax Map#{field := value}Changed record compilation from Erlang records to maps:
maps:get/2#{...}compile_make_record([RecordName, FieldNames, FieldCount], Context) ->
% Generate: #{field1 => Val1, field2 => Val2, ...}
MapForm = {map, Line, MapAssocs}
examples/04patternguards.cure - Shows record pattern matching with guards (e.g., Point{x: x, y: y} when x == 0.0 and y == 0.0)Point{x: 1.0, y: 2.0}).field) and record update (Record{base | field: value}) syntax#fieldaccessexpr{} and #recordupdateexpr{})compilefieldaccessexpr/2 and compilerecordupdateexpr/2)def get_name(p: Person): String =
p.name # Direct field access
# Chained access
def get_nested_field(contact: Contact): String =
contact.person.name # Access nested record fields
def birthday(p: Person): Person =
Person{p | age: p.age + 1} # Update single field
def move_point(pt: Point, dx: Float, dy: Float): Point =
Point{pt | x: pt.x + dx, y: pt.y + dy} # Update multiple fields
✅ Parser Implementation:
parsepostfixoperators/2 (lines 2756-2801)cure_parser.erl✅ Codegen Implementation:
compilefieldaccessexpr/2: lines 1692-1706 in curecodegen.erlcompilerecordupdateexpr/2: lines 1668-1689 in curecodegen.erlrecordfieldaccess and update_record BEAM instructions✅ AST Definitions:
#fieldaccessexpr{}: lines 293-298 in cure_ast.hrl#recordupdateexpr{}: lines 300-306 in cure_ast.hrlThe parser disambiguates between module qualification and field access by checking:
#identifier_expr{})( token after the field nameThe record update syntax is parsed by:
{ after a record type name{| token| found → record update, otherwise backtrack to regular constructionRecords compile to Erlang maps, which provides:
maps:get/2Potential improvements for future iterations:
Person{p | address.city: "New York"}Person{p | age: a} when a > 18 -> ..}Person{p1 | ...p2} to merge recordssrc/parser/cure_ast.hrl (lines 293-306)src/parser/cure_parser.erlparsepostfixoperators/2)parseidentifieror_call/1)src/codegen/cure_codegen.erlcompilefieldaccess_expr/2: lines 1692-1706compilerecordupdate_expr/2: lines 1668-1689src/types/cure_typechecker.erl (type inference for new expressions)src/codegen/curebeamcompiler.erl (BEAM bytecode generation)examples/04patternguards.cure (record pattern matching)