3.2.0 Literal Expressions

LiteralExpressionNode (MS-VBAL §5.6.5) represents a value that is statically resolved to a VBTypedValue.

The parser resolves the literal's declared type from the source token: a LiteralExpressionNode already carries a fully-typed VBTypedValue, including the effect of any type-declaration character.


3.2.0.1 Numeric Literal Types

The declared type of a numeric literal follows MS-VBAL §3.3.2:

  1. An explicit type-declaration character suffix, if present, forces the type. A value that does not fit the forced type is a syntax error (NumericLiteralOverflow), located at the literal.

    Suffix Declared type
    % Integer
    & Long
    ^ LongLong
    ! Single
    # Double
    @ Currency
  2. Otherwise, an unsuffixed decimal integer literal (no fractional part, no exponent) takes the smallest of Integer, Long, Double that can hold its value.

  3. Otherwise, a floating-point literal (fractional part or exponent) is Double. The exponent letter is [DEde]D is the legacy double-precision marker and produces the same value as E. A literal that overflows to infinity is a NumericLiteralOverflow syntax error.

  4. A &H… hexadecimal / &O… octal literal is typed by bit width, interpreting the radix digits as a two's-complement value at that width — not by the decimal rule (2). Unsuffixed, it is the narrowest of Integer (16-bit) or Long (32-bit) that the value's bit width fits: &HFFFF is Integer -1, &H8000 is Integer -32768, &H10000 is Long 65536, &HFFFFFFFF is Long -1. &HFFFFFFFF is the largest unsuffixed radix literal; beyond 32 bits is a NumericLiteralOverflow syntax error (use a ^ suffix for a 64-bit LongLong). % / & / ^ set the width (16 / 32 / 64 bits); a radix literal is never Double.

Note

LongLong is only produced by the ^ suffix — an unsuffixed integer literal that exceeds Long range widens to Double, never LongLong. String and $-suffixed identifiers are covered by the declared-type rules for String, not here.


3.2.0.2 Static Symbols

The environment host defines a number of static symbols that are globally defined, on top of the global IStdConstantsModule:

Type Value Literal (token)
VBBooleanType VBBooleanValue True,False
VBStringType VBStringValue VBEmptyString
VBNullType VBNullValue Null
VBVariantType VBEmptyValue Empty
VBObjectType VBNothingValue Nothing

3.2.0.2.1 Instance Expressions - "Me"

Note

MS-VBAL §5.6.11 describes instance expressions as values with the declared type defined by the class module containing the enclosing procedure, statically invalid within a procedural ("standard") module. At run-time, it represents the current instance of the type defined by the enclosing class module and has this type as its value type.

It would be aligned with the specification to implement this "expression" not as such, but rather as a simple runtime artifact: the current object is a common concept in many programming languages (often expressed with the token this). The implementation could be as simple as having the runtime context inject a VBObjectValue presenting the default interface of the enclosing class type - pushing it to the stack frame of instance member calls as it would any parameter.

Tip

In other words, we can get this one "for free" by having the runtime inject an implicit Me (ByVal) parameter to all instance member calls, pointed at the current object.


⏮️ RD-VBAL §3.1 Attributes and Directives | ⏭️ RD-VBAL §3.3 Operators