5.4.3.8 Let Statement
A let statement performs Let-assignment of a non-object value. The Let keyword itself is optional and can be omitted.
-
let-statement = ["Let"] l-expression "=" expression
Static Semantics.
This statement is invalid if any of the following is true:
<expression> cannot be evaluated to a simple data value (section 5.6.2.2).
<l-expression> is classified as something other than a value, variable, property, function or unbound member.
<l-expression> is classified as a value and the declared type of <l-expression> is any type except a class or Object.
<l-expression> is classified as a variable, the declared type of <l-expression> is any type except a class or Object, and a Let coercion from the declared type of <expression> to the declared type of <l-expression> is invalid.
<l-expression> is classified as a property, does not refer to the enclosing procedure, and any of the following is true:
<l-expression> has no accessible Property Let or Property Get.
<l-expression> has an inaccessible Property Let.
<l-expression> has an accessible Property Let and a Let coercion from the declared type of <expression> to the declared type of <l-expression> is invalid.
<l-expression> has no Property Let at all and does have an accessible Property Get and the declared type of <l-expression> is any type except a class or Object or Variant.
<l-expression> is classified as a function, does not refer to the enclosing procedure, and the declared type of <l-expression> is any type except a class or Object or Variant.
<l-expression> is classified as a property or function, refers to the enclosing procedure, and any of the following is true:
The declared type of <l-expression> is any type except a class or Object.
A Let-coercion from the declared type of <expression> to the declared type of <l-expression> is invalid.
Runtime Semantics.
The runtime semantics of Let-assignment are as follows:
If <l-expression> is classified as an unbound member, resolve it first as a variable, property, function or subroutine.
If the declared type of <l-expression> is any type except a class or Object:
Evaluate <expression> as a simple data value to get an expression value.
Let-coerce the expression value from its value type to the declared type of <l-expression>. o If <l-expression> is classified as a variable, assign the coerced expression value to <l-expression>.
If <l-expression> is classified as a property, and does not refer to an enclosing Property Get:
If <l-expression> has an accessible Property Let, invoke the Property Let, passing it any specified argument list, along with the coerced expression value as an extra final parameter.
If <l-expression> does not have a Property Let and does have an accessible Property Get, runtime error 451 (Property let procedure not defined and property get procedure did not return an object) is raised.
If <l-expression> does not have an accessible Property Let or accessible Property Get, runtime error 450 (Wrong number of arguments or invalid property assignment) is raised.
If <l-expression> is classified as a property or function and refers to an enclosing Property Get or function, assign the coerced expression value to the enclosing procedure’s return value.
If <l-expression> is not classified as a variable or property, runtime error 450 (Wrong number of arguments or invalid property assignment) is raised.
Otherwise, if the declared type of <l-expression> is a class or Object:
Evaluate <expression> to get an expression value.
If <l-expression> is classified as a value or a variable:
If the declared type of <l-expression> is a class with a default property, a Let-assignment is performed with <l-expression> being a property access to the object’s default property and <expression> being the coerced expression value.
Otherwise, runtime error 438 (Object doesn’t support this property or method) is raised.
If <l-expression> is classified as a property:
If <l-expression> has an accessible Property Let:
Let-coerce the expression value from its value type to the declared type of the property.
Invoke the Property Let, passing it any specified argument list, along with the coerced expression value as the final value parameter.
If <l-expression> does not have a Property Let and does have an accessible Property Get:
Invoke the Property Get, passing it any specified argument list, getting back an LHS value with the same declared type as the property.
Perform a Let-assignment with <l-expression> being the LHS value and <expression> being the coerced expression value.
Otherwise, if <l-expression> does not have an accessible Property Let or accessible Property Get, runtime error 438 (Object doesn’t support this property or method) is raised.
If <l-expression> is classified as a function:
Invoke the function, passing it any specified argument list, getting back an LHS value with the same declared type as the property.
Perform a Let-assignment with <l-expression> being the LHS value and <expression> being the coerced expression value.
Otherwise, if <l-expression> is not a variable, property or function, runtime error 450 (Wrong number of arguments or invalid property assignment) is raised.