forked from Orchid/orchid
bkp
This commit is contained in:
@@ -22,4 +22,3 @@ ordered-float = "4.2.0"
|
||||
paste = "1.0.15"
|
||||
substack = "1.1.0"
|
||||
trait-set = "0.3.0"
|
||||
typeid = "1.0.0"
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
use std::any::{type_name, Any};
|
||||
use std::any::{type_name, Any, TypeId};
|
||||
use std::io::{Read, Write};
|
||||
use std::ops::Deref;
|
||||
|
||||
@@ -9,7 +9,6 @@ use orchid_api_traits::{Coding, Decode, Request};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::reqnot::Requester;
|
||||
use trait_set::trait_set;
|
||||
use typeid::ConstTypeId;
|
||||
|
||||
use crate::error::ProjectError;
|
||||
use crate::expr::{ExprHandle, GenExpr};
|
||||
@@ -33,19 +32,22 @@ impl<A: Atomic> AtomCard for A {
|
||||
|
||||
pub trait AtomicFeatures: Atomic {
|
||||
fn factory(self) -> AtomFactory;
|
||||
fn info() -> &'static AtomInfo;
|
||||
type Info: AtomDynfo;
|
||||
const INFO: &'static Self::Info;
|
||||
}
|
||||
pub trait AtomicFeaturesImpl<Variant: AtomicVariant> {
|
||||
fn _factory(self) -> AtomFactory;
|
||||
fn _info() -> &'static AtomInfo;
|
||||
type _Info: AtomDynfo;
|
||||
const _INFO: &'static Self::_Info;
|
||||
}
|
||||
impl<A: Atomic + AtomicFeaturesImpl<A::Variant>> AtomicFeatures for A {
|
||||
fn factory(self) -> AtomFactory { self._factory() }
|
||||
fn info() -> &'static AtomInfo { Self::_info() }
|
||||
type Info = <Self as AtomicFeaturesImpl<A::Variant>>::_Info;
|
||||
const INFO: &'static Self::Info = Self::_INFO;
|
||||
}
|
||||
|
||||
pub fn get_info<A: AtomCard>(sys: &(impl DynSystemCard + ?Sized)) -> (u64, &AtomInfo) {
|
||||
atom_info_for(sys, ConstTypeId::of::<A>()).unwrap_or_else(|| {
|
||||
pub fn get_info<A: AtomCard>(sys: &(impl DynSystemCard + ?Sized)) -> (u64, &'static dyn AtomDynfo) {
|
||||
atom_info_for(sys, TypeId::of::<A>()).unwrap_or_else(|| {
|
||||
panic!("Atom {} not associated with system {}", type_name::<A>(), sys.name())
|
||||
})
|
||||
}
|
||||
@@ -75,14 +77,14 @@ impl<A: AtomCard> Deref for TypAtom<A> {
|
||||
fn deref(&self) -> &Self::Target { &self.value }
|
||||
}
|
||||
|
||||
pub struct AtomInfo {
|
||||
pub tid: ConstTypeId,
|
||||
pub decode: fn(&[u8]) -> Box<dyn Any>,
|
||||
pub call: fn(&[u8], SysCtx, ExprTicket) -> GenExpr,
|
||||
pub call_ref: fn(&[u8], SysCtx, ExprTicket) -> GenExpr,
|
||||
pub same: fn(&[u8], SysCtx, &[u8]) -> bool,
|
||||
pub handle_req: fn(&[u8], SysCtx, &mut dyn Read, &mut dyn Write),
|
||||
pub drop: fn(&[u8], SysCtx),
|
||||
pub trait AtomDynfo: Send + Sync + 'static {
|
||||
fn tid(&self) -> TypeId;
|
||||
fn decode(&self, data: &[u8]) -> Box<dyn Any>;
|
||||
fn call(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr;
|
||||
fn call_ref(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr;
|
||||
fn same(&self, buf: &[u8], ctx: SysCtx, buf2: &[u8]) -> bool;
|
||||
fn handle_req(&self, buf: &[u8], ctx: SysCtx, req: &mut dyn Read, rep: &mut dyn Write);
|
||||
fn drop(&self, buf: &[u8], ctx: SysCtx);
|
||||
}
|
||||
|
||||
trait_set! {
|
||||
@@ -102,4 +104,4 @@ impl Clone for AtomFactory {
|
||||
pub struct ErrorNotCallable;
|
||||
impl ProjectError for ErrorNotCallable {
|
||||
const DESCRIPTION: &'static str = "This atom is not callable";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,11 +1,19 @@
|
||||
use std::{any::{type_name, Any}, borrow::Cow, io::{Read, Write}, num::NonZeroU64};
|
||||
use std::any::{type_name, Any, TypeId};
|
||||
use std::borrow::Cow;
|
||||
use std::io::{Read, Write};
|
||||
use std::marker::PhantomData;
|
||||
use std::num::NonZeroU64;
|
||||
|
||||
use orchid_api::{atom::LocalAtom, expr::ExprTicket};
|
||||
use orchid_api::atom::LocalAtom;
|
||||
use orchid_api::expr::ExprTicket;
|
||||
use orchid_api_traits::{Decode, Encode};
|
||||
use orchid_base::id_store::{IdRecord, IdStore};
|
||||
use typeid::ConstTypeId;
|
||||
|
||||
use crate::{atom::{AtomCard, AtomFactory, AtomInfo, Atomic, AtomicFeaturesImpl, AtomicVariant, ErrorNotCallable}, expr::{bot, ExprHandle, GenExpr}, system::{atom_info_for, SysCtx}};
|
||||
use crate::atom::{
|
||||
AtomCard, AtomDynfo, AtomFactory, Atomic, AtomicFeaturesImpl, AtomicVariant, ErrorNotCallable,
|
||||
};
|
||||
use crate::expr::{bot, ExprHandle, GenExpr};
|
||||
use crate::system::{atom_info_for, SysCtx};
|
||||
|
||||
pub struct OwnedVariant;
|
||||
impl AtomicVariant for OwnedVariant {}
|
||||
@@ -19,26 +27,37 @@ impl<A: OwnedAtom + Atomic<Variant = OwnedVariant>> AtomicFeaturesImpl<OwnedVari
|
||||
LocalAtom { drop: true, data }
|
||||
})
|
||||
}
|
||||
fn _info() -> &'static AtomInfo {
|
||||
fn with_atom<U>(mut b: &[u8], f: impl FnOnce(IdRecord<'_, Box<dyn DynOwnedAtom>>) -> U) -> U {
|
||||
f(OBJ_STORE.get(NonZeroU64::decode(&mut b)).expect("Received invalid atom ID"))
|
||||
}
|
||||
&const {
|
||||
AtomInfo {
|
||||
tid: ConstTypeId::of::<Self>(),
|
||||
decode: |mut b| Box::new(<Self as Atomic>::Data::decode(&mut b)),
|
||||
call: |b, ctx, arg| with_atom(b, |a| a.remove().dyn_call(ctx, arg)),
|
||||
call_ref: |b, ctx, arg| with_atom(b, |a| a.dyn_call_ref(ctx, arg)),
|
||||
same: |b1, ctx, b2| with_atom(b1, |a1| with_atom(b2, |a2| a1.dyn_same(ctx, &**a2))),
|
||||
handle_req: |b, ctx, req, rep| with_atom(b, |a| a.dyn_handle_req(ctx, req, rep)),
|
||||
drop: |b, ctx| with_atom(b, |a| a.remove().dyn_free(ctx)),
|
||||
}
|
||||
}
|
||||
type _Info = OwnedAtomDynfo<A>;
|
||||
const _INFO: &'static Self::_Info = &OwnedAtomDynfo(PhantomData);
|
||||
}
|
||||
|
||||
fn with_atom<U>(mut b: &[u8], f: impl FnOnce(IdRecord<'_, Box<dyn DynOwnedAtom>>) -> U) -> U {
|
||||
f(OBJ_STORE.get(NonZeroU64::decode(&mut b)).expect("Received invalid atom ID"))
|
||||
}
|
||||
|
||||
pub struct OwnedAtomDynfo<T: OwnedAtom>(PhantomData<T>);
|
||||
impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
|
||||
fn tid(&self) -> TypeId { TypeId::of::<T>() }
|
||||
fn decode(&self, data: &[u8]) -> Box<dyn Any> {
|
||||
Box::new(<T as AtomCard>::Data::decode(&mut &data[..]))
|
||||
}
|
||||
fn call(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr {
|
||||
with_atom(buf, |a| a.remove().dyn_call(ctx, arg))
|
||||
}
|
||||
fn call_ref(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr {
|
||||
with_atom(buf, |a| a.dyn_call_ref(ctx, arg))
|
||||
}
|
||||
fn same(&self, buf: &[u8], ctx: SysCtx, buf2: &[u8]) -> bool {
|
||||
with_atom(buf, |a1| with_atom(buf2, |a2| a1.dyn_same(ctx, &**a2)))
|
||||
}
|
||||
fn handle_req(&self, buf: &[u8], ctx: SysCtx, req: &mut dyn Read, rep: &mut dyn Write) {
|
||||
with_atom(buf, |a| a.dyn_handle_req(ctx, req, rep))
|
||||
}
|
||||
fn drop(&self, buf: &[u8], ctx: SysCtx) { with_atom(buf, |a| a.remove().dyn_free(ctx)) }
|
||||
}
|
||||
|
||||
/// Atoms that have a [Drop]
|
||||
pub trait OwnedAtom: AtomCard + Send + Sync + Any + Clone + 'static {
|
||||
pub trait OwnedAtom: Atomic<Variant = OwnedVariant> + Send + Sync + Any + Clone + 'static {
|
||||
fn val(&self) -> Cow<'_, Self::Data>;
|
||||
#[allow(unused_variables)]
|
||||
fn call_ref(&self, arg: ExprHandle) -> GenExpr { bot(ErrorNotCallable) }
|
||||
@@ -61,7 +80,7 @@ pub trait OwnedAtom: AtomCard + Send + Sync + Any + Clone + 'static {
|
||||
fn free(self, ctx: SysCtx) {}
|
||||
}
|
||||
pub trait DynOwnedAtom: Send + Sync + 'static {
|
||||
fn atom_tid(&self) -> ConstTypeId;
|
||||
fn atom_tid(&self) -> TypeId;
|
||||
fn as_any_ref(&self) -> &dyn Any;
|
||||
fn encode(&self, buffer: &mut dyn Write);
|
||||
fn dyn_call_ref(&self, ctx: SysCtx, arg: ExprTicket) -> GenExpr;
|
||||
@@ -71,7 +90,7 @@ pub trait DynOwnedAtom: Send + Sync + 'static {
|
||||
fn dyn_free(self: Box<Self>, ctx: SysCtx);
|
||||
}
|
||||
impl<T: OwnedAtom> DynOwnedAtom for T {
|
||||
fn atom_tid(&self) -> ConstTypeId { ConstTypeId::of::<T>() }
|
||||
fn atom_tid(&self) -> TypeId { TypeId::of::<T>() }
|
||||
fn as_any_ref(&self) -> &dyn Any { self }
|
||||
fn encode(&self, buffer: &mut dyn Write) { self.val().as_ref().encode(buffer) }
|
||||
fn dyn_call_ref(&self, ctx: SysCtx, arg: ExprTicket) -> GenExpr {
|
||||
@@ -81,7 +100,7 @@ impl<T: OwnedAtom> DynOwnedAtom for T {
|
||||
self.call(ExprHandle::from_args(ctx, arg))
|
||||
}
|
||||
fn dyn_same(&self, ctx: SysCtx, other: &dyn DynOwnedAtom) -> bool {
|
||||
if ConstTypeId::of::<Self>() != other.as_any_ref().type_id() {
|
||||
if TypeId::of::<Self>() != other.as_any_ref().type_id() {
|
||||
return false;
|
||||
}
|
||||
let other_self = other.as_any_ref().downcast_ref().expect("The type_ids are the same");
|
||||
@@ -93,4 +112,4 @@ impl<T: OwnedAtom> DynOwnedAtom for T {
|
||||
fn dyn_free(self: Box<Self>, ctx: SysCtx) { self.free(ctx) }
|
||||
}
|
||||
|
||||
pub(crate) static OBJ_STORE: IdStore<Box<dyn DynOwnedAtom>> = IdStore::new();
|
||||
pub(crate) static OBJ_STORE: IdStore<Box<dyn DynOwnedAtom>> = IdStore::new();
|
||||
|
||||
@@ -1,10 +1,18 @@
|
||||
use std::{any::type_name, fmt, io::Write};
|
||||
use std::any::{type_name, Any, TypeId};
|
||||
use std::fmt;
|
||||
use std::io::Write;
|
||||
use std::marker::PhantomData;
|
||||
|
||||
use orchid_api::atom::LocalAtom;
|
||||
use orchid_api::expr::ExprTicket;
|
||||
use orchid_api_traits::{Coding, Decode, Encode};
|
||||
use typeid::ConstTypeId;
|
||||
|
||||
use crate::{atom::{get_info, AtomCard, AtomFactory, AtomInfo, Atomic, AtomicFeaturesImpl, AtomicVariant, ErrorNotCallable}, expr::{bot, ExprHandle, GenExpr}, system::SysCtx};
|
||||
use crate::atom::{
|
||||
get_info, AtomCard, AtomDynfo, AtomFactory, Atomic, AtomicFeaturesImpl, AtomicVariant,
|
||||
ErrorNotCallable,
|
||||
};
|
||||
use crate::expr::{bot, ExprHandle, GenExpr};
|
||||
use crate::system::SysCtx;
|
||||
|
||||
pub struct ThinVariant;
|
||||
impl AtomicVariant for ThinVariant {}
|
||||
@@ -16,22 +24,32 @@ impl<A: ThinAtom + Atomic<Variant = ThinVariant>> AtomicFeaturesImpl<ThinVariant
|
||||
LocalAtom { drop: false, data: buf }
|
||||
})
|
||||
}
|
||||
fn _info() -> &'static AtomInfo {
|
||||
&const {
|
||||
AtomInfo {
|
||||
tid: ConstTypeId::of::<Self>(),
|
||||
decode: |mut b| Box::new(Self::decode(&mut b)),
|
||||
call: |mut b, ctx, extk| Self::decode(&mut b).call(ExprHandle::from_args(ctx, extk)),
|
||||
call_ref: |mut b, ctx, extk| Self::decode(&mut b).call(ExprHandle::from_args(ctx, extk)),
|
||||
handle_req: |mut b, ctx, req, rep| Self::decode(&mut b).handle_req(ctx, Decode::decode(req), rep),
|
||||
same: |mut b1, ctx, mut b2| Self::decode(&mut b1).same(ctx, &Self::decode(&mut b2)),
|
||||
drop: |mut b1, _| eprintln!("Received drop signal for non-drop atom {:?}", Self::decode(&mut b1)),
|
||||
}
|
||||
}
|
||||
type _Info = ThinAtomDynfo<Self>;
|
||||
const _INFO: &'static Self::_Info = &ThinAtomDynfo(PhantomData);
|
||||
}
|
||||
|
||||
pub struct ThinAtomDynfo<T: ThinAtom>(PhantomData<T>);
|
||||
impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
fn tid(&self) -> TypeId { TypeId::of::<T>() }
|
||||
fn decode(&self, mut data: &[u8]) -> Box<dyn Any> { Box::new(T::decode(&mut data)) }
|
||||
fn call(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr {
|
||||
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
|
||||
}
|
||||
fn call_ref(&self, buf: &[u8], ctx: SysCtx, arg: ExprTicket) -> GenExpr {
|
||||
T::decode(&mut &buf[..]).call(ExprHandle::from_args(ctx, arg))
|
||||
}
|
||||
fn handle_req(&self, buf: &[u8], ctx: SysCtx, req: &mut dyn std::io::Read, rep: &mut dyn Write) {
|
||||
T::decode(&mut &buf[..]).handle_req(ctx, Decode::decode(req), rep)
|
||||
}
|
||||
fn same(&self, buf: &[u8], ctx: SysCtx, buf2: &[u8]) -> bool {
|
||||
T::decode(&mut &buf[..]).same(ctx, &T::decode(&mut &buf2[..]))
|
||||
}
|
||||
fn drop(&self, buf: &[u8], _ctx: SysCtx) {
|
||||
eprintln!("Received drop signal for non-drop atom {:?}", T::decode(&mut &buf[..]))
|
||||
}
|
||||
}
|
||||
|
||||
pub trait ThinAtom: AtomCard<Data = Self> + Coding + fmt::Debug {
|
||||
pub trait ThinAtom: AtomCard<Data = Self> + Coding + fmt::Debug + Send + Sync + 'static {
|
||||
#[allow(unused_variables)]
|
||||
fn call(&self, arg: ExprHandle) -> GenExpr { bot(ErrorNotCallable) }
|
||||
#[allow(unused_variables)]
|
||||
|
||||
@@ -1,6 +1,9 @@
|
||||
use orchid_base::location::Pos;
|
||||
|
||||
use crate::{atom::{AtomicFeatures, TypAtom}, error::{ProjectError, ProjectResult}, expr::{atom, bot_obj, ExprHandle, GenExpr, OwnedExpr}, system::downcast_atom};
|
||||
use crate::atom::{AtomicFeatures, TypAtom};
|
||||
use crate::error::{ProjectError, ProjectResult};
|
||||
use crate::expr::{atom, bot_obj, ExprHandle, GenExpr, OwnedExpr};
|
||||
use crate::system::downcast_atom;
|
||||
|
||||
pub trait TryFromExpr: Sized {
|
||||
fn try_from_expr(expr: ExprHandle) -> ProjectResult<Self>;
|
||||
@@ -25,14 +28,14 @@ impl ProjectError for ErrorNotAtom {
|
||||
pub struct ErrorUnexpectedType(Pos);
|
||||
impl ProjectError for ErrorUnexpectedType {
|
||||
const DESCRIPTION: &'static str = "Type error";
|
||||
fn one_position(&self) -> Pos {
|
||||
self.0.clone()
|
||||
}
|
||||
fn one_position(&self) -> Pos { self.0.clone() }
|
||||
}
|
||||
|
||||
impl<A: AtomicFeatures> TryFromExpr for TypAtom<A> {
|
||||
fn try_from_expr(expr: ExprHandle) -> ProjectResult<Self> {
|
||||
OwnedExpr::new(expr).foreign_atom().map_err(|ex| ErrorNotAtom(ex.pos.clone()).pack())
|
||||
OwnedExpr::new(expr)
|
||||
.foreign_atom()
|
||||
.map_err(|ex| ErrorNotAtom(ex.pos.clone()).pack())
|
||||
.and_then(|f| downcast_atom(f).map_err(|f| ErrorUnexpectedType(f.pos).pack()))
|
||||
}
|
||||
}
|
||||
@@ -43,13 +46,13 @@ pub trait ToExpr {
|
||||
|
||||
impl<T: ToExpr> ToExpr for ProjectResult<T> {
|
||||
fn to_expr(self) -> GenExpr {
|
||||
match self {
|
||||
Err(e) => bot_obj(e),
|
||||
Ok(t) => t.to_expr(),
|
||||
}
|
||||
match self {
|
||||
Err(e) => bot_obj(e),
|
||||
Ok(t) => t.to_expr(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<A: AtomicFeatures> ToExpr for A {
|
||||
fn to_expr(self) -> GenExpr { atom(self) }
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ use orchid_base::interner::{deintern, init_replica, sweep_replica};
|
||||
use orchid_base::name::PathSlice;
|
||||
use orchid_base::reqnot::{ReqNot, Requester};
|
||||
|
||||
use crate::atom::AtomInfo;
|
||||
use crate::atom::AtomDynfo;
|
||||
use crate::error::{err_or_ref_to_api, unpack_err};
|
||||
use crate::fs::VirtFS;
|
||||
use crate::lexer::LexContext;
|
||||
@@ -48,7 +48,7 @@ pub struct SystemRecord {
|
||||
pub fn with_atom_record<T>(
|
||||
systems: &Mutex<HashMap<SysId, SystemRecord>>,
|
||||
atom: &Atom,
|
||||
cb: impl FnOnce(&AtomInfo, CtedObj, &[u8]) -> T,
|
||||
cb: impl FnOnce(&'static dyn AtomDynfo, CtedObj, &[u8]) -> T,
|
||||
) -> T {
|
||||
let mut data = &atom.data[..];
|
||||
let systems_g = systems.lock().unwrap();
|
||||
@@ -77,7 +77,7 @@ pub fn extension_main(data: ExtensionData) {
|
||||
mem::drop(systems.lock().unwrap().remove(&sys_id)),
|
||||
HostExtNotif::AtomDrop(AtomDrop(atom)) => {
|
||||
with_atom_record(&systems, &atom, |rec, cted, data| {
|
||||
(rec.drop)(data, SysCtx{ reqnot, id: atom.owner, cted })
|
||||
rec.drop(data, SysCtx{ reqnot, id: atom.owner, cted })
|
||||
})
|
||||
}
|
||||
}),
|
||||
|
||||
@@ -10,7 +10,7 @@ use orchid_api::error::{GetErrorDetails, ProjErr, ProjErrId, ProjErrOrRef};
|
||||
use orchid_api::proto::ExtMsgSet;
|
||||
use orchid_base::boxed_iter::{box_once, BoxedIter};
|
||||
use orchid_base::clone;
|
||||
use orchid_base::error::{ErrorDetails, ErrorPosition};
|
||||
use orchid_base::error::{ErrorPosition, OwnedError};
|
||||
use orchid_base::interner::{deintern, intern};
|
||||
use orchid_base::location::{GetSrc, Pos};
|
||||
use orchid_base::reqnot::{ReqNot, Requester};
|
||||
@@ -290,12 +290,16 @@ pub(crate) fn err_or_ref_to_api(err: ProjectErrorObj) -> ProjErrOrRef {
|
||||
}
|
||||
|
||||
pub fn err_from_api(err: &ProjErr, reqnot: ReqNot<ExtMsgSet>) -> ProjectErrorObj {
|
||||
Arc::new(RelayedError { id: None, reqnot, details: ErrorDetails::from_api(err).into() })
|
||||
Arc::new(RelayedError { id: None, reqnot, details: OwnedError::from_api(err).into() })
|
||||
}
|
||||
|
||||
pub(crate) fn err_from_api_or_ref(err: &ProjErrOrRef, reqnot: ReqNot<ExtMsgSet>) -> ProjectErrorObj {
|
||||
pub(crate) fn err_from_api_or_ref(
|
||||
err: &ProjErrOrRef,
|
||||
reqnot: ReqNot<ExtMsgSet>,
|
||||
) -> ProjectErrorObj {
|
||||
match err {
|
||||
ProjErrOrRef::Known(id) => Arc::new(RelayedError { id: Some(*id), reqnot, details: OnceLock::default() }),
|
||||
ProjErrOrRef::Known(id) =>
|
||||
Arc::new(RelayedError { id: Some(*id), reqnot, details: OnceLock::default() }),
|
||||
ProjErrOrRef::New(err) => err_from_api(err, reqnot),
|
||||
}
|
||||
}
|
||||
@@ -303,18 +307,18 @@ pub(crate) fn err_from_api_or_ref(err: &ProjErrOrRef, reqnot: ReqNot<ExtMsgSet>)
|
||||
struct RelayedError {
|
||||
pub id: Option<ProjErrId>,
|
||||
pub reqnot: ReqNot<ExtMsgSet>,
|
||||
pub details: OnceLock<ErrorDetails>,
|
||||
pub details: OnceLock<OwnedError>,
|
||||
}
|
||||
impl RelayedError {
|
||||
fn details(&self) -> &ErrorDetails {
|
||||
fn details(&self) -> &OwnedError {
|
||||
let Self { id, reqnot, details: data } = self;
|
||||
data.get_or_init(clone!(reqnot; move || {
|
||||
let id = id.expect("Either data or ID must be initialized");
|
||||
let projerr = reqnot.request(GetErrorDetails(id));
|
||||
ErrorDetails {
|
||||
OwnedError {
|
||||
description: deintern(projerr.description),
|
||||
message: projerr.message,
|
||||
locations: projerr.locations.iter().map(ErrorPosition::from_api).collect_vec(),
|
||||
positions: projerr.locations.iter().map(ErrorPosition::from_api).collect_vec(),
|
||||
}
|
||||
}))
|
||||
}
|
||||
@@ -325,6 +329,6 @@ impl DynProjectError for RelayedError {
|
||||
fn as_any_ref(&self) -> &dyn std::any::Any { self }
|
||||
fn into_packed(self: Arc<Self>) -> ProjectErrorObj { self }
|
||||
fn positions(&self) -> BoxedIter<'_, ErrorPosition> {
|
||||
Box::new(self.details().locations.iter().cloned())
|
||||
Box::new(self.details().positions.iter().cloned())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,9 +6,9 @@ use trait_set::trait_set;
|
||||
|
||||
use crate::atom::Atomic;
|
||||
use crate::atom_owned::{OwnedAtom, OwnedVariant};
|
||||
use crate::conv::{ToExpr, TryFromExpr};
|
||||
use crate::expr::{ExprHandle, GenExpr};
|
||||
use crate::system::SysCtx;
|
||||
use crate::conv::{ToExpr, TryFromExpr};
|
||||
|
||||
trait_set! {
|
||||
trait FunCB = FnOnce(ExprHandle) -> GenExpr + DynClone + Send + Sync + 'static;
|
||||
@@ -16,7 +16,9 @@ trait_set! {
|
||||
|
||||
pub struct Fun(Box<dyn FunCB>);
|
||||
impl Fun {
|
||||
pub fn new<I: TryFromExpr, O: ToExpr>(f: impl FnOnce(I) -> O + Clone + Send + Sync + 'static) -> Self {
|
||||
pub fn new<I: TryFromExpr, O: ToExpr>(
|
||||
f: impl FnOnce(I) -> O + Clone + Send + Sync + 'static,
|
||||
) -> Self {
|
||||
Self(Box::new(|eh| I::try_from_expr(eh).map(f).to_expr()))
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ use orchid_base::reqnot::{ReqNot, Requester};
|
||||
use crate::error::{
|
||||
err_from_api_or_ref, err_or_ref_to_api, pack_err, unpack_err, ProjectErrorObj, ProjectResult,
|
||||
};
|
||||
use crate::tree::{GenTok, GenTokTree};
|
||||
use crate::tree::{OwnedTok, OwnedTokTree};
|
||||
|
||||
pub struct LexContext<'a> {
|
||||
pub text: &'a Tok<String>,
|
||||
@@ -20,13 +20,13 @@ pub struct LexContext<'a> {
|
||||
pub reqnot: ReqNot<ExtMsgSet>,
|
||||
}
|
||||
impl<'a> LexContext<'a> {
|
||||
pub fn recurse(&self, tail: &'a str) -> ProjectResult<(&'a str, GenTokTree)> {
|
||||
pub fn recurse(&self, tail: &'a str) -> ProjectResult<(&'a str, OwnedTokTree)> {
|
||||
let start = self.pos(tail);
|
||||
self
|
||||
.reqnot
|
||||
.request(SubLex { pos: start, id: self.id })
|
||||
.map_err(|e| pack_err(e.iter().map(|e| err_from_api_or_ref(e, self.reqnot.clone()))))
|
||||
.map(|lx| (&self.text[lx.pos as usize..], GenTok::Slot(lx.ticket).at(start..lx.pos)))
|
||||
.map(|lx| (&self.text[lx.pos as usize..], OwnedTok::Slot(lx.ticket).at(start..lx.pos)))
|
||||
}
|
||||
|
||||
pub fn pos(&self, tail: &'a str) -> u32 { (self.text.len() - tail.len()) as u32 }
|
||||
@@ -47,7 +47,7 @@ pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
fn lex<'a>(
|
||||
tail: &'a str,
|
||||
ctx: &'a LexContext<'a>,
|
||||
) -> Option<ProjectResult<(&'a str, GenTokTree)>>;
|
||||
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>>;
|
||||
}
|
||||
|
||||
pub trait DynLexer: Send + Sync + 'static {
|
||||
@@ -56,7 +56,7 @@ pub trait DynLexer: Send + Sync + 'static {
|
||||
&self,
|
||||
tail: &'a str,
|
||||
ctx: &'a LexContext<'a>,
|
||||
) -> Option<ProjectResult<(&'a str, GenTokTree)>>;
|
||||
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>>;
|
||||
}
|
||||
|
||||
impl<T: Lexer> DynLexer for T {
|
||||
@@ -65,7 +65,7 @@ impl<T: Lexer> DynLexer for T {
|
||||
&self,
|
||||
tail: &'a str,
|
||||
ctx: &'a LexContext<'a>,
|
||||
) -> Option<ProjectResult<(&'a str, GenTokTree)>> {
|
||||
) -> Option<ProjectResult<(&'a str, OwnedTokTree)>> {
|
||||
T::lex(tail, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
pub mod atom;
|
||||
pub mod atom_owned;
|
||||
pub mod atom_thin;
|
||||
pub mod conv;
|
||||
pub mod entrypoint;
|
||||
pub mod error;
|
||||
pub mod expr;
|
||||
@@ -10,6 +13,3 @@ pub mod other_system;
|
||||
pub mod system;
|
||||
pub mod system_ctor;
|
||||
pub mod tree;
|
||||
pub mod conv;
|
||||
pub mod atom_thin;
|
||||
pub mod atom_owned;
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
use orchid_api_traits::Decode;
|
||||
use std::any::TypeId;
|
||||
|
||||
use orchid_api::proto::ExtMsgSet;
|
||||
use orchid_api::system::SysId;
|
||||
use orchid_api_traits::Decode;
|
||||
use orchid_base::reqnot::ReqNot;
|
||||
use typeid::ConstTypeId;
|
||||
|
||||
use crate::atom::{get_info, AtomCard, AtomInfo, AtomicFeatures, ForeignAtom, TypAtom};
|
||||
use crate::atom::{get_info, AtomCard, AtomDynfo, AtomicFeatures, ForeignAtom, TypAtom};
|
||||
use crate::fs::DeclFs;
|
||||
use crate::fun::Fun;
|
||||
use crate::lexer::LexerObj;
|
||||
@@ -15,44 +15,45 @@ use crate::tree::GenTree;
|
||||
/// System as consumed by foreign code
|
||||
pub trait SystemCard: Default + Send + Sync + 'static {
|
||||
type Ctor: SystemCtor;
|
||||
const ATOM_DEFS: &'static [Option<fn() -> &'static AtomInfo>];
|
||||
const ATOM_DEFS: &'static [Option<&'static dyn AtomDynfo>];
|
||||
}
|
||||
|
||||
pub trait DynSystemCard: Send + Sync + 'static {
|
||||
fn name(&self) -> &'static str;
|
||||
/// Atoms explicitly defined by the system card. Do not rely on this for
|
||||
/// querying atoms as it doesn't include the general atom types
|
||||
fn atoms(&self) -> &'static [Option<fn() -> &'static AtomInfo>];
|
||||
fn atoms(&self) -> &'static [Option<&'static dyn AtomDynfo>];
|
||||
}
|
||||
|
||||
/// Atoms supported by this package which may appear in all extensions.
|
||||
/// The indices of these are bitwise negated, such that the MSB of an atom index
|
||||
/// marks whether it belongs to this package (0) or the importer (1)
|
||||
fn general_atoms() -> &'static [Option<fn () -> &'static AtomInfo>] {
|
||||
&[Some(Fun::info)]
|
||||
}
|
||||
fn general_atoms() -> &'static [Option<&'static dyn AtomDynfo>] { &[Some(Fun::INFO)] }
|
||||
|
||||
pub fn atom_info_for(
|
||||
sys: &(impl DynSystemCard + ?Sized),
|
||||
tid: ConstTypeId,
|
||||
) -> Option<(u64, &AtomInfo)> {
|
||||
tid: TypeId,
|
||||
) -> Option<(u64, &'static dyn AtomDynfo)> {
|
||||
(sys.atoms().iter().enumerate().map(|(i, o)| (i as u64, o)))
|
||||
.chain(general_atoms().iter().enumerate().map(|(i, o)| (!(i as u64), o)))
|
||||
.filter_map(|(i, o)| o.as_ref().map(|a| (i, a())))
|
||||
.find(|ent| ent.1.tid == tid)
|
||||
.filter_map(|(i, o)| o.as_ref().map(|a| (i, *a)))
|
||||
.find(|ent| ent.1.tid() == tid)
|
||||
}
|
||||
|
||||
pub fn atom_by_idx(sys: &(impl DynSystemCard + ?Sized), tid: u64) -> Option<&'static AtomInfo> {
|
||||
pub fn atom_by_idx(
|
||||
sys: &(impl DynSystemCard + ?Sized),
|
||||
tid: u64,
|
||||
) -> Option<&'static dyn AtomDynfo> {
|
||||
if (tid >> (u64::BITS - 1)) & 1 == 1 {
|
||||
general_atoms()[!tid as usize].map(|f| f())
|
||||
general_atoms()[!tid as usize]
|
||||
} else {
|
||||
sys.atoms()[tid as usize].map(|f| f())
|
||||
sys.atoms()[tid as usize]
|
||||
}
|
||||
}
|
||||
|
||||
impl<T: SystemCard> DynSystemCard for T {
|
||||
fn name(&self) -> &'static str { T::Ctor::NAME }
|
||||
fn atoms(&self) -> &'static [Option<fn() -> &'static AtomInfo>] { Self::ATOM_DEFS }
|
||||
fn atoms(&self) -> &'static [Option<&'static dyn AtomDynfo>] { Self::ATOM_DEFS }
|
||||
}
|
||||
|
||||
/// System as defined by author
|
||||
@@ -85,7 +86,7 @@ pub fn downcast_atom<A: AtomCard>(foreign: ForeignAtom) -> Result<TypAtom<A>, Fo
|
||||
match info_ent {
|
||||
None => Err(foreign),
|
||||
Some((_, info)) => {
|
||||
let val = (info.decode)(data);
|
||||
let val = info.decode(data);
|
||||
let value = *val.downcast::<A::Data>().expect("atom decode returned wrong type");
|
||||
Ok(TypAtom { value, data: foreign })
|
||||
},
|
||||
|
||||
@@ -4,38 +4,34 @@ use ahash::HashMap;
|
||||
use dyn_clone::{clone_box, DynClone};
|
||||
use itertools::Itertools;
|
||||
use orchid_api::tree::{
|
||||
MacroRule, Paren, Placeholder, PlaceholderKind, Token, TokenTree, Tree, TreeId, TreeModule,
|
||||
MacroRule, Paren, PlaceholderKind, Token, TokenTree, Tree, TreeId, TreeModule,
|
||||
TreeTicket,
|
||||
};
|
||||
use orchid_base::interner::{intern, Tok};
|
||||
use orchid_base::interner::intern;
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::VName;
|
||||
use orchid_base::tokens::OwnedPh;
|
||||
use ordered_float::NotNan;
|
||||
use trait_set::trait_set;
|
||||
|
||||
use crate::atom::AtomFactory;
|
||||
use crate::conv::ToExpr;
|
||||
use crate::error::{err_or_ref_to_api, ProjectErrorObj};
|
||||
use crate::expr::GenExpr;
|
||||
use crate::system::DynSystem;
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenPh {
|
||||
pub name: Tok<String>,
|
||||
pub kind: PlaceholderKind,
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenTokTree {
|
||||
pub tok: GenTok,
|
||||
pub struct OwnedTokTree {
|
||||
pub tok: OwnedTok,
|
||||
pub range: Range<u32>,
|
||||
}
|
||||
impl GenTokTree {
|
||||
impl OwnedTokTree {
|
||||
pub fn into_api(self, sys: &dyn DynSystem) -> TokenTree {
|
||||
TokenTree { token: self.tok.into_api(sys), range: self.range }
|
||||
}
|
||||
}
|
||||
|
||||
pub fn ph(s: &str) -> GenPh {
|
||||
pub fn ph(s: &str) -> OwnedPh {
|
||||
match s.strip_prefix("..") {
|
||||
Some(v_tail) => {
|
||||
let (mid, priority) = match v_tail.split_once(':') {
|
||||
@@ -49,29 +45,30 @@ pub fn ph(s: &str) -> GenPh {
|
||||
if konst::string::starts_with(name, "_") {
|
||||
panic!("Names starting with an underscore indicate a single-name scalar placeholder")
|
||||
}
|
||||
GenPh { name: intern(name), kind: PlaceholderKind::Vector { nonzero, priority } }
|
||||
OwnedPh { name: intern(name), kind: PlaceholderKind::Vector { nonzero, priority } }
|
||||
},
|
||||
None => match konst::string::strip_prefix(s, "$_") {
|
||||
Some(name) => GenPh { name: intern(name), kind: PlaceholderKind::Name },
|
||||
Some(name) => OwnedPh { name: intern(name), kind: PlaceholderKind::Name },
|
||||
None => match konst::string::strip_prefix(s, "$") {
|
||||
None => panic!("Invalid placeholder"),
|
||||
Some(name) => GenPh { name: intern(name), kind: PlaceholderKind::Scalar },
|
||||
Some(name) => OwnedPh { name: intern(name), kind: PlaceholderKind::Scalar },
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub enum GenTok {
|
||||
Lambda(Vec<GenTokTree>, Vec<GenTokTree>),
|
||||
pub enum OwnedTok {
|
||||
Lambda(Vec<OwnedTokTree>, Vec<OwnedTokTree>),
|
||||
Name(VName),
|
||||
S(Paren, Vec<GenTokTree>),
|
||||
S(Paren, Vec<OwnedTokTree>),
|
||||
Atom(AtomFactory),
|
||||
Slot(TreeTicket),
|
||||
Ph(GenPh),
|
||||
Ph(OwnedPh),
|
||||
Bottom(ProjectErrorObj),
|
||||
}
|
||||
impl GenTok {
|
||||
pub fn at(self, range: Range<u32>) -> GenTokTree { GenTokTree { tok: self, range } }
|
||||
impl OwnedTok {
|
||||
pub fn at(self, range: Range<u32>) -> OwnedTokTree { OwnedTokTree { tok: self, range } }
|
||||
pub fn into_api(self, sys: &dyn DynSystem) -> Token {
|
||||
match self {
|
||||
Self::Lambda(x, body) => Token::Lambda(
|
||||
@@ -79,32 +76,33 @@ impl GenTok {
|
||||
body.into_iter().map(|tt| tt.into_api(sys)).collect_vec(),
|
||||
),
|
||||
Self::Name(n) => Token::Name(n.into_iter().map(|t| t.marker()).collect_vec()),
|
||||
Self::Ph(GenPh { name, kind }) => Token::Ph(Placeholder { name: name.marker(), kind }),
|
||||
Self::Ph(ph) => Token::Ph(ph.to_api()),
|
||||
Self::S(p, body) => Token::S(p, body.into_iter().map(|tt| tt.into_api(sys)).collect_vec()),
|
||||
Self::Slot(tk) => Token::Slot(tk),
|
||||
Self::Atom(at) => Token::Atom(at.build(sys)),
|
||||
Self::Bottom(err) => Token::Bottom(err_or_ref_to_api(err)),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenMacro {
|
||||
pub pattern: Vec<GenTokTree>,
|
||||
pub pattern: Vec<OwnedTokTree>,
|
||||
pub priority: NotNan<f64>,
|
||||
pub template: Vec<GenTokTree>,
|
||||
pub template: Vec<OwnedTokTree>,
|
||||
}
|
||||
|
||||
pub fn tokv_into_api(
|
||||
tokv: impl IntoIterator<Item = GenTokTree>,
|
||||
tokv: impl IntoIterator<Item = OwnedTokTree>,
|
||||
sys: &dyn DynSystem,
|
||||
) -> Vec<TokenTree> {
|
||||
tokv.into_iter().map(|tok| tok.into_api(sys)).collect_vec()
|
||||
}
|
||||
|
||||
pub fn wrap_tokv(items: Vec<GenTokTree>, range: Range<u32>) -> GenTokTree {
|
||||
pub fn wrap_tokv(items: Vec<OwnedTokTree>, range: Range<u32>) -> OwnedTokTree {
|
||||
match items.len() {
|
||||
1 => items.into_iter().next().unwrap(),
|
||||
_ => GenTok::S(Paren::Round, items).at(range),
|
||||
_ => OwnedTok::S(Paren::Round, items).at(range),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -120,8 +118,8 @@ impl GenTree {
|
||||
}
|
||||
pub fn rule(
|
||||
prio: f64,
|
||||
pat: impl IntoIterator<Item = GenTokTree>,
|
||||
tpl: impl IntoIterator<Item = GenTokTree>,
|
||||
pat: impl IntoIterator<Item = OwnedTokTree>,
|
||||
tpl: impl IntoIterator<Item = OwnedTokTree>,
|
||||
) -> Self {
|
||||
GenItem::Rule(GenMacro {
|
||||
pattern: pat.into_iter().collect(),
|
||||
|
||||
Reference in New Issue
Block a user