5.4.3.8 Let Statement
Note
This section describes the implementation of MS-VBAL §5.4.3.8 Let Statement.
Syntax
| AST node | Instruction kind(s) | Notes |
|---|---|---|
AssignmentStatementNode (Kind: ImplicitLet or ExplicitLet) |
Simple |
[Let] lExpression = expression. The Target of an AssignmentStatementNode is always an lExpression; see RD-VBAL §3.0.2 Node Types. |
See RD-VBAL §3.4.2 Simple Statements.
Static Semantics
For a predeclared class Widget, Widget.Size = 3 is valid: it assigns a member of the object the default
instance variable holds. See RD-VBAL §3.1.1 Attributes (VB_PredeclaredId).
Runtime Semantics
The executor dispatches a Let-assignment statement to its statement runtime semantics: Let-assignment is one of
the statement kinds the Simple statement provider handles
(RD-VBAL §3.5.4 Execution).
StatementRuntimeSemanticsProvider.ExecuteLetAssignmentevaluates the value expression.ExecuteLetAssignmentpasses the value toLetAssignmentEvaluator, which assigns it to the target:
| Target | Assignment |
|---|---|
| A bare reference to the procedure's own name, from within its own body | Assigns the ReturnValue slot (the function result variable) instead of the general symbol table. The value is Let-coerced directly. See Function result variable. |
| A UDT field | Let-coerces the value to the field's own declared type, and writes the field's cell. See UDT fields. |
| A variable | Assigns through the "__let_op" Let-assignment operator: Let-assignment reuses the operator pipeline. |
The Set statement does not use the operator pipeline; see RD-VBAL §5.4.3.9 Set Statement. Let-coercion is described in RD-VBAL §5.5.1.2 Runtime semantics.
Function result variable
A Let-assignment to a bare reference to a procedure's own name, from within its own body, assigns the
ReturnValue slot instead of the general symbol table. See
RD-VBAL §5.3.1.6 Subroutine and Function Declarations.
LetAssignmentEvaluator.Assigndetects a self-reference the same way asRuntimeExpressionEvaluator.EvaluateSimpleName: by comparing the resolved symbol'sUriagainstRuntimeEvaluationContext.Scope.StatementRuntimeSemanticsProvider.ExecuteLetAssignmentreaches it throughLetAssignmentEvaluator.Assign.- A bare reference to the function result variable never goes through
"__let_op". The function result variable is not an addressableSymbolwith an IBindingHandle. - The self-reference branch of
LetAssignmentEvaluator.AssignLet-coerces the assigned value directly. - That direct Let-coercion is the same lower-level call that
ByValandByRef-fallback parameter passing make, for the same reason: there is no addressable symbol. See RD-VBAL §5.3.1.11 Procedure Invocation Argument Processing.
Members of an object
obj.Member = value assigns a member of the object obj holds (LetAssignmentEvaluator.AssignObjectMember). A Nothing reference
raises error 91. The member is the Property Let declared for it (an indexed one takes the index arguments before the value) or else a
public variable of the class, found through the declared interface when obj is declared as one its object's class implements
(RD-VBAL §5.3.1.9). A public variable is assigned by Let-coercing the value to
its declared type; with no such member, error 438 is raised. A With block assigns the same way.
Elements of an array
a(i, j) = value, and obj.Items(i) = value when the array is what a public variable of an object holds
(LetAssignmentEvaluator.AssignArrayElement), assigns an element in place: the value is Let-coerced to the element type of the array and
written to the element's own cell, and the array is never copied. A subscript outside the bounds of the array is error 9. Set a(i) = obj does
the same with Set-coercion, and lets go of the object the element held and takes a reference to the one it is given.
A ReDim of an array gives it the element type of the variable's declaration (Dim a() As Long), including a variable of an object.
UDT fields
A Let statement assigns a UDT field by Let-coercing the value to the field's own declared type and writing the field's cell. It writes the cell because a UDT field is not an addressable symbol the way a variable is.
A UDT field is reachable from source code in both directions: a member access reads one, and a Let statement assigns one. See RD-VBAL §5.6.12 Member Access Expressions.
VBA copies a UDT on assignment. A copy of a UDT value gets a field store of its own, deep through a nested UDT; see RD-VBAL §2.5.2.1.3 User-Defined Type (UDT) Values.
Other statements that Let-assign
| Statement | Shares |
|---|---|
For (ForOpener) |
Let-assigns the loop counter to start-value through the same Let-assignment machinery a Let statement uses. See RD-VBAL §5.4.2.3 For Statement. |
Input #, Line Input #, Get |
Resolve their targets with LetAssignmentEvaluator.TryResolveTarget, the same target resolution the Let statement uses. See RD-VBAL §5.4.5 File Statements. |
Implementation
| Type or member | Role |
|---|---|
RDCore.Runtime.Semantics.Statements.StatementRuntimeSemanticsProvider.ExecuteLetAssignment |
Evaluates the value expression and passes it to LetAssignmentEvaluator. |
RDCore.Runtime.Semantics.Statements.LetAssignmentEvaluator.Assign |
Assigns an evaluated value to the target: the function result variable, a UDT field, or a variable through "__let_op". |
LetAssignmentEvaluator.TryResolveTarget |
Resolves the symbol a target names; shared with Input #, Line Input # and Get. |
OperatorSymbolNames.BinaryAssignmentValueOp |
The name of the "__let_op" Let-assignment operator (RDCore.SDK). |
ICallStackFrame.ReturnValue |
The function result variable. |
⏮️ RD-VBAL §5.4.3.7 RSet Statement | ⏭️ RD-VBAL §5.4.3.9 Set Statement