Skip to content

Commit

Permalink
use an IndexMap to stabilize the order of coprocessors in a Lang
Browse files Browse the repository at this point in the history
  • Loading branch information
arthurpaulino committed Sep 12, 2023
1 parent fc9156d commit 44d1f40
Showing 1 changed file with 58 additions and 5 deletions.
63 changes: 58 additions & 5 deletions src/eval/lang.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
use std::collections::HashMap;
use std::fmt::Debug;
use std::marker::PhantomData;

use indexmap::IndexMap;
use lurk_macros::Coproc;
use serde::{Deserialize, Serialize};

Expand All @@ -10,6 +10,7 @@ use crate::field::LurkField;
use crate::ptr::Ptr;
use crate::store::Store;
use crate::symbol::Symbol;
use crate::tag::ExprTag;
use crate::z_ptr::ZExprPtr;

use crate::{self as lurk, lurk_sym_ptr};
Expand Down Expand Up @@ -76,10 +77,35 @@ pub enum Coproc<F: LurkField> {
/// exact set of coprocessors to be allowed in the `Lang` struct.
///
// TODO: Define a trait for the Hash and parameterize on that also.
#[derive(Debug, Default, Clone, Deserialize, Serialize)]
#[derive(Debug, Default, Clone)]
pub struct Lang<F: LurkField, C: Coprocessor<F>> {
// A HashMap that stores coprocessors with their associated `Sym` keys.
coprocessors: HashMap<Symbol, (C, ZExprPtr<F>)>,
/// An IndexMap that stores coprocessors with their associated `Sym` keys
coprocessors: IndexMap<Symbol, (C, ZExprPtr<F>)>,
}

impl<F: LurkField + Serialize, C: Coprocessor<F> + Serialize> Serialize for Lang<F, C> {
fn serialize<S>(&self, serializer: S) -> Result<S::Ok, S::Error>
where
S: serde::Serializer,
{
let vec = self.coprocessors.clone().into_iter().collect::<Vec<_>>();
vec.serialize(serializer)
}
}

impl<'a, F: LurkField + Deserialize<'a>, C: Coprocessor<F> + Deserialize<'a>> Deserialize<'a>
for Lang<F, C>
{
fn deserialize<D>(deserializer: D) -> Result<Self, D::Error>
where
D: serde::Deserializer<'a>,
{
use crate::z_ptr::ZPtr;
let vec: Vec<(Symbol, (C, ZPtr<ExprTag, F>))> = Vec::deserialize(deserializer)?;
Ok(Lang {
coprocessors: IndexMap::from_iter(vec),
})
}
}

impl<F: LurkField, C: Coprocessor<F>> Lang<F, C> {
Expand Down Expand Up @@ -127,6 +153,13 @@ impl<F: LurkField, C: Coprocessor<F>> Lang<F, C> {
self.coprocessors.insert(name, (cproc.into(), z_ptr));
}

pub fn add_coprocessor_lem<T: Into<C>, S: Into<Symbol>>(&mut self, name: S, cproc: T) {
let name = name.into();
// TODO: eliminate this unecessary piece of data
let z_ptr = lurk::z_ptr::ZPtr(ExprTag::Nil, F::ZERO);
self.coprocessors.insert(name, (cproc.into(), z_ptr));
}

pub fn add_binding<B: Into<Binding<F, C>>>(&mut self, binding: B, store: &mut Store<F>) {
let Binding { name, coproc, _p } = binding.into();
let ptr = store.intern_symbol(&name);
Expand All @@ -135,7 +168,15 @@ impl<F: LurkField, C: Coprocessor<F>> Lang<F, C> {
self.coprocessors.insert(name, (coproc, z_ptr));
}

pub fn coprocessors(&self) -> &HashMap<Symbol, (C, ZExprPtr<F>)> {
pub fn add_binding_lem<B: Into<Binding<F, C>>>(&mut self, binding: B) {
let Binding { name, coproc, _p } = binding.into();
// TODO: eliminate this unecessary piece of data
let z_ptr = lurk::z_ptr::ZPtr(ExprTag::Nil, F::ZERO);
self.coprocessors.insert(name, (coproc, z_ptr));
}

#[inline]
pub fn coprocessors(&self) -> &IndexMap<Symbol, (C, ZExprPtr<F>)> {
&self.coprocessors
}

Expand All @@ -153,10 +194,22 @@ impl<F: LurkField, C: Coprocessor<F>> Lang<F, C> {
maybe_sym.and_then(|sym| self.coprocessors.get(&sym))
}

#[inline]
pub fn lookup_by_sym(&self, sym: &Symbol) -> Option<&C> {
self.coprocessors.get(sym).map(|(c, _)| c)
}

#[inline]
pub fn get_coprocessor_index(&self, sym: &Symbol) -> Option<usize> {
self.coprocessors.get_index_of(sym)
}

#[inline]
pub fn has_coprocessors(&self) -> bool {
!self.coprocessors.is_empty()
}

#[inline]
pub fn is_default(&self) -> bool {
!self.has_coprocessors()
}
Expand Down

0 comments on commit 44d1f40

Please sign in to comment.