use crate::{ obj::{prelude::*, reserved::*}, vm::error::*, }; use once_cell::sync::Lazy; use shredder::Scan; use std::fmt::{self, Debug, Formatter}; pub type BoolRef = ObjRef; #[derive(Scan)] pub struct Bool { value: bool, vtable: Vtable, attrs: Attrs, } impl Bool { /// Gets the value of this boolean. pub fn value(&self) -> bool { self.value } } impl From for BoolRef { fn from(value: bool) -> Self { if value { BOOL_TRUE.clone() } else { BOOL_FALSE.clone() } } } impl_obj_readonly!(Bool); impl Debug for Bool { fn fmt(&self, fmt: &mut Formatter) -> fmt::Result { fmt.debug_struct("Bool").field("value", &self.value).finish() } } /// A true boolean value. /// /// This value should be the only instance of a "true" boolean. pub static BOOL_TRUE: Lazy = Lazy::new(|| self_referring_obj! { Bool { value: true, vtable: Default::default(), attrs: Default::default(), }, vtable: |obj_ref: ObjRef| vtable! { BOOL_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), BOOL_BOOL_FUN.clone()), } } ); /// A false boolean value. /// /// This value should be the only instance of a "false" boolean. pub static BOOL_FALSE: Lazy = Lazy::new(|| self_referring_obj! { Bool { value: false, vtable: Default::default(), attrs: Default::default(), }, vtable: |obj_ref: ObjRef| vtable! { BOOL_MEMBER_NAME.sym => Method::new_obj(obj_ref.clone(), BOOL_BOOL_FUN.clone()), } } ); //////////////////////////////////////////////////////////////////////////////// // Builtin Bool functions //////////////////////////////////////////////////////////////////////////////// /// Bool.__bool__(self) impl static BOOL_BOOL_FUN: Lazy = Lazy::new(|| { NativeFun::new_obj(1, |_callee, vm, args| { { read_obj_downcast!(let value: Option<&Bool> = &args[0]); value.ok_or_else(|| Error::ValueError { error: "expected Bool value".to_string(), })?; } // just push a copy of the "self" value vm.push(args[0].clone()); Ok(crate::vm::signal::Signal::Return) }) });