Table of Contents

5.6.10 Simple Name Expressions

Note

This section describes the implementation of MS-VBAL §5.6.10 Simple Name Expressions.

Syntax

Expression AST node Binding context Resolver call
A bare name SimpleNameExpressionNode Default binding context ISymbolResolver.ResolveValue

🎯 In RDCore, name lookups are an explicit evaluation step involving specific AST nodes such as SimpleNameExpressionNode. A simple name expression calls ISymbolResolver.ResolveValue, which binds under the default binding context. See RD-VBAL §3.0.3 Binding Contexts.

Static Semantics

The declared type of a simple name expression is the declared type of the entity its identifier resolves to. The identifier resolves per the ordered lookup of RD-VBAL §2.3.1.3 Name Resolution.

This section specifies how a simple name expression's declared type is determined from a ResolveValue outcome. SimpleNameExpressionStaticSemantics implements it.

Candidates

ResolveValue and ResolveType bind different candidates (MS-VBAL §5.6.10). A simple name expression is bound by ResolveValue:

ResolveValue binds ResolveValue never binds
A variable, constant, Enum type or Enum member, property, function, subroutine, procedural module or project. A user-defined type or a class module.

The name of a class that is not predeclared, used in an expression, is an undefined variable. See RD-VBAL §3.1.1.6 VB_PredeclaredId and RD-VBAL §2.3.1.3 Name Resolution.

Declared Type

Resolved entity Declared type of the simple name expression
A Symbol that determines its own declared type (ITypedSymbol) That type, directly.
A bare procedure reference The procedure's return type.
A bare reference to a Sub VBVoidType.

Type Characters

MS-VBAL §5.6.10 makes a name invalid when its type character does not match the declared type of what it names: x$ of a variable declared As Long is VBC09335 Type-declaration character does not match declared data type, as it is in MS-VBA. A function of the library that has a form with the character in its name (Left$) is that form.

🎯 A reserved function of the library takes any type character, which MS-VBA ignores (recorded in Excel): Len$("abc") is 3, a Long, and CVar$(5), Abs%(-3) and CInt$(2.6) are the functions without it. RD-VBA does as MS-VBA does, and RDC11019 warns where the character is not the function's type. Any other function of the library refuses a character that does not match: Asc$("A"), Sqr$(4) are VBC09335.

Resolution Outcomes

The static semantics of a simple name expression have three outcomes, depending on the resolver's result. Each outcome is a StaticSemanticsEvaluationResult:

Resolver result Outcome
Ambiguous: Duplicate or Ambiguous (see RD-VBAL §2.3.1.3 Name Resolution) An Error carrying AmbiguousName or DuplicateDeclaration (VBCompileErrorId).
Unresolved, under Option Explicit An Error carrying VariableNotDefined (VBCompileErrorId).
Unresolved, without Option Explicit Success(VBUnknownType) (VBUnknownType).

SimpleNameExpressionStaticSemantics consumes ResolveValue's error outcomes, and reports an ambiguous or duplicate name as a coded compile-time error. See RD-VBAL §2.3.1.3 Name Resolution.

The static-semantics layer consumes ModuleDirectives to decide whether an unresolved simple name is a deferred VBUnknownType or a VBC09302 Variable not defined compile-time error. See RD-VBAL §5.2.1 Option Directives and RD-VBAL §2.3.1.3 Name Resolution.

A Name That Is No Value

A project, a procedural module and an Enum type qualify the names of what they declare (VBA.Len, Strings.Left, Color.Red): as the owner of a member access they are what they are, and by themselves they are no value, variable or procedure. Written bare or qualified (VBA.Strings, Globals.Color) where an expression is, each is an error of what it is, as MS-VBA reports it (recorded in Excel), with a verbose message that says what the name is (NameClassificationStaticSemantics):

The name is Error
A project or a library (VBA) VBC09376 Expected variable or procedure, not project
A procedural module, of the project or of a library (Globals, Strings) VBC09363 Expected variable or procedure, not module
An Enum type (Color) VBC09377 Expected variable or procedure, not enum type

That is the error wherever the name is: a value, an argument, the target of a Let or a Set, the operand of Not, of a negation or of parentheses, a condition, a statement by itself. A few places report it as what they require of the name instead:

