nanvm_lib/vm/any/instanceof_.rs
1use crate::vm::{
2 Any, Array, BigInt, Function, IVm, Number, Object, String, ToAny, dispatch::Dispatch,
3 nullish::Nullish,
4};
5
6/// The constructors `instanceof` may name: the EDAG's `constructorId`, a
7/// closed list — `Array` alone today, where `Map` and `Set` are one variant
8/// each once the VM has such values. A name, not a value: no global is a
9/// value in the EDAG, so the operator's right side is carried as the word
10/// it is, and a variant here rather than an `Any<A>`.
11#[derive(Clone, Copy, Debug, PartialEq, Eq)]
12pub enum Constructor {
13 Array,
14}
15
16/// `x instanceof Array`, over `Unpacked`: `true` of an array and `false` of
17/// every other value, `null` and `undefined` included.
18struct InstanceOfArray;
19
20impl<A: IVm> Dispatch<A> for InstanceOfArray {
21 type Result = bool;
22
23 fn nullish(self, _: Nullish) -> Self::Result {
24 false
25 }
26
27 fn bool(self, _: bool) -> Self::Result {
28 false
29 }
30
31 fn number(self, _: Number) -> Self::Result {
32 false
33 }
34
35 fn string(self, _: String<A>) -> Self::Result {
36 false
37 }
38
39 fn bigint(self, _: BigInt<A>) -> Self::Result {
40 false
41 }
42
43 fn object(self, _: Object<A>) -> Self::Result {
44 false
45 }
46
47 fn array(self, _: Array<A>) -> Self::Result {
48 true
49 }
50
51 fn function(self, _: Function<A>) -> Self::Result {
52 false
53 }
54}
55
56impl<A: IVm> Any<A> {
57 /// `instanceof`, against a built-in constructor. Not a `core::ops`
58 /// trait — Rust has no operator to spell it with — so this is a plain
59 /// method, named as `typeof_` is: a trailing underscore keeps the
60 /// reserved-word spelling recognizable. Never throws: the right side is
61 /// a constructor by construction, so JavaScript's `TypeError` for a
62 /// non-callable right operand has no case here; stays a `Result` to
63 /// match every other operator's shape.
64 /// <https://tc39.es/ecma262/#sec-instanceofoperator>
65 pub fn instanceof_(self, constructor: Constructor) -> Result<Any<A>, Any<A>> {
66 Ok(match constructor {
67 Constructor::Array => self.dispatch(InstanceOfArray),
68 }
69 .to_any())
70 }
71}