harn-vm 0.8.6

Async bytecode virtual machine for the Harn programming language
Documentation
use std::future::Future;
use std::pin::Pin;

use crate::value::{VmError, VmValue};
use crate::vm::iter::iter_from_value;

impl crate::vm::Vm {
    pub(in crate::vm) fn call_method<'a>(
        &'a mut self,
        obj: VmValue,
        method: &'a str,
        args: &'a [VmValue],
    ) -> Pin<Box<dyn Future<Output = Result<VmValue, VmError>> + 'a>> {
        Box::pin(async move {
            if method == "iter"
                && matches!(
                    &obj,
                    VmValue::List(_)
                        | VmValue::Set(_)
                        | VmValue::Dict(_)
                        | VmValue::String(_)
                        | VmValue::Generator(_)
                        | VmValue::Stream(_)
                        | VmValue::Channel(_)
                        | VmValue::Iter(_)
                )
            {
                return iter_from_value(obj);
            }

            match &obj {
                VmValue::String(s) => self.call_string_method(s, method, args),
                VmValue::List(items) => self.call_list_method(items, method, args).await,
                VmValue::Dict(map) => self.call_dict_method(map, method, args).await,
                VmValue::Set(items) => self.call_set_method(items, method, args).await,
                VmValue::Range(r) => self.call_range_method(&obj, r, method, args).await,
                VmValue::Int(_) | VmValue::Float(_) => self.call_number_method(&obj, method, args),
                VmValue::StructInstance { .. } => {
                    self.call_struct_instance_method(&obj, method, args).await
                }
                VmValue::Generator(gen) => self.call_generator_method(gen, method).await,
                VmValue::Stream(stream) => self.call_stream_method(stream, method).await,
                VmValue::Iter(handle) => self.call_iter_method(handle, method, args).await,
                other => Err(VmError::TypeError(format!(
                    "value of type {} has no method `{method}`",
                    other.type_name()
                ))),
            }
        })
    }
}