use std::sync::Arc;
use sim_kernel::{
Args, Callable, Class, ClassId, ClassRef, Cx, Object, ReadConstructor, ReadConstructorRef,
Result, ShapeRef, Symbol, TableRef, Value, id::CORE_CLASS_CLASS_ID,
};
use crate::OverrideTable;
pub fn construct_override_table(cx: &mut Cx, args: Vec<Value>) -> Result<Value> {
let table = OverrideTable::new(args)?;
cx.factory().opaque(Arc::new(table))
}
#[derive(Clone)]
pub(crate) struct OverrideTableClass {
id: ClassId,
}
impl OverrideTableClass {
pub(crate) fn new(id: ClassId) -> Self {
Self { id }
}
}
impl Object for OverrideTableClass {
fn display(&self, _cx: &mut Cx) -> Result<String> {
Ok("#<class OverrideTable>".to_owned())
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl sim_kernel::ObjectCompat for OverrideTableClass {
fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
if let Some(value) = cx
.registry()
.class_by_symbol(&Symbol::qualified("core", "Class"))
{
return Ok(value.clone());
}
cx.factory()
.class_stub(CORE_CLASS_CLASS_ID, Symbol::qualified("core", "Class"))
}
fn as_expr(&self, _cx: &mut Cx) -> Result<sim_kernel::Expr> {
Ok(sim_kernel::Expr::Symbol(Symbol::new("OverrideTable")))
}
fn as_callable(&self) -> Option<&dyn Callable> {
Some(self)
}
fn as_class(&self) -> Option<&dyn Class> {
Some(self)
}
}
impl Callable for OverrideTableClass {
fn call(&self, cx: &mut Cx, args: Args) -> Result<Value> {
construct_override_table(cx, args.into_vec())
}
}
impl Class for OverrideTableClass {
fn id(&self) -> ClassId {
self.id
}
fn symbol(&self) -> Symbol {
Symbol::new("OverrideTable")
}
fn constructor_shape(&self, cx: &mut Cx) -> Result<ShapeRef> {
cx.factory().nil()
}
fn instance_shape(&self, cx: &mut Cx) -> Result<ShapeRef> {
cx.factory().nil()
}
fn read_constructor(&self, cx: &mut Cx) -> Result<Option<ReadConstructorRef>> {
Ok(Some(
cx.factory()
.opaque(Arc::new(OverrideTableReadConstructor))?,
))
}
fn members(&self, cx: &mut Cx) -> Result<TableRef> {
cx.factory().table(Vec::new())
}
}
struct OverrideTableReadConstructor;
impl Object for OverrideTableReadConstructor {
fn display(&self, _cx: &mut Cx) -> Result<String> {
Ok("#<read-constructor OverrideTable>".to_owned())
}
fn as_any(&self) -> &dyn std::any::Any {
self
}
}
impl sim_kernel::ObjectCompat for OverrideTableReadConstructor {
fn class(&self, cx: &mut Cx) -> Result<ClassRef> {
if let Some(value) = cx
.registry()
.class_by_symbol(&Symbol::qualified("core", "Function"))
{
return Ok(value.clone());
}
cx.factory().class_stub(
sim_kernel::id::CORE_FUNCTION_CLASS_ID,
Symbol::qualified("core", "Function"),
)
}
fn as_read_constructor(&self) -> Option<&dyn ReadConstructor> {
Some(self)
}
}
impl ReadConstructor for OverrideTableReadConstructor {
fn symbol(&self) -> Symbol {
Symbol::new("OverrideTable")
}
fn args_shape(&self, cx: &mut Cx) -> Result<ShapeRef> {
cx.factory().nil()
}
fn construct_read(&self, cx: &mut Cx, args: Vec<Value>) -> Result<Value> {
construct_override_table(cx, args)
}
}