Where Example Error
The operand of a binary operator Strings + 1, VBA & "x", Color = 1, Strings Is Nothing VBC09310 Type mismatch
The value a Set statement assigns Set o = Strings, Set o = Color VBC09310 Type mismatch
What Len and LenB measure Len(Globals), LenB(Strings) VBC09333 Variable required
What a With block is about With Strings VBC09378 (RD-VBAL §5.4.2.21)
What a For Each loop iterates For Each v In VBA VBC09379 (RD-VBAL §5.4.2.4)

A user-defined type or a class is no candidate of ResolveValue at all: its name is an undefined variable (x = Pair), and Method or data member not found qualified by its module (Program.Pair).

Unresolved Names

MS-VBA permits an implicit Variant declaration for an unresolved name (without Option Explicit).

RD-VBA defers inferring the type of an unresolved name to a later type-inference pass (IVBInferableType), rather than deciding it in the simple-name-expression rule. See RD-VBAL §2.4.4 Deferred Types.

Runtime Semantics

RuntimeExpressionEvaluator.EvaluateSimpleName evaluates a simple name expression according to the symbol the name resolves to:

Resolved symbol Evaluation
A Sub, Function or Property Get, referenced by a bare name (other than the executing Function or Property Get itself, below) An implicit call: the procedure is invoked through IProcedureInvoker, with zero arguments.
The executing Function or Property Get: a bare reference to a procedure's own name, from within its own body Reads the ReturnValue slot instead of the general symbol table.
A Const, EnumConst, module or instance field, or UDT field A plain value read, not an implicit call attempt.

See RD-VBAL §5.3.1.11 Procedure Invocation Argument Processing for the invocation itself.

Members of the Current Instance

A member of a class module named bare in the module's own code is a member of the current instance: the call is made on Me. This holds for every form of the call: a Sub named alone (Helper) or with Call (Call Helper), a Function given arguments (Twice(3)), a Property Get read by its name (If IsEmptyBox Then), and a Property Let assigned by it (Size = 3). A member called on one object therefore reads and writes that object's state, and no other's, whichever object it is, the class's default instance included (RD-VBAL §5.2.4.1.2 Default Instance Variables Static Semantics).

Implicit Calls

RuntimeExpressionEvaluator's bare SimpleName dispatch decides whether a name is an implicit call by checking the two callable leaf symbol types, VBFunctionMemberSymbol and VBPropertyGetMemberSymbol. It does not check their shared base type, VBReturningMemberSymbol.

VBReturningMemberSymbol is the base type of a Function's and a Property Get's member symbol. Const, EnumConst, module-level and instance fields, and UDT fields share this base type with Function and Property Get symbols. See RD-VBAL §2.5.1 Runtime Entities.

For an index expression, whether its Callee is a bare name resolving to a Sub, Function or Property Get is checked before the usual recursive Evaluate(Callee). Otherwise, the bare-name Callee would already have been auto-invoked with zero arguments by SimpleName's own dispatch, before the index expression could supply its arguments. See RD-VBAL §5.6.13 Index Expressions.

Function Result Variable

A bare reference to a procedure's own name, from within its own body, reads the ReturnValue slot (ICallStackFrame.ReturnValue) instead of the general symbol table. See RD-VBAL §5.3.1.6 Subroutine and Function Declarations.

RuntimeExpressionEvaluator.EvaluateSimpleName detects a self-reference to the executing procedure by comparing the resolved symbol's Uri against RuntimeEvaluationContext.Scope. RuntimeProcedureInvoker sets RuntimeEvaluationContext.Scope to the invoked procedure's own Uri for the whole activation (RD-VBAL §5.3.1.11 Procedure Invocation Argument Processing).

RuntimeExpressionEvaluator.EvaluateInstance resolves Me from the same RuntimeEvaluationContext.Scope. See RD-VBAL §5.6.11 Instance Expressions.

Arrays

A plain array-typed variable read back as an expression (SimpleNameExpressionNode, the ordinary shape of arr in For Each item In arr) yields the array value stored in it. See RD-VBAL §2.5.2.1.2 Array Values and RD-VBAL §5.4.2.4 For Each Statement.

Implementation

Type or member Role
SimpleNameExpressionStaticSemantics Static semantics: the declared type of a simple name expression, and its compile-time errors.
RuntimeExpressionEvaluator.EvaluateSimpleName (RDCore.Runtime) Runtime semantics: a value read, an implicit call, or a read of the function result variable.

⏮️ RD-VBAL §5.6.9.8 Logical Operators | ⏭️ RD-VBAL §5.6.11 Instance Expressions