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.