5.4.3.6 LSet Statement
Note
This section describes the implementation of MS-VBAL §5.4.3.6 LSet Statement.
LSet (MS-VBAL §5.4.3.6) and RSet
(MS-VBAL §5.4.3.7 RSet Statement;
RD-VBAL §5.4.3.7 RSet Statement) are implemented.
Syntax
| AST node | Instruction kind(s) | Notes |
|---|---|---|
AssignmentStatementNode (Kind: LSet) |
Simple |
The same node shape as Let, Set and RSet, which share AssignmentStatementNode and are distinguished by its AssignmentKind Kind. |
See RD-VBAL §3.4.2 Simple Statements.
Static Semantics
A program written against MS-VBA that uses LSet over a record holding a variable-length String member relies
on what MS-VBA does with it (see UDT form). The statement says so with a semantic flag, and not with an error: it is not wrong.
FixedAssignmentRuntimeSemantics.Analyze sets the
FixedAssignmentSemanticFlags of the statement, the way an operator's Analyze sets its own:
| Flag | Set when |
|---|---|
StringTarget |
The target is a String: the string form. |
UserDefinedTypeCopy |
LSet between two user-defined types: the byte copy. |
SourceHoldsVariableLengthString |
The source of the byte copy has a variable-length String member, at any depth. |
DestinationHoldsVariableLengthString |
The destination of the byte copy has one. |
Failed |
The operation raises a run-time error: the target is neither. |
A diagnostic is the job of an analyzer that reads the flags (RDCore.Diagnostics, or any other).
Runtime Semantics
LSet has two forms:
| Form | Operands | Effect |
|---|---|---|
| String form | A String target |
Fits a value into the width the target already has. |
| UDT form | Two UDT variables | Copies one UDT over another as bytes. |
String form
LSet fits a value into the width the target already has. It takes the target's width from the target's current
value, not from its declared type. Taking the width from the current value makes LSet meaningful on a
variable-length String, and harmless on one.
LSet and RSet differ only in which end pads: LSet is left-aligned and RSet is right-aligned. Both truncate
from the same end.
| Value, compared with the target's width | LSet |
RSet |
|---|---|---|
| Shorter | Left-aligned: padded at the end. | Right-aligned: padded at the start. |
| Longer | Truncated. | Truncated from the same end as LSet. |
UDT form
LSet's other form is a byte copy between two UDT variables. LSet copies a UDT as bytes because a byte copy
between two UDTs is how VBA emulates a union.
- The source record is laid out through its own layout (VBUserDefinedTypeLayout).
- Only the bytes both types have are copied.
- The copied bytes are read back through the destination's layout. For example, a
Longis reinterpreted as twoIntegers. - A destination field that the source's image does not reach is set to its declared type's default value, rather than being filled with half a value.
A variable-length String member is not part of the byte image:
- In MS-VBA,
LSetover a UDT with a variable-lengthStringmember copies the pointer, leaving two records owning one allocation, which corrupts the process. - In RD-VBA, a variable-length
Stringmember of a UDT has no byte image. - The value of a variable-length
Stringmember is carried across only when the destination has a field of the same type at the same offset. LSet's UDT form never reinterprets a reference as a different kind of reference.
The layout and the field store of a UDT value are described in RD-VBAL §2.5.2.1.3 User-Defined Type (UDT) Values.
Implementation
| Type or member | Role |
|---|---|
| VBUserDefinedTypeImage | The byte copy of LSet's UDT form (RDCore.SDK). |
VBUserDefinedTypeLayout |
The layout a record is laid out through, and read back through (RDCore.SDK). |
RDCore.Runtime.Semantics.Statements.StatementRuntimeSemanticsProvider |
Dispatches an AssignmentStatementNode whose Kind is LSet or RSet; see RD-VBAL §3.5.4 Execution. |
⏮️ RD-VBAL §5.4.3.5 Mid/MidB/Mid$/MidB$ Statement | ⏭️ RD-VBAL §5.4.3.7 RSet Statement