Skip to main content

nanvm_lib/vm/any/
typeof_.rs

1use crate::vm::{Any, IVm, Nullish, Unpacked};
2
3impl<A: IVm> Any<A> {
4    /// `typeof`. Not a `core::ops` trait — Rust has no unary operator to
5    /// spell it with — so this is a plain method, the same as `unary_plus`.
6    /// Named `typeof_`, not `type_of`: `typeof` is itself a reserved word, and
7    /// a trailing underscore — the convention FJS and JS both use for this —
8    /// resolves the collision while keeping the name recognizable. Never
9    /// throws, but stays a `Result` to match every other operator's shape.
10    /// <https://tc39.es/ecma262/#sec-typeof-operator>
11    pub fn typeof_(&self) -> Result<Any<A>, Any<A>> {
12        let tag = self.with_unpacked(|v| match v {
13            Unpacked::Nullish(Nullish::Undefined) => "undefined",
14            Unpacked::Boolean(_) => "boolean",
15            Unpacked::Number(_) => "number",
16            Unpacked::String(_) => "string",
17            Unpacked::BigInt(_) => "bigint",
18            // `null` is famously an object in JavaScript's `typeof`.
19            Unpacked::Nullish(Nullish::Null) | Unpacked::Object(_) | Unpacked::Array(_) => "object",
20            Unpacked::Function(_) => "function",
21        });
22        Ok(tag.into())
23    }
24}