vb6runtime 0.2.0

VB6 runtime library - value system, type conversions, and standard library implementations
Documentation
# Parameter classification

- **typed** — every parameter is a wrapper (`&VBString`, `&VBLong`, ...);
  conversion happens once at the host boundary via `boundary::arg`;
  Null raises error 94 there.
- **variant-input** — non-`$` form whose primary input stays `&VBVariant`
  by design (A8: Variant-returning siblings of `$` forms); auxiliary
  numeric/string parameters are still typed. The function body decides
  Null propagation.
- **\$-strict**`$` form, all parameters typed, Null raises 94.
- **predicate** — observes the un-coerced variant; stays `&VBVariant`.
- **structural** — array/list parameters that are genuinely Variant.
- **statement-form** — executed by `exec::*`, conversions wrapped by
  `error_here` (see table at the bottom).

## `arrays`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `array` | 0..∞ | `fn(elements: &[VBVariant]) -> VBVariant` | structural | propagates Null |
| `filter` | 2..4 | `fn(sourcearray: &VBVariant, match_string: &VBString, include: Option<&VBBoolean>, compare: Option<&VBLong>) -> VBResult<VBVariant>` | structural | propagates Null |
| `join` | 1..2 | `fn(sourcearray: &VBVariant, delimiter: Option<&VBString>) -> VBResult<String>` | structural | propagates Null |
| `lbound` | 1..2 | `fn(array: &VBVariant, dimension: Option<&VBLong>) -> VBResult<VBVariant>` | structural | propagates Null |
| `split` | 1..4 | `fn(expression: &VBString, delimiter: Option<&VBString>, limit: Option<&VBLong>, compare: Option<&VBLong>) -> VBResult<VBVariant>` | typed | raises 94 |
| `ubound` | 1..2 | `fn(array: &VBVariant, dimension: Option<&VBLong>) -> VBResult<VBVariant>` | structural | propagates Null |

## `conversion`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `cverr` | 1..1 | `fn(errornumber: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `hex` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `hex$` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBString>` | $-strict | raises 94 |
| `oct` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `oct$` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBString>` | $-strict | raises 94 |
| `vartype` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |

## `datetime`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `date` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `date$` | 0..0 | `fn() -> VBResult<VBString>` | \$-strict | raises 94 |
| `dateadd` | 3..3 | `fn(interval: &VBString, number: &VBDouble, date: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `datediff` | 3..5 | `fn(interval: &VBString, date1: &VBDate, date2: &VBDate, first_day_of_week: Option<&VBLong>, first_week_of_year: Option<&VBLong>) -> VBResult<VBVariant>` | typed | raises 94 |
| `datepart` | 2..4 | `fn(interval: &VBString, date: &VBDate, first_day_of_week: Option<&VBLong>, first_week_of_year: Option<&VBLong>) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `dateserial` | 3..3 | `fn(year: &VBLong, month: &VBLong, day: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `datevalue` | 1..1 | `fn(date: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `day` | 1..1 | `fn(date: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `hour` | 1..1 | `fn(time: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `minute` | 1..1 | `fn(time: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `month` | 1..1 | `fn(date: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `monthname` | 1..2 | `fn(month: &VBLong, abbreviate: Option<&VBBoolean>) -> VBResult<VBString>` | typed | raises 94 |
| `now` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `second` | 1..1 | `fn(time: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `time` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `time$` | 0..0 | `fn() -> VBResult<VBString>` | \$-strict | raises 94 |
| `timer` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `timeserial` | 3..3 | `fn(hour: &VBLong, minute: &VBLong, second: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `timevalue` | 1..1 | `fn(time: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `weekday` | 1..2 | `fn(date: &VBDate, firstdayofweek: Option<&VBLong>) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `weekdayname` | 1..3 | `fn(weekday: &VBLong, abbreviate: Option<&VBBoolean>, firstdayofweek: Option<&VBLong>) -> VBResult<VBString>` | typed | raises 94 |
| `year` | 1..1 | `fn(date: &VBDate) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |

## `environment`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `deletesetting` | 2..3 | `fn(appname: &VBString, section: &VBString, key: Option<&VBString>) -> VBResult<VBVariant>` | typed | raises 94 |
| `environ` | 1..1 | `fn(arg: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `environ$` | 1..1 | `fn(arg: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 5 |
| `error` | 0..1 | `fn(arg: Option<&VBVariant>) -> VBResult<VBVariant>` | variant-input | raises 94 |
| `error$` | 0..1 | `fn(arg: Option<&VBVariant>) -> VBResult<VBVariant>` | variant-input | raises 94 |
| `getallsettings` | 2..2 | `fn(appname: &VBString, section: &VBString) -> VBResult<VBVariant>` | typed | raises 94 |
| `getautoserversettings` | 3..3 | `fn(progid: &VBString, clsid: &VBString, machine: &VBString) -> VBResult<VBVariant>` | typed | raises 94 |
| `getsetting` | 3..4 | `fn(appname: &VBString, section: &VBString, key: &VBString, default: Option<&VBString>) -> VBResult<VBVariant>` | typed | raises 94 |
| `imestatus` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `savesetting` | 4..4 | `fn(appname: &VBString, section: &VBString, key: &VBString, value: &VBString) -> VBResult<VBVariant>` | typed | raises 94 |

## `file`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `chdir` | 1..1 | `fn(path: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `chdrive` | 1..1 | `fn(drive: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `curdir` | 0..1 | `fn(drive: Option<&VBVariant>) -> VBResult<VBVariant>` | variant-input | raises 13 |
| `curdir$` | 0..1 | `fn(drive: Option<&VBVariant>) -> VBResult<VBVariant>` | variant-input | raises 13 |
| `dir` | 0..2 | `fn(pathname: Option<&VBVariant>, attributes: Option<&VBVariant>) -> VBResult<VBVariant>` | variant-input | raises 13 |
| `eof` | 1..1 | `fn(file_number: &VBVariant) -> VBResult<VBBoolean>` | variant-input | raises 13 |
| `fileattr` | 2..2 | `fn(file_number: &VBVariant, return_type: &VBVariant) -> VBResult<VBLong>` | variant-input | raises 13 |
| `filecopy` | 2..2 | `fn(source: &VBVariant, destination: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `filedatetime` | 1..1 | `fn(pathname: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 13 |
| `filelen` | 1..1 | `fn(pathname: &VBVariant) -> VBResult<VBLong>` | variant-input | raises 13 |
| `freefile` | 0..1 | `fn(range: Option<&VBVariant>) -> VBResult<VBInteger>` | variant-input | Null acts as omitted |
| `getattr` | 1..1 | `fn(pathname: &VBVariant) -> VBResult<VBInteger>` | variant-input | raises 13 |
| `input` | 2..2 | `fn(number_chars: &VBVariant, file_number: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 13 |
| `kill` | 1..1 | `fn(pathname: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `loc` | 1..1 | `fn(file_number: &VBVariant) -> VBResult<VBLong>` | variant-input | raises 13 |
| `lof` | 1..1 | `fn(file_number: &VBVariant) -> VBResult<VBLong>` | variant-input | raises 13 |
| `mkdir` | 1..1 | `fn(path: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `name` | 2..2 | `fn(old_pathname: &VBVariant, new_pathname: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `rmdir` | 1..1 | `fn(path: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |
| `seek` | 1..1 | `fn(file_number: &VBVariant) -> VBResult<VBLong>` | variant-input | raises 13 |
| `setattr` | 2..2 | `fn(pathname: &VBVariant, attributes: &VBVariant) -> VBResult<()>` | variant-input | raises 13 |

## `financial`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `ddb` | 4..5 | `fn(cost: &VBDouble, salvage: &VBDouble, life: &VBDouble, period: &VBDouble, factor: Option<&VBDouble>) -> VBResult<VBVariant>` | typed | raises 94 |
| `fv` | 3..5 | `fn(rate: &VBDouble, nper: &VBDouble, pmt: &VBDouble, pv: Option<&VBDouble>, type_: Option<&VBInteger>) -> VBResult<VBVariant>` | typed | raises 94 |
| `ipmt` | 4..6 | `fn(rate: &VBDouble, per: &VBDouble, nper: &VBDouble, pv: &VBDouble, fv: Option<&VBDouble>, type_: Option<&VBInteger>) -> VBResult<VBVariant>` | typed | raises 94 |
| `irr` | 1..2 | `fn(values: &VBVariant, guess: Option<&VBDouble>) -> VBResult<VBVariant>` | structural | propagates Null |
| `mirr` | 2..2 | `fn(values: &VBVariant, finance_rate: &VBDouble, reinvest_rate: &VBDouble) -> VBResult<VBVariant>` | structural | propagates Null |
| `nper` | 3..5 | `fn(rate: &VBDouble, pmt: &VBDouble, pv: &VBDouble, fv: Option<&VBDouble>, type_: Option<&VBInteger>) -> VBResult<VBVariant>` | typed | raises 94 |
| `npv` | 2..2 | `fn(rate: &VBDouble, values: &VBVariant) -> VBResult<VBVariant>` | structural | propagates Null |
| `pmt` | 3..5 | `fn(rate: &VBDouble, nper: &VBDouble, pv: &VBDouble, fv: Option<&VBDouble>, type_val: Option<&VBDouble>) -> VBResult<VBVariant>` | typed | raises 94 |
| `ppmt` | 4..6 | `fn(rate: &VBDouble, per: &VBDouble, nper: &VBDouble, pv: &VBDouble, fv: Option<&VBDouble>, type_: Option<&VBInteger>) -> VBResult<VBVariant>` | typed | raises 94 |
| `pv` | 3..5 | `fn(rate: &VBDouble, nper: &VBDouble, pmt: &VBDouble, fv: Option<&VBDouble>, type_: Option<&VBInteger>) -> VBResult<VBVariant>` | typed | raises 94 |
| `rate` | 3..6 | `fn(nper: &VBDouble, pmt: &VBDouble, pv: &VBDouble, fv: Option<&VBDouble>, type_: Option<&VBInteger>, guess: Option<&VBDouble>) -> VBResult<VBVariant>` | typed | raises 94 |
| `sln` | 3..3 | `fn(cost: &VBDouble, salvage: &VBDouble, life: &VBDouble) -> VBResult<VBVariant>` | typed | raises 94 |
| `syd` | 4..4 | `fn(cost: &VBDouble, salvage: &VBDouble, life: &VBDouble, period: &VBDouble) -> VBResult<VBVariant>` | typed | raises 94 |

## `graphics`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `loadpicture` | 0..1 | `fn(filename: Option<&VBString>) -> VBResult<VBVariant>` | typed | raises 94 |

## `interaction`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `beep` | 0..0 | `fn() -> ()` | typed | raises 94 |
| `command` | 0..0 | `fn() -> VBResult<VBString>` | typed | raises 94 |
| `command$` | 0..0 | `fn() -> VBResult<VBString>` | $-strict | raises 94 |
| `doevents` | 0..0 | `fn() -> VBResult<VBVariant>` | typed | raises 94 |
| `msgbox` | 1..5 | `fn(prompt: &VBString, buttons: Option<&VBLong>, title: Option<&VBString>, helpfile: Option<&VBString>, context: Option<&VBLong>) -> VBResult<VBVariant>` | typed | raises 94 |
| `shell` | 1..2 | `fn(pathname: &VBString, window_style: Option<&VBLong>) -> VBResult<VBVariant>` | typed | raises 94 |

## `logic`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `choose` | 2..∞ | `fn(index: &VBLong, choices: &[VBVariant]) -> VBResult<VBVariant>` | structural | propagates Null (dispatch) |
| `iif` | 3..3 | `fn(condition: &VBBoolean, truepart: &VBVariant, falsepart: &VBVariant) -> VBResult<VBVariant>` | structural | propagates Null (dispatch) |
| `switch` | 2..∞ | `fn(arguments: &[VBVariant]) -> VBResult<VBVariant>` | structural | propagates Null |

## `math`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `abs` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `atn` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `cos` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `exp` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `fix` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `int` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `log` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `rnd` | 0..1 | `fn(number: Option<&VBSingle>) -> VBResult<VBVariant>` | typed | raises 94 |
| `round` | 1..2 | `fn(expression: &VBDouble, numdecimalplaces: Option<&VBLong>) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `sgn` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `sin` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `sqr` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `tan` | 1..1 | `fn(value: &VBDouble) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |

## `objects`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `typename` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |

## `resources`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `loadresdata` | 2..2 | `fn(index: &VBVariant, format: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 326 |
| `loadrespicture` | 2..2 | `fn(index: &VBVariant, format: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 326 |
| `loadresstring` | 1..1 | `fn(index: &VBVariant) -> VBResult<VBVariant>` | variant-input | raises 326 |

## `string`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `asc` | 1..1 | `fn(input: &VBString) -> VBResult<VBLong>` | typed | raises 94 |
| `ascb` | 1..1 | `fn(input: &VBString) -> VBResult<VBLong>` | typed | raises 94 |
| `ascw` | 1..1 | `fn(input: &VBString) -> VBResult<VBLong>` | typed | raises 94 |
| `chr` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `chr$` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `chrb` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `chrb$` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBString>` | $-strict | raises 94 |
| `chrw` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `chrw$` | 1..1 | `fn(charcode: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `format` | 1..4 | `fn(expression: &VBVariant, format: Option<&VBString>, firstdayofweek: Option<&VBLong>, firstweekofyear: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `format$` | 1..4 | `fn(expression: &VBVariant, format: Option<&VBString>, firstdayofweek: Option<&VBLong>, firstweekofyear: Option<&VBLong>) -> VBResult<VBString>` | \$-strict | raises 94 |
| `formatcurrency` | 1..5 | `fn(expression: &VBVariant, numdigitsafterdecimal: Option<&VBLong>, includeleadingdigit: Option<&VBLong>, useparensfornegativenumbers: Option<&VBLong>, groupdigits: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `formatdatetime` | 1..2 | `fn(expression: &VBVariant, namedformat: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `formatnumber` | 1..5 | `fn(expression: &VBVariant, numdigitsafterdecimal: Option<&VBLong>, includeleadingdigit: Option<&VBLong>, useparensfornegativenumbers: Option<&VBLong>, groupdigits: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `formatpercent` | 1..5 | `fn(expression: &VBVariant, numdigitsafterdecimal: Option<&VBLong>, includeleadingdigit: Option<&VBLong>, useparensfornegativenumbers: Option<&VBLong>, groupdigits: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `instr` | 2..4 | `fn(start: Option<&VBLong>, string1: &VBString, string2: &VBString, compare: Option<&VBLong>) -> VBResult<VBLong>` | typed | propagates Null (dispatch) |
| `instrrev` | 2..4 | `fn(stringcheck: &VBString, stringmatch: &VBString, start: Option<&VBLong>, compare: Option<&VBLong>) -> VBResult<VBLong>` | typed | raises 94 |
| `lcase` | 1..1 | `fn(input: &VBString) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `lcase$` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | \$-strict | raises 94 |
| `left` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `left$` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `leftb` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `leftb$` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `len` | 1..1 | `fn(input: &VBString) -> VBResult<VBLong>` | typed | raises 94 |
| `lenb` | 1..1 | `fn(input: &VBString) -> VBResult<VBLong>` | typed | raises 94 |
| `lset` | 2..2 | `fn(stringvar: &VBString, string: &VBString) -> VBResult<VBString>` | typed | raises 94 |
| `ltrim` | 1..1 | `fn(input: &VBString) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `ltrim$` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | \$-strict | raises 94 |
| `mid` | 2..3 | `fn(input: &VBString, start: &VBLong, length: Option<&VBLong>) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `mid$` | 2..3 | `fn(input: &VBString, start: &VBLong, length: Option<&VBLong>) -> VBResult<VBString>` | \$-strict | raises 94 |
| `midb` | 2..3 | `fn(input: &VBString, start: &VBLong, length: Option<&VBLong>) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `midb$` | 2..3 | `fn(input: &VBString, start: &VBLong, length: Option<&VBLong>) -> VBResult<VBString>` | \$-strict | raises 94 |
| `replace` | 3..6 | `fn(expression: &VBVariant, find: &VBVariant, replace: &VBVariant, start: Option<&VBLong>, count: Option<&VBLong>, compare: Option<&VBLong>) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `right` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `right$` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `rightb` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `rightb$` | 2..2 | `fn(input: &VBString, length: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `rset` | 2..2 | `fn(stringvar: &VBString, string: &VBString) -> VBResult<VBString>` | typed | raises 94 |
| `rtrim` | 1..1 | `fn(input: &VBString) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `rtrim$` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | \$-strict | raises 94 |
| `space` | 1..1 | `fn(number: &VBLong) -> VBResult<VBVariant>` | typed | raises 94 |
| `space$` | 1..1 | `fn(number: &VBLong) -> VBResult<VBString>` | \$-strict | raises 94 |
| `str` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `str$` | 1..1 | `fn(number: &VBVariant) -> VBResult<VBString>` | \$-strict | raises 94 |
| `strcomp` | 2..3 | `fn(string1: &VBString, string2: &VBString, compare: Option<&VBLong>) -> VBResult<VBInteger>` | typed | raises 94 |
| `strconv` | 2..3 | `fn(string: &VBString, conversion: &VBLong, lcid: Option<&VBLong>) -> VBResult<VBVariant>` | typed | raises 94 |
| `strconv$` | 2..3 | `fn(string: &VBString, conversion: &VBLong, _lcid: Option<&VBLong>) -> VBResult<VBString>` | \$-strict | raises 94 |
| `string` | 2..2 | `fn(number: &VBLong, character: &VBVariant) -> VBResult<VBVariant>` | variant-input | propagates Null |
| `string$` | 2..2 | `fn(number: &VBLong, character: &VBVariant) -> VBResult<VBString>` | variant-input | propagates Null |
| `strreverse` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | typed | propagates Null (dispatch) |
| `trim` | 1..1 | `fn(input: &VBString) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `trim$` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | \$-strict | raises 94 |
| `ucase` | 1..1 | `fn(input: &VBString) -> VBResult<VBVariant>` | typed | propagates Null (dispatch) |
| `ucase$` | 1..1 | `fn(input: &VBString) -> VBResult<VBString>` | \$-strict | raises 94 |

## `type_checking`

| Function | Arity | Runtime signature | Class | Null |
|---|---|---|---|---|
| `isarray` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `isdate` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `isempty` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `iserror` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `ismissing` | 0..1 | `fn(value: Option<&VBVariant>) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `isnull` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `isnumeric` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |
| `isobject` | 1..1 | `fn(value: &VBVariant) -> VBResult<VBVariant>` | predicate | n/a (observes raw variant) |

## Statement forms (exec-wired, not registry dispatch)

| Statement | Runtime primitive | Boundary conversions in exec | Null |
|---|---|---|---|
| `Date` / `Time` (=) | `date_statement` / `time_statement` | value -> date serial (`as_date_serial`) | raises on bad coerce |
| `LSet` / `RSet` var = s | `lset_statement` / `rset_statement` | both sides -> `VBString` | renders `Error n`, else 94/13 |
| `Mid`/`MidB` target(start[,len]) = s | `mid_statement` / `midb_statement` | start,len -> `VBLong`; strings -> `VBString` | raises on bad coerce |
| `AppActivate title[,wait]` | `app_activate` | title -> string, wait -> bool | renders `Error n` for title |
| `SendKeys keys[,wait]` | `send_keys` | keys -> string, wait -> bool | same |
| `SavePicture pic, file` | `save_picture` | filename -> `VBString` | raises |
| `Open`/`Close`/`Print #`/`Input #`/`Write #` | `exec/file_io.rs` | path/mode/record -> typed forms | raises |

Statement-form operands arrive as flat token runs; their conversions
live in `vb6interpret/src/exec/*` until the parser emits expression
nodes, and are out of scope for the registry sweep.