Removed macro facets

Macros, placeholders, etc. will all be handled by std eventually so they shouldn't appear in the protocol or the host
This commit is contained in:
2024-08-22 18:05:57 +02:00
parent 3a63894de2
commit 84cbcdd4fe
37 changed files with 210 additions and 350 deletions

22
.zed/settings.json Normal file
View File

@@ -0,0 +1,22 @@
{
"languages": {
"Rust": {
"language_servers": ["rust-analyzer", "..."]
}
},
"wrap_guides": [100],
"lsp": {
"rust-analyzer": {
"binary": {
"path": "C:\\Users\\z004yk5r\\.cargo\\bin\\rust-analyzer.exe"
},
"initialization_options": {
"checkOnSave": {
"command": "clippy"
}
}
}
},
"tab_size": 2,
"rust-analyzer": {}
}

35
Cargo.lock generated
View File

@@ -236,12 +236,6 @@ version = "0.2.8"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b" checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b"
[[package]]
name = "convert_case"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
[[package]] [[package]]
name = "cpufeatures" name = "cpufeatures"
version = "0.2.12" version = "0.2.12"
@@ -307,19 +301,6 @@ dependencies = [
"syn 0.15.44", "syn 0.15.44",
] ]
[[package]]
name = "derive_more"
version = "0.99.17"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "4fb810d30a7c1953f91334de7244731fc3f3c10d7fe163338a35b9f640960321"
dependencies = [
"convert_case",
"proc-macro2 1.0.78",
"quote 1.0.35",
"rustc_version",
"syn 1.0.109",
]
[[package]] [[package]]
name = "digest" name = "digest"
version = "0.10.7" version = "0.10.7"
@@ -513,7 +494,6 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
name = "orchid-api" name = "orchid-api"
version = "0.1.0" version = "0.1.0"
dependencies = [ dependencies = [
"derive_more",
"orchid-api-derive", "orchid-api-derive",
"orchid-api-traits", "orchid-api-traits",
"ordered-float", "ordered-float",
@@ -858,15 +838,6 @@ dependencies = [
"serde_json", "serde_json",
] ]
[[package]]
name = "rustc_version"
version = "0.4.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfa0f585226d2e68097d4f95d113b15b83a82e819ab25717ec0590d9584ef366"
dependencies = [
"semver",
]
[[package]] [[package]]
name = "ryu" name = "ryu"
version = "1.0.18" version = "1.0.18"
@@ -888,12 +859,6 @@ version = "4.1.0"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b" checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
[[package]]
name = "semver"
version = "1.0.22"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
[[package]] [[package]]
name = "serde" name = "serde"
version = "1.0.204" version = "1.0.204"

View File

@@ -25,5 +25,3 @@ pub fn hierarchy(input: TokenStream) -> TokenStream { hierarchy::derive(input) }
pub fn coding(input: TokenStream) -> TokenStream { pub fn coding(input: TokenStream) -> TokenStream {
decode(input.clone()).into_iter().chain(encode(input)).collect() decode(input.clone()).into_iter().chain(encode(input)).collect()
} }
// TODO: Figure out how serialize/deserialize can be elegantly implemented
// consider adding a context argument to encode/decode that can just be forwarded

View File

@@ -8,7 +8,7 @@ use std::rc::Rc;
use std::sync::Arc; use std::sync::Arc;
use never::Never; use never::Never;
use ordered_float::{FloatCore, NotNan}; use ordered_float::NotNan;
use crate::encode_enum; use crate::encode_enum;
@@ -29,10 +29,10 @@ pub trait Coding: Encode + Decode + Clone {
impl<T: Encode + Decode + Clone> Coding for T {} impl<T: Encode + Decode + Clone> Coding for T {}
macro_rules! num_impl { macro_rules! num_impl {
($number:ty, $size:expr) => { ($number:ty) => {
impl Decode for $number { impl Decode for $number {
fn decode<R: Read + ?Sized>(read: &mut R) -> Self { fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
let mut bytes = [0u8; $size]; let mut bytes = [0u8; (<$number>::BITS / 8) as usize];
read.read_exact(&mut bytes).unwrap(); read.read_exact(&mut bytes).unwrap();
<$number>::from_be_bytes(bytes) <$number>::from_be_bytes(bytes)
} }
@@ -43,9 +43,6 @@ macro_rules! num_impl {
} }
} }
}; };
($number:ty) => {
num_impl!($number, (<$number>::BITS / 8) as usize);
};
} }
num_impl!(u128); num_impl!(u128);
num_impl!(u64); num_impl!(u64);
@@ -57,8 +54,6 @@ num_impl!(i64);
num_impl!(i32); num_impl!(i32);
num_impl!(i16); num_impl!(i16);
num_impl!(i8); num_impl!(i8);
num_impl!(f64, 8);
num_impl!(f32, 4);
macro_rules! nonzero_impl { macro_rules! nonzero_impl {
($name:ty) => { ($name:ty) => {
@@ -85,14 +80,26 @@ nonzero_impl!(std::num::NonZeroI128);
impl<'a, T: Encode + ?Sized> Encode for &'a T { impl<'a, T: Encode + ?Sized> Encode for &'a T {
fn encode<W: Write + ?Sized>(&self, write: &mut W) { (**self).encode(write) } fn encode<W: Write + ?Sized>(&self, write: &mut W) { (**self).encode(write) }
} }
impl<T: Decode + FloatCore> Decode for NotNan<T> { macro_rules! float_impl {
($t:ty, $size:expr) => {
impl Decode for NotNan<$t> {
fn decode<R: Read + ?Sized>(read: &mut R) -> Self { fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
NotNan::new(T::decode(read)).expect("Float was NaN") let mut bytes = [0u8; $size];
read.read_exact(&mut bytes).unwrap();
NotNan::new(<$t>::from_be_bytes(bytes)).expect("Float was NaN")
} }
}
impl Encode for NotNan<$t> {
fn encode<W: Write + ?Sized>(&self, write: &mut W) {
write.write_all(&self.as_ref().to_be_bytes()).expect("Could not write number")
}
}
};
} }
impl<T: Encode + FloatCore> Encode for NotNan<T> {
fn encode<W: Write + ?Sized>(&self, write: &mut W) { self.as_ref().encode(write) } float_impl!(f64, 8);
} float_impl!(f32, 4);
impl Decode for String { impl Decode for String {
fn decode<R: Read + ?Sized>(read: &mut R) -> Self { fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
let len = u64::decode(read).try_into().unwrap(); let len = u64::decode(read).try_into().unwrap();

View File

@@ -4,6 +4,6 @@ mod hierarchy;
mod relations; mod relations;
pub use coding::{Coding, Decode, Encode}; pub use coding::{Coding, Decode, Encode};
pub use helpers::{encode_enum, read_exact, write_exact, enc_vec}; pub use helpers::{enc_vec, encode_enum, read_exact, write_exact};
pub use hierarchy::{Extends, InHierarchy, TLBool, TLFalse, TLTrue, UnderRoot}; pub use hierarchy::{Extends, InHierarchy, TLBool, TLFalse, TLTrue, UnderRoot};
pub use relations::{Channel, MsgSet, Request}; pub use relations::{Channel, MsgSet, Request};

View File

@@ -1,6 +1,5 @@
use crate::helpers::enc_vec;
use super::coding::Coding; use super::coding::Coding;
use crate::helpers::enc_vec;
pub trait Request: Coding + Sized + Send + 'static { pub trait Request: Coding + Sized + Send + 'static {
type Response: Coding + Send + 'static; type Response: Coding + Send + 'static;

View File

@@ -9,4 +9,3 @@ edition = "2021"
ordered-float = "4.2.0" ordered-float = "4.2.0"
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" } orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" } orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
derive_more = "0.99.17"

View File

@@ -75,8 +75,6 @@ pub enum Clause {
/// the atom must be trivial. This is always a newly constructed atom, if you /// the atom must be trivial. This is always a newly constructed atom, if you
/// want to reference an existing atom, use the corresponding [ExprTicket]. /// want to reference an existing atom, use the corresponding [ExprTicket].
/// Because the atom is newly constructed, it also must belong to this system. /// Because the atom is newly constructed, it also must belong to this system.
/// For convenience, [SysId::MAX] is also accepted as referring to this
/// system.
NewAtom(Atom), NewAtom(Atom),
/// An atom, specifically an atom that already exists. This form is only ever /// An atom, specifically an atom that already exists. This form is only ever
/// returned from [Inspect], and it's borrowed from the expression being /// returned from [Inspect], and it's borrowed from the expression being

View File

@@ -1,7 +1,7 @@
mod atom; mod atom;
pub use atom::{ pub use atom::{
Atom, AtomData, AtomDrop, AtomId, AtomPrint, AtomReq, AtomSame, CallRef, Command, FinalCall, Fwd, Atom, AtomData, AtomDrop, AtomId, AtomPrint, AtomReq, AtomSame, CallRef, Command, DeserAtom,
Fwded, LocalAtom, NextStep, DeserAtom, SerializeAtom FinalCall, Fwd, Fwded, LocalAtom, NextStep, SerializeAtom,
}; };
mod error; mod error;
pub use error::{ErrId, ErrLocation, OrcError, OrcResult}; pub use error::{ErrId, ErrLocation, OrcError, OrcResult};
@@ -25,11 +25,11 @@ pub use proto::{
HostExtNotif, HostExtReq, HostHeader, HostMsgSet, Ping, HostExtNotif, HostExtReq, HostHeader, HostMsgSet, Ping,
}; };
mod system; mod system;
pub use system::{SysReq, NewSystem, SysDeclId, SysId, SystemDecl, SystemDrop, SystemInst}; pub use system::{NewSystem, SysDeclId, SysId, SysReq, SystemDecl, SystemDrop, SystemInst};
mod tree; mod tree;
pub use tree::{ pub use tree::{
CompName, GetMember, Item, ItemKind, Macro, Member, MemberKind, Module, Paren, Placeholder, CompName, GetMember, Item, ItemKind, Member, MemberKind, Module, Paren, Token, TokenTree, TreeId,
PlaceholderKind, Token, TokenTree, TreeId, TreeTicket, TreeTicket,
}; };
mod vfs; mod vfs;
pub use vfs::{EagerVfs, GetVfs, Loaded, VfsId, VfsRead, VfsReq}; pub use vfs::{EagerVfs, GetVfs, Loaded, VfsId, VfsRead, VfsReq};

View File

@@ -146,7 +146,7 @@ impl MsgSet for HostMsgSet {
#[cfg(test)] #[cfg(test)]
mod tests { mod tests {
use orchid_api_traits::enc_vec; use orchid_api_traits::enc_vec;
use ordered_float::NotNan; use ordered_float::NotNan;
use system::{SysDeclId, SystemDecl}; use system::{SysDeclId, SystemDecl};
use super::*; use super::*;

View File

@@ -4,7 +4,6 @@ use std::sync::Arc;
use orchid_api_derive::{Coding, Hierarchy}; use orchid_api_derive::{Coding, Hierarchy};
use orchid_api_traits::Request; use orchid_api_traits::Request;
use ordered_float::NotNan;
use crate::error::OrcError; use crate::error::OrcError;
use crate::interner::{TStr, TStrv}; use crate::interner::{TStr, TStrv};
@@ -41,9 +40,6 @@ pub enum Token {
BR, BR,
/// ( Round parens ), [ Square brackets ] or { Curly braces } /// ( Round parens ), [ Square brackets ] or { Curly braces }
S(Paren, Vec<TokenTree>), S(Paren, Vec<TokenTree>),
/// A placeholder in a macro. This variant is forbidden everywhere outside
/// line parser output
Ph(Placeholder),
/// A new atom /// A new atom
Atom(Atom), Atom(Atom),
/// Anchor to insert a subtree /// Anchor to insert a subtree
@@ -55,19 +51,6 @@ pub enum Token {
Comment(Arc<String>), Comment(Arc<String>),
} }
#[derive(Clone, Debug, Coding)]
pub struct Placeholder {
pub name: TStr,
pub kind: PlaceholderKind,
}
#[derive(Clone, Debug, Coding)]
pub enum PlaceholderKind {
Scalar,
Name,
Vector { nz: bool, prio: u8 },
}
#[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)] #[derive(Clone, Debug, Hash, PartialEq, Eq, Coding)]
pub enum Paren { pub enum Paren {
Round, Round,
@@ -75,13 +58,6 @@ pub enum Paren {
Curly, Curly,
} }
#[derive(Clone, Debug, Coding)]
pub struct Macro {
pub pattern: Vec<TokenTree>,
pub priority: NotNan<f64>,
pub template: Vec<TokenTree>,
}
#[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Coding)] #[derive(Copy, Clone, Debug, Hash, PartialEq, Eq, PartialOrd, Ord, Coding)]
pub struct TreeId(pub NonZeroU64); pub struct TreeId(pub NonZeroU64);
@@ -97,7 +73,6 @@ pub enum ItemKind {
Member(Member), Member(Member),
Raw(Vec<TokenTree>), Raw(Vec<TokenTree>),
Export(TStr), Export(TStr),
Rule(Macro),
Import(CompName), Import(CompName),
} }

View File

@@ -2,9 +2,9 @@ use std::sync::Arc;
use itertools::Itertools; use itertools::Itertools;
use crate::api;
use crate::interner::{deintern, Tok}; use crate::interner::{deintern, Tok};
use crate::location::Pos; use crate::location::Pos;
use crate::api;
/// A point of interest in resolving the error, such as the point where /// A point of interest in resolving the error, such as the point where
/// processing got stuck, a command that is likely to be incorrect /// processing got stuck, a command that is likely to be incorrect

View File

@@ -7,7 +7,7 @@ use std::{fmt, hash};
use hashbrown::{HashMap, HashSet}; use hashbrown::{HashMap, HashSet};
use itertools::Itertools as _; use itertools::Itertools as _;
use orchid_api_traits::{Encode, Decode, Request}; use orchid_api_traits::{Decode, Encode, Request};
use crate::api; use crate::api;
use crate::reqnot::{DynRequester, Requester}; use crate::reqnot::{DynRequester, Requester};
@@ -59,9 +59,7 @@ impl<T: Interned + Encode> Encode for Tok<T> {
fn encode<W: std::io::Write + ?Sized>(&self, write: &mut W) { self.data.encode(write) } fn encode<W: std::io::Write + ?Sized>(&self, write: &mut W) { self.data.encode(write) }
} }
impl<T: Interned + Decode> Decode for Tok<T> { impl<T: Interned + Decode> Decode for Tok<T> {
fn decode<R: std::io::Read + ?Sized>(read: &mut R) -> Self { fn decode<R: std::io::Read + ?Sized>(read: &mut R) -> Self { intern(&T::decode(read)) }
intern(&T::decode(read))
}
} }
pub trait Interned: Eq + hash::Hash + Clone + Internable<Interned = Self> { pub trait Interned: Eq + hash::Hash + Clone + Internable<Interned = Self> {

View File

@@ -93,7 +93,7 @@ impl<T: NameIndex> Index<T> for PathSlice {
mod idx_impls { mod idx_impls {
use std::ops; use std::ops;
use super::{NameIndex, PathSlice, conv_range}; use super::{conv_range, NameIndex, PathSlice};
use crate::interner::Tok; use crate::interner::Tok;
impl NameIndex for u16 { impl NameIndex for u16 {
@@ -146,7 +146,7 @@ pub fn conv_bound<T: Into<U> + Clone, U>(bound: Bound<&T>) -> Bound<U> {
} }
} }
pub fn conv_range<'a, T: Into<U> + Clone + 'a, U: 'a>( pub fn conv_range<'a, T: Into<U> + Clone + 'a, U: 'a>(
range: impl RangeBounds<T> range: impl RangeBounds<T>,
) -> (Bound<U>, Bound<U>) { ) -> (Bound<U>, Bound<U>) {
(conv_bound(range.start_bound()), conv_bound(range.end_bound())) (conv_bound(range.start_bound()), conv_bound(range.end_bound()))
} }

View File

@@ -143,7 +143,8 @@ pub fn expect_end(snip: Snippet<'_, '_, impl AtomInTok, impl Sized>) -> OrcRes<(
} }
pub fn expect_tok<'a, 'b, A: AtomInTok, X: fmt::Display>( pub fn expect_tok<'a, 'b, A: AtomInTok, X: fmt::Display>(
snip: Snippet<'a, 'b, A, X>, tok: Tok<String> snip: Snippet<'a, 'b, A, X>,
tok: Tok<String>,
) -> OrcRes<Snippet<'a, 'b, A, X>> { ) -> OrcRes<Snippet<'a, 'b, A, X>> {
let (head, tail) = try_pop_no_fluff(snip)?; let (head, tail) = try_pop_no_fluff(snip)?;
match &head.tok { match &head.tok {
@@ -151,8 +152,8 @@ pub fn expect_tok<'a, 'b, A: AtomInTok, X: fmt::Display>(
t => Err(vec![mk_err( t => Err(vec![mk_err(
intern!(str: "Expected specific keyword"), intern!(str: "Expected specific keyword"),
format!("Expected {tok} but found {t}"), format!("Expected {tok} but found {t}"),
[Pos::Range(head.range.clone()).into()] [Pos::Range(head.range.clone()).into()],
)]) )]),
} }
} }

View File

@@ -14,7 +14,8 @@ pub struct ReplyToken;
trait_set! { trait_set! {
pub trait SendFn<T: MsgSet> = for<'a> FnMut(&'a [u8], ReqNot<T>) + DynClone + Send + 'static; pub trait SendFn<T: MsgSet> = for<'a> FnMut(&'a [u8], ReqNot<T>) + DynClone + Send + 'static;
pub trait ReqFn<T: MsgSet> = FnMut(RequestHandle<T>) -> ReplyToken + DynClone + Send + Sync + 'static; pub trait ReqFn<T: MsgSet> =
FnMut(RequestHandle<T>) -> ReplyToken + DynClone + Send + Sync + 'static;
pub trait NotifFn<T: MsgSet> = pub trait NotifFn<T: MsgSet> =
for<'a> FnMut(<T::In as Channel>::Notif, ReqNot<T>) + DynClone + Send + Sync + 'static; for<'a> FnMut(<T::In as Channel>::Notif, ReqNot<T>) + DynClone + Send + Sync + 'static;
} }

View File

@@ -1,34 +1,6 @@
use std::fmt::Display;
pub use api::Paren; pub use api::Paren;
use crate::api; use crate::api;
use crate::interner::{deintern, Tok};
pub const PARENS: &[(char, char, Paren)] = pub const PARENS: &[(char, char, Paren)] =
&[('(', ')', Paren::Round), ('[', ']', Paren::Square), ('{', '}', Paren::Curly)]; &[('(', ')', Paren::Round), ('[', ']', Paren::Square), ('{', '}', Paren::Curly)];
#[derive(Clone, Debug)]
pub struct OwnedPh {
pub name: Tok<String>,
pub kind: api::PlaceholderKind,
}
impl OwnedPh {
pub fn to_api(&self) -> api::Placeholder {
api::Placeholder { name: self.name.marker(), kind: self.kind.clone() }
}
pub fn from_api(ph: api::Placeholder) -> Self { Self { name: deintern(ph.name), kind: ph.kind } }
}
impl Display for OwnedPh {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self.kind {
api::PlaceholderKind::Name => write!(f, "$_{}", self.name),
api::PlaceholderKind::Scalar => write!(f, "${}", self.name),
api::PlaceholderKind::Vector { nz: false, prio: 0 } => write!(f, "..${}", self.name),
api::PlaceholderKind::Vector { nz: true, prio: 0 } => write!(f, "...${}", self.name),
api::PlaceholderKind::Vector { nz: false, prio } => write!(f, "..${}:{prio}", self.name),
api::PlaceholderKind::Vector { nz: true, prio } => write!(f, "...${}:{prio}", self.name),
}
}
}

View File

@@ -12,9 +12,9 @@ use trait_set::trait_set;
use crate::api; use crate::api;
use crate::error::OrcErr; use crate::error::OrcErr;
use crate::interner::{deintern, intern, Tok}; use crate::interner::{deintern, Tok};
use crate::name::{NameLike, VName}; use crate::name::{NameLike, VName};
use crate::tokens::{OwnedPh, PARENS}; use crate::tokens::PARENS;
trait_set! { trait_set! {
pub trait RecurCB<'a, A: AtomInTok, X> = Fn(TokTree<'a, A, X>) -> TokTree<'a, A, X>; pub trait RecurCB<'a, A: AtomInTok, X> = Fn(TokTree<'a, A, X>) -> TokTree<'a, A, X>;
@@ -27,7 +27,7 @@ pub fn recur<'a, A: AtomInTok, X>(
f(tt, &|TokTree { range, tok }| { f(tt, &|TokTree { range, tok }| {
let tok = match tok { let tok = match tok {
tok @ (Token::Atom(_) | Token::BR | Token::Bottom(_) | Token::Comment(_) | Token::NS) => tok, tok @ (Token::Atom(_) | Token::BR | Token::Bottom(_) | Token::Comment(_) | Token::NS) => tok,
tok @ (Token::Name(_) | Token::Ph(_) | Token::Slot(_) | Token::X(_)) => tok, tok @ (Token::Name(_) | Token::Slot(_) | Token::X(_)) => tok,
Token::LambdaHead(arg) => Token::LambdaHead(arg) =>
Token::LambdaHead(arg.into_iter().map(|tt| recur(tt, f)).collect_vec()), Token::LambdaHead(arg.into_iter().map(|tt| recur(tt, f)).collect_vec()),
Token::S(p, b) => Token::S(p, b.into_iter().map(|tt| recur(tt, f)).collect_vec()), Token::S(p, b) => Token::S(p, b.into_iter().map(|tt| recur(tt, f)).collect_vec()),
@@ -73,7 +73,6 @@ impl<'a, A: AtomInTok, X> TokTree<'a, A, X> {
api::Token::Bottom(e) => Token::Bottom(e.iter().map(OrcErr::from_api).collect()), api::Token::Bottom(e) => Token::Bottom(e.iter().map(OrcErr::from_api).collect()),
api::Token::Lambda(arg) => Token::LambdaHead(ttv_from_api(arg, ctx)), api::Token::Lambda(arg) => Token::LambdaHead(ttv_from_api(arg, ctx)),
api::Token::Name(name) => Token::Name(deintern(*name)), api::Token::Name(name) => Token::Name(deintern(*name)),
api::Token::Ph(ph) => Token::Ph(OwnedPh::from_api(ph.clone())),
api::Token::S(par, b) => Token::S(par.clone(), ttv_from_api(b, ctx)), api::Token::S(par, b) => Token::S(par.clone(), ttv_from_api(b, ctx)),
api::Token::Comment(c) => Token::Comment(c.clone()), api::Token::Comment(c) => Token::Comment(c.clone()),
api::Token::Slot(id) => Token::Slot(TreeHandle::new(*id)), api::Token::Slot(id) => Token::Slot(TreeHandle::new(*id)),
@@ -94,7 +93,6 @@ impl<'a, A: AtomInTok, X> TokTree<'a, A, X> {
Token::LambdaHead(arg) => Token::LambdaHead(arg) =>
api::Token::Lambda(arg.iter().map(|t| t.to_api(do_extra)).collect_vec()), api::Token::Lambda(arg.iter().map(|t| t.to_api(do_extra)).collect_vec()),
Token::Name(n) => api::Token::Name(n.marker()), Token::Name(n) => api::Token::Name(n.marker()),
Token::Ph(ph) => api::Token::Ph(ph.to_api()),
Token::Slot(tt) => api::Token::Slot(tt.ticket()), Token::Slot(tt) => api::Token::Slot(tt.ticket()),
Token::S(p, b) => api::Token::S(p.clone(), b.iter().map(|t| t.to_api(do_extra)).collect()), Token::S(p, b) => api::Token::S(p.clone(), b.iter().map(|t| t.to_api(do_extra)).collect()),
Token::X(x) => return do_extra(x, self.range.clone()), Token::X(x) => return do_extra(x, self.range.clone()),
@@ -146,35 +144,6 @@ pub fn wrap_tokv<'a, A: AtomInTok + 'a, X: 'a>(
} }
} }
pub fn ph(s: &str) -> OwnedPh {
match s.strip_prefix("..") {
Some(v_tail) => {
let (mid, priority) = match v_tail.split_once(':') {
Some((h, t)) => (h, t.parse().expect("priority not an u8")),
None => (v_tail, 0),
};
let (name, nonzero) = match mid.strip_prefix(".$") {
Some(name) => (name, true),
None => (mid.strip_prefix('$').expect("Invalid placeholder"), false),
};
if name.starts_with("_") {
panic!("Names starting with an underscore indicate a single-name scalar placeholder")
}
OwnedPh {
name: intern(name),
kind: api::PlaceholderKind::Vector { nz: nonzero, prio: priority },
}
},
None => match s.strip_prefix("$_") {
Some(name) => OwnedPh { name: intern(name), kind: api::PlaceholderKind::Name },
None => match s.strip_prefix("$") {
None => panic!("Invalid placeholder"),
Some(name) => OwnedPh { name: intern(name), kind: api::PlaceholderKind::Scalar },
},
},
}
}
pub use api::Paren; pub use api::Paren;
#[derive(Clone, Debug)] #[derive(Clone, Debug)]
@@ -186,7 +155,6 @@ pub enum Token<'a, A: AtomInTok, X> {
BR, BR,
S(Paren, Vec<TokTree<'a, A, X>>), S(Paren, Vec<TokTree<'a, A, X>>),
Atom(A), Atom(A),
Ph(OwnedPh),
Bottom(Vec<OrcErr>), Bottom(Vec<OrcErr>),
Slot(TreeHandle<'a>), Slot(TreeHandle<'a>),
X(X), X(X),
@@ -218,7 +186,6 @@ impl<'a, A: AtomInTok + Display, X: Display> Display for Token<'a, A, X> {
Self::LambdaHead(arg) => with_indent(|| write!(f, "\\ {} .", ttv_fmt(arg))), Self::LambdaHead(arg) => with_indent(|| write!(f, "\\ {} .", ttv_fmt(arg))),
Self::NS => f.write_str("::"), Self::NS => f.write_str("::"),
Self::Name(n) => f.write_str(n), Self::Name(n) => f.write_str(n),
Self::Ph(ph) => write!(f, "{ph}"),
Self::Slot(th) => write!(f, "{th}"), Self::Slot(th) => write!(f, "{th}"),
Self::S(p, b) => { Self::S(p, b) => {
let (lp, rp, _) = PARENS.iter().find(|(_, _, par)| par == p).unwrap(); let (lp, rp, _) = PARENS.iter().find(|(_, _, par)| par == p).unwrap();

View File

@@ -63,7 +63,7 @@ impl<A: Atomic + AtomicFeaturesImpl<A::Variant> + ?Sized> AtomicFeatures for A {
} }
pub fn get_info<A: AtomCard>( pub fn get_info<A: AtomCard>(
sys: &(impl DynSystemCard + ?Sized) sys: &(impl DynSystemCard + ?Sized),
) -> (api::AtomId, &'static dyn AtomDynfo) { ) -> (api::AtomId, &'static dyn AtomDynfo) {
atom_info_for(sys, TypeId::of::<A>()).unwrap_or_else(|| { atom_info_for(sys, TypeId::of::<A>()).unwrap_or_else(|| {
panic!("Atom {} not associated with system {}", type_name::<A>(), sys.name()) panic!("Atom {} not associated with system {}", type_name::<A>(), sys.name())
@@ -195,10 +195,10 @@ pub trait ReqPck<T: AtomCard + ?Sized>: Sized {
} }
} }
pub(crate) struct RequestPack<'a, T: AtomCard + ?Sized, W: Write + ?Sized>{ pub(crate) struct RequestPack<'a, T: AtomCard + ?Sized, W: Write + ?Sized> {
pub req: T::Req, pub req: T::Req,
pub write: &'a mut W, pub write: &'a mut W,
pub sys: SysCtx pub sys: SysCtx,
} }
impl<'a, T: AtomCard + ?Sized, W: Write + ?Sized> ReqPck<T> for RequestPack<'a, T, W> { impl<'a, T: AtomCard + ?Sized, W: Write + ?Sized> ReqPck<T> for RequestPack<'a, T, W> {

View File

@@ -64,7 +64,11 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
fn drop(&self, AtomCtx(_, id, ctx): AtomCtx) { fn drop(&self, AtomCtx(_, id, ctx): AtomCtx) {
with_atom(id.unwrap(), |a| a.remove().dyn_free(ctx)) with_atom(id.unwrap(), |a| a.remove().dyn_free(ctx))
} }
fn serialize(&self, AtomCtx(_, id, ctx): AtomCtx<'_>, write: &mut dyn Write) -> Vec<api::ExprTicket> { fn serialize(
&self,
AtomCtx(_, id, ctx): AtomCtx<'_>,
write: &mut dyn Write,
) -> Vec<api::ExprTicket> {
let id = id.unwrap(); let id = id.unwrap();
id.encode(write); id.encode(write);
with_atom(id, |a| a.dyn_serialize(ctx, write)).into_iter().map(|t| t.into_tk()).collect_vec() with_atom(id, |a| a.dyn_serialize(ctx, write)).into_iter().map(|t| t.into_tk()).collect_vec()
@@ -182,7 +186,8 @@ impl<T: OwnedAtom> DynOwnedAtom for T {
self.same(ctx, other_self) self.same(ctx, other_self)
} }
fn dyn_handle_req(&self, sys: SysCtx, req: &mut dyn Read, write: &mut dyn Write) { fn dyn_handle_req(&self, sys: SysCtx, req: &mut dyn Read, write: &mut dyn Write) {
let pack = RequestPack::<T, dyn Write>{ req: <Self as AtomCard>::Req::decode(req), write, sys }; let pack =
RequestPack::<T, dyn Write> { req: <Self as AtomCard>::Req::decode(req), write, sys };
self.handle_req(pack) self.handle_req(pack)
} }
fn dyn_command(self: Box<Self>, ctx: SysCtx) -> OrcRes<Option<GenExpr>> { self.command(ctx) } fn dyn_command(self: Box<Self>, ctx: SysCtx) -> OrcRes<Option<GenExpr>> { self.command(ctx) }

View File

@@ -49,7 +49,7 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
req: &mut dyn std::io::Read, req: &mut dyn std::io::Read,
write: &mut dyn Write, write: &mut dyn Write,
) { ) {
let pack = RequestPack::<T, dyn Write>{ req: Decode::decode(req), write, sys }; let pack = RequestPack::<T, dyn Write> { req: Decode::decode(req), write, sys };
T::decode(&mut &buf[..]).handle_req(pack) T::decode(&mut &buf[..]).handle_req(pack)
} }
fn same(&self, AtomCtx(buf, _, ctx): AtomCtx, a2: &api::Atom) -> bool { fn same(&self, AtomCtx(buf, _, ctx): AtomCtx, a2: &api::Atom) -> bool {
@@ -58,7 +58,7 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
fn command(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> OrcRes<Option<GenExpr>> { fn command(&self, AtomCtx(buf, _, ctx): AtomCtx<'_>) -> OrcRes<Option<GenExpr>> {
T::decode(&mut &buf[..]).command(ctx) T::decode(&mut &buf[..]).command(ctx)
} }
fn serialize(&self, AtomCtx(buf, _, _): AtomCtx<'_>, write: &mut dyn Write) -> Vec<ExprTicket> { fn serialize(&self, AtomCtx(buf, ..): AtomCtx<'_>, write: &mut dyn Write) -> Vec<ExprTicket> {
T::decode(&mut &buf[..]).encode(write); T::decode(&mut &buf[..]).encode(write);
Vec::new() Vec::new()
} }
@@ -72,7 +72,9 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
} }
} }
pub trait ThinAtom: AtomCard<Data = Self> + Atomic<Variant = ThinVariant> + Coding + Send + Sync + 'static { pub trait ThinAtom:
AtomCard<Data = Self> + Atomic<Variant = ThinVariant> + Coding + Send + Sync + 'static
{
#[allow(unused_variables)] #[allow(unused_variables)]
fn call(&self, arg: ExprHandle) -> GenExpr { bot(err_not_callable()) } fn call(&self, arg: ExprHandle) -> GenExpr { bot(err_not_callable()) }
#[allow(unused_variables)] #[allow(unused_variables)]

View File

@@ -127,7 +127,7 @@ fn extension_main_logic(data: ExtensionData) {
}; };
let mut tia_ctx = TIACtxImpl{ let mut tia_ctx = TIACtxImpl{
lazy: &mut lazy_mems, lazy: &mut lazy_mems,
ctx: ctx.clone(), sys: ctx.clone(),
basepath: &[], basepath: &[],
path: Substack::Bottom, path: Substack::Bottom,
}; };
@@ -156,9 +156,12 @@ fn extension_main_logic(data: ExtensionData) {
Some(MemberRecord::Gen(path, cb)) => (path, cb), Some(MemberRecord::Gen(path, cb)) => (path, cb),
}; };
let tree = cb.build(path.clone()); let tree = cb.build(path.clone());
let ctx = SysCtx::new(*sys_id, &sys.cted, &logger, req.reqnot()); req.handle(get_tree, &tree.into_api(&mut TIACtxImpl{
let reply_tree = tree.into_api(&mut TIACtxImpl{ ctx: ctx.clone(), lazy, path: Substack::Bottom, basepath: &path }); sys: SysCtx::new(*sys_id, &sys.cted, &logger, req.reqnot()),
req.handle(get_tree, &reply_tree) path: Substack::Bottom,
basepath: &path,
lazy,
}))
} }
api::HostExtReq::VfsReq(api::VfsReq::GetVfs(get_vfs@api::GetVfs(sys_id))) => { api::HostExtReq::VfsReq(api::VfsReq::GetVfs(get_vfs@api::GetVfs(sys_id))) => {
let systems_g = systems.lock().unwrap(); let systems_g = systems.lock().unwrap();

View File

@@ -1,4 +1,3 @@
use orchid_base::interner::Tok;
use std::borrow::Cow; use std::borrow::Cow;
use std::collections::HashMap; use std::collections::HashMap;
use std::io; use std::io;
@@ -9,6 +8,7 @@ use lazy_static::lazy_static;
use never::Never; use never::Never;
use orchid_api_traits::Encode; use orchid_api_traits::Encode;
use orchid_base::error::OrcRes; use orchid_base::error::OrcRes;
use orchid_base::interner::Tok;
use orchid_base::name::Sym; use orchid_base::name::Sym;
use trait_set::trait_set; use trait_set::trait_set;
@@ -27,12 +27,12 @@ pub trait ExprFunc<I, O>: Clone + Send + Sync + 'static {
fn apply(&self, v: Vec<ExprHandle>) -> OrcRes<GenExpr>; fn apply(&self, v: Vec<ExprHandle>) -> OrcRes<GenExpr>;
} }
lazy_static!{ lazy_static! {
static ref FUNS: Mutex<HashMap<Sym, (u8, Arc<dyn FunCB>)>> = Mutex::default(); static ref FUNS: Mutex<HashMap<Sym, (u8, Arc<dyn FunCB>)>> = Mutex::default();
} }
#[derive(Clone)] #[derive(Clone)]
pub(crate) struct Fun{ pub(crate) struct Fun {
path: Sym, path: Sym,
args: Vec<ExprHandle>, args: Vec<ExprHandle>,
arity: u8, arity: u8,
@@ -64,8 +64,8 @@ impl OwnedAtom for Fun {
if new_args.len() == self.arity.into() { if new_args.len() == self.arity.into() {
(self.fun)(new_args).to_expr() (self.fun)(new_args).to_expr()
} else { } else {
Self { Self { args: new_args, arity: self.arity, fun: self.fun.clone(), path: self.path.clone() }
args: new_args, arity: self.arity, fun: self.fun.clone(), path: self.path.clone() }.to_expr() .to_expr()
} }
} }
fn call(self, arg: ExprHandle) -> GenExpr { self.call_ref(arg) } fn call(self, arg: ExprHandle) -> GenExpr { self.call_ref(arg) }
@@ -83,10 +83,10 @@ impl OwnedAtom for Fun {
mod expr_func_derives { mod expr_func_derives {
use orchid_base::error::OrcRes; use orchid_base::error::OrcRes;
use crate::func_atom::GenExpr;
use super::ExprFunc; use super::ExprFunc;
use crate::conv::{TryFromExpr, ToExpr}; use crate::conv::{ToExpr, TryFromExpr};
use crate::func_atom::ExprHandle; use crate::func_atom::{ExprHandle, GenExpr};
macro_rules! expr_func_derive { macro_rules! expr_func_derive {
($arity: tt, $($t:ident),*) => { ($arity: tt, $($t:ident),*) => {

View File

@@ -55,17 +55,12 @@ pub trait Lexer: Send + Sync + Sized + Default + 'static {
pub trait DynLexer: Send + Sync + 'static { pub trait DynLexer: Send + Sync + 'static {
fn char_filter(&self) -> &'static [RangeInclusive<char>]; fn char_filter(&self) -> &'static [RangeInclusive<char>];
fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>) fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)>;
-> OrcRes<(&'a str, GenTokTree<'a>)>;
} }
impl<T: Lexer> DynLexer for T { impl<T: Lexer> DynLexer for T {
fn char_filter(&self) -> &'static [RangeInclusive<char>] { T::CHAR_FILTER } fn char_filter(&self) -> &'static [RangeInclusive<char>] { T::CHAR_FILTER }
fn lex<'a>( fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)> {
&self,
tail: &'a str,
ctx: &'a LexContext<'a>,
) -> OrcRes<(&'a str, GenTokTree<'a>)> {
T::lex(tail, ctx) T::lex(tail, ctx)
} }
} }

View File

@@ -34,7 +34,9 @@ pub trait DynSystemCard: Send + Sync + 'static {
/// Atoms supported by this package which may appear in all extensions. /// 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 /// 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) /// marks whether it belongs to this package (0) or the importer (1)
fn general_atoms() -> &'static [Option<&'static dyn AtomDynfo>] { &[/*Some(Fun::INFO)*/] } fn general_atoms() -> &'static [Option<&'static dyn AtomDynfo>] {
&[/*Some(Fun::INFO)*/]
}
pub fn atom_info_for( pub fn atom_info_for(
sys: &(impl DynSystemCard + ?Sized), sys: &(impl DynSystemCard + ?Sized),

View File

@@ -8,8 +8,7 @@ use itertools::Itertools;
use orchid_base::interner::{intern, Tok}; use orchid_base::interner::{intern, Tok};
use orchid_base::location::Pos; use orchid_base::location::Pos;
use orchid_base::name::Sym; use orchid_base::name::Sym;
use orchid_base::tree::{ttv_to_api, TokTree, Token}; use orchid_base::tree::{TokTree, Token};
use ordered_float::NotNan;
use substack::Substack; use substack::Substack;
use trait_set::trait_set; use trait_set::trait_set;
@@ -28,13 +27,6 @@ pub fn do_extra(f: &AtomFactory, r: Range<u32>, ctx: SysCtx) -> api::TokenTree {
api::TokenTree { range: r, token: api::Token::Atom(f.clone().build(ctx)) } api::TokenTree { range: r, token: api::Token::Atom(f.clone().build(ctx)) }
} }
#[derive(Clone)]
pub struct GenMacro {
pub pattern: Vec<GenTokTree<'static>>,
pub priority: NotNan<f64>,
pub template: Vec<GenTokTree<'static>>,
}
pub struct GenItem { pub struct GenItem {
pub item: GenItemKind, pub item: GenItemKind,
pub comments: Vec<(String, Pos)>, pub comments: Vec<(String, Pos)>,
@@ -43,11 +35,6 @@ pub struct GenItem {
impl GenItem { impl GenItem {
pub fn into_api(self, ctx: &mut impl TreeIntoApiCtx) -> api::Item { pub fn into_api(self, ctx: &mut impl TreeIntoApiCtx) -> api::Item {
let kind = match self.item { let kind = match self.item {
GenItemKind::Rule(m) => api::ItemKind::Rule(api::Macro {
pattern: ttv_to_api(m.pattern, &mut |f, r| do_extra(f, r, ctx.sys())),
priority: m.priority,
template: ttv_to_api(m.template, &mut |f, r| do_extra(f, r, ctx.sys())),
}),
GenItemKind::Raw(item) => api::ItemKind::Raw(Vec::from_iter( GenItemKind::Raw(item) => api::ItemKind::Raw(Vec::from_iter(
item.into_iter().map(|t| t.to_api(&mut |f, r| do_extra(f, r, ctx.sys()))), item.into_iter().map(|t| t.to_api(&mut |f, r| do_extra(f, r, ctx.sys()))),
)), )),
@@ -84,21 +71,9 @@ pub fn root_mod(
} }
pub fn fun<I, O>(exported: bool, name: &str, xf: impl ExprFunc<I, O>) -> GenItem { pub fn fun<I, O>(exported: bool, name: &str, xf: impl ExprFunc<I, O>) -> GenItem {
let fac = LazyMemberFactory::new(move |sym| GenMemberKind::Const(Fun::new(sym, xf).to_expr())); let fac = LazyMemberFactory::new(move |sym| GenMemberKind::Const(Fun::new(sym, xf).to_expr()));
let mem = GenMember{ exported, name: intern(name), kind: GenMemberKind::Lazy(fac) }; let mem = GenMember { exported, name: intern(name), kind: GenMemberKind::Lazy(fac) };
GenItemKind::Member(mem).at(Pos::Inherit) GenItemKind::Member(mem).at(Pos::Inherit)
} }
pub fn rule(
priority: f64,
pat: impl IntoIterator<Item = GenTokTree<'static>>,
tpl: impl IntoIterator<Item = GenTokTree<'static>>,
) -> GenItem {
GenItemKind::Rule(GenMacro {
pattern: pat.into_iter().collect(),
priority: NotNan::new(priority).expect("Rule created with NaN prio"),
template: tpl.into_iter().collect(),
})
.at(Pos::Inherit)
}
pub fn comments<'a>(cmts: impl IntoIterator<Item = &'a str>, mut val: GenItem) -> GenItem { pub fn comments<'a>(cmts: impl IntoIterator<Item = &'a str>, mut val: GenItem) -> GenItem {
val.comments.extend(cmts.into_iter().map(|c| (c.to_string(), Pos::Inherit))); val.comments.extend(cmts.into_iter().map(|c| (c.to_string(), Pos::Inherit)));
@@ -122,7 +97,6 @@ impl Clone for LazyMemberFactory {
pub enum GenItemKind { pub enum GenItemKind {
Member(GenMember), Member(GenMember),
Raw(Vec<GenTokTree<'static>>), Raw(Vec<GenTokTree<'static>>),
Rule(GenMacro),
} }
impl GenItemKind { impl GenItemKind {
pub fn at(self, position: Pos) -> GenItem { pub fn at(self, position: Pos) -> GenItem {
@@ -140,7 +114,7 @@ impl GenMember {
api::Member { api::Member {
name: self.name.marker(), name: self.name.marker(),
exported: self.exported, exported: self.exported,
kind: self.kind.into_api(&mut ctx.push_path(self.name)) kind: self.kind.into_api(&mut ctx.push_path(self.name)),
} }
} }
} }
@@ -170,20 +144,20 @@ pub trait TreeIntoApiCtx {
} }
pub struct TIACtxImpl<'a, 'b> { pub struct TIACtxImpl<'a, 'b> {
pub ctx: SysCtx, pub sys: SysCtx,
pub basepath: &'a [Tok<String>], pub basepath: &'a [Tok<String>],
pub path: Substack<'a, Tok<String>>, pub path: Substack<'a, Tok<String>>,
pub lazy: &'b mut HashMap<api::TreeId, MemberRecord>, pub lazy: &'b mut HashMap<api::TreeId, MemberRecord>,
} }
impl<'a, 'b> TreeIntoApiCtx for TIACtxImpl<'a, 'b> { impl<'a, 'b> TreeIntoApiCtx for TIACtxImpl<'a, 'b> {
fn sys(&self) -> SysCtx { self.ctx.clone() } fn sys(&self) -> SysCtx { self.sys.clone() }
fn push_path(&mut self, seg: Tok<String>) -> impl TreeIntoApiCtx { fn push_path(&mut self, seg: Tok<String>) -> impl TreeIntoApiCtx {
TIACtxImpl { TIACtxImpl {
ctx: self.ctx.clone(), sys: self.sys.clone(),
lazy: self.lazy, lazy: self.lazy,
basepath: self.basepath, basepath: self.basepath,
path: self.path.push(seg) path: self.path.push(seg),
} }
} }
fn with_lazy(&mut self, fac: LazyMemberFactory) -> api::TreeId { fn with_lazy(&mut self, fac: LazyMemberFactory) -> api::TreeId {

View File

@@ -1,4 +1,3 @@
use orchid_base::intern;
use std::collections::VecDeque; use std::collections::VecDeque;
use std::num::NonZero; use std::num::NonZero;
use std::ops::{Deref, Range}; use std::ops::{Deref, Range};
@@ -14,12 +13,12 @@ use itertools::Itertools;
use lazy_static::lazy_static; use lazy_static::lazy_static;
use orchid_api_traits::{enc_vec, Decode, Request}; use orchid_api_traits::{enc_vec, Decode, Request};
use orchid_base::char_filter::char_filter_match; use orchid_base::char_filter::char_filter_match;
use orchid_base::clone;
use orchid_base::error::{errv_from_apiv, mk_err, OrcRes}; use orchid_base::error::{errv_from_apiv, mk_err, OrcRes};
use orchid_base::interner::{deintern, intern, Tok}; use orchid_base::interner::{deintern, intern, Tok};
use orchid_base::logging::Logger; use orchid_base::logging::Logger;
use orchid_base::reqnot::{ReqNot, Requester as _}; use orchid_base::reqnot::{ReqNot, Requester as _};
use orchid_base::tree::{ttv_from_api, AtomInTok}; use orchid_base::tree::{ttv_from_api, AtomInTok};
use orchid_base::{clone, intern};
use ordered_float::NotNan; use ordered_float::NotNan;
use substack::{Stackframe, Substack}; use substack::{Stackframe, Substack};
@@ -135,9 +134,7 @@ pub struct ExtensionData {
logger: Logger, logger: Logger,
} }
impl Drop for ExtensionData { impl Drop for ExtensionData {
fn drop(&mut self) { fn drop(&mut self) { self.reqnot.notify(api::HostExtNotif::Exit); }
self.reqnot.notify(api::HostExtNotif::Exit);
}
} }
fn acq_expr(sys: api::SysId, extk: api::ExprTicket) { fn acq_expr(sys: api::SysId, extk: api::ExprTicket) {
@@ -156,7 +153,6 @@ fn rel_expr(sys: api::SysId, extk: api::ExprTicket) {
#[derive(Clone)] #[derive(Clone)]
pub struct Extension(Arc<ExtensionData>); pub struct Extension(Arc<ExtensionData>);
impl Extension { impl Extension {
pub fn new_process(port: Arc<dyn ExtensionPort>, logger: Logger) -> io::Result<Self> { pub fn new_process(port: Arc<dyn ExtensionPort>, logger: Logger) -> io::Result<Self> {
port.send(&enc_vec(&api::HostHeader { log_strategy: logger.strat() })); port.send(&enc_vec(&api::HostHeader { log_strategy: logger.strat() }));
let header_reply = port.receive().expect("Extension exited immediately"); let header_reply = port.receive().expect("Extension exited immediately");
@@ -187,7 +183,7 @@ impl Extension {
api::IntReq::ExternStr(si) => req.handle(si, &deintern(si.0).arc()), api::IntReq::ExternStr(si) => req.handle(si, &deintern(si.0).arc()),
api::IntReq::ExternStrv(vi) => api::IntReq::ExternStrv(vi) =>
req.handle(vi, &Arc::new(deintern(vi.0).iter().map(|t| t.marker()).collect_vec())), req.handle(vi, &Arc::new(deintern(vi.0).iter().map(|t| t.marker()).collect_vec())),
} },
api::ExtHostReq::Fwd(fw @ api::Fwd(atom, _body)) => { api::ExtHostReq::Fwd(fw @ api::Fwd(atom, _body)) => {
let sys = System::resolve(atom.owner).unwrap(); let sys = System::resolve(atom.owner).unwrap();
req.handle(fw, &sys.reqnot().request(api::Fwded(fw.0.clone(), fw.1.clone()))) req.handle(fw, &sys.reqnot().request(api::Fwded(fw.0.clone(), fw.1.clone())))
@@ -199,23 +195,23 @@ impl Extension {
req_in.send(ReqPair(sl.clone(), rep_in)).unwrap(); req_in.send(ReqPair(sl.clone(), rep_in)).unwrap();
req.handle(sl, &rep_out.recv().unwrap()) req.handle(sl, &rep_out.recv().unwrap())
}, },
api::ExtHostReq::ExprReq(api::ExprReq::Inspect(ins@api::Inspect(tk))) => { api::ExtHostReq::ExprReq(api::ExprReq::Inspect(ins @ api::Inspect(tk))) => {
let expr = RtExpr::resolve(*tk); let expr = RtExpr::resolve(*tk);
req.handle(ins, &api::Details{ req.handle(ins, &api::Details {
refcount: 1, refcount: 1,
expr: api::Expr{ expr: api::Expr {
location: api::Location::None, location: api::Location::None,
clause: api::Clause::Bottom(vec![ clause: api::Clause::Bottom(vec![
mk_err( mk_err(
intern!(str: "Unsupported"), intern!(str: "Unsupported"),
"Inspecting clauses is unsupported at the moment", "Inspecting clauses is unsupported at the moment",
[] [],
) )
.to_api() .to_api(),
]) ]),
} },
}) })
} },
}, },
), ),
systems: eh.systems.into_iter().map(|decl| SystemCtor { decl, ext: weak.clone() }).collect(), systems: eh.systems.into_iter().map(|decl| SystemCtor { decl, ext: weak.clone() }).collect(),
@@ -223,12 +219,14 @@ impl Extension {
let weak = Arc::downgrade(&ret); let weak = Arc::downgrade(&ret);
thread::Builder::new() thread::Builder::new()
.name(format!("host-end:{}", eh.name)) .name(format!("host-end:{}", eh.name))
.spawn::<_, Option<()>>(move || loop { .spawn::<_, Option<()>>(move || {
loop {
// thread will exit if either the peer exits or the extension object is dropped. // thread will exit if either the peer exits or the extension object is dropped.
// It holds a strong reference to the port so the port's destructor will not be called // It holds a strong reference to the port so the port's destructor will not be
// until the // called until the
let msg = port.receive()?; let msg = port.receive()?;
weak.upgrade()?.reqnot.receive(msg); weak.upgrade()?.reqnot.receive(msg);
}
}) })
.unwrap(); .unwrap();
Ok(Self(ret)) Ok(Self(ret))

View File

@@ -7,7 +7,7 @@ use orchid_base::intern;
use orchid_base::interner::{deintern, intern, Tok}; use orchid_base::interner::{deintern, intern, Tok};
use orchid_base::location::Pos; use orchid_base::location::Pos;
use orchid_base::parse::{name_char, name_start, op_char, unrep_space}; use orchid_base::parse::{name_char, name_start, op_char, unrep_space};
use orchid_base::tokens::{OwnedPh, PARENS}; use orchid_base::tokens::PARENS;
use crate::api; use crate::api;
use crate::extension::{AtomHand, System}; use crate::extension::{AtomHand, System};
@@ -162,7 +162,6 @@ pub fn lex_once(ctx: &mut LexCtx) -> OrcRes<ParsTokTree> {
fn tt_to_owned(api: &api::TokenTree, ctx: &mut LexCtx<'_>) -> ParsTokTree { fn tt_to_owned(api: &api::TokenTree, ctx: &mut LexCtx<'_>) -> ParsTokTree {
let tok = match &api.token { let tok = match &api.token {
api::Token::Atom(atom) => ParsTok::Atom(AtomHand::from_api(atom.clone())), api::Token::Atom(atom) => ParsTok::Atom(AtomHand::from_api(atom.clone())),
api::Token::Ph(ph) => ParsTok::Ph(OwnedPh::from_api(ph.clone())),
api::Token::Bottom(err) => ParsTok::Bottom(err.iter().map(OrcErr::from_api).collect()), api::Token::Bottom(err) => ParsTok::Bottom(err.iter().map(OrcErr::from_api).collect()),
api::Token::Lambda(arg) => api::Token::Lambda(arg) =>
ParsTok::LambdaHead(arg.iter().map(|t| tt_to_owned(t, ctx)).collect()), ParsTok::LambdaHead(arg.iter().map(|t| tt_to_owned(t, ctx)).collect()),

View File

@@ -5,5 +5,5 @@ pub mod expr;
pub mod extension; pub mod extension;
pub mod lex; pub mod lex;
pub mod parse; pub mod parse;
pub mod tree;
pub mod subprocess; pub mod subprocess;
pub mod tree;

View File

@@ -7,12 +7,13 @@ use orchid_base::intern;
use orchid_base::interner::Tok; use orchid_base::interner::Tok;
use orchid_base::location::Pos; use orchid_base::location::Pos;
use orchid_base::parse::{ use orchid_base::parse::{
expect_end, expect_tok, line_items, parse_multiname, strip_fluff, try_pop_no_fluff, Comment, CompName, Snippet expect_end, line_items, parse_multiname, strip_fluff, try_pop_no_fluff, Comment, CompName,
Snippet,
}; };
use orchid_base::tree::{Paren, TokTree, Token}; use orchid_base::tree::{Paren, TokTree, Token};
use crate::extension::{AtomHand, System}; use crate::extension::{AtomHand, System};
use crate::tree::{Item, ItemKind, Macro, Member, MemberKind, Module, ParsTokTree}; use crate::tree::{Item, ItemKind, Member, MemberKind, Module, ParsTokTree};
type ParsSnippet<'a> = Snippet<'a, 'static, AtomHand, Never>; type ParsSnippet<'a> = Snippet<'a, 'static, AtomHand, Never>;
@@ -115,26 +116,21 @@ pub fn parse_item_2(
} else if discr == intern!(str: "const") { } else if discr == intern!(str: "const") {
let (name, val) = parse_const(tail)?; let (name, val) = parse_const(tail)?;
ItemKind::Member(Member::new(exported, name, MemberKind::Const(val))) ItemKind::Member(Member::new(exported, name, MemberKind::Const(val)))
} else if discr == intern!(str: "macro") {
ItemKind::Rule(parse_macro(tail)?)
} else if let Some(sys) = ctx.systems().find(|s| s.can_parse(discr.clone())) { } else if let Some(sys) = ctx.systems().find(|s| s.can_parse(discr.clone())) {
let line = sys.parse(tail.to_vec())?; let line = sys.parse(tail.to_vec())?;
return parse_items(ctx, Snippet::new(tail.prev(), &line)) return parse_items(ctx, Snippet::new(tail.prev(), &line));
} else { } else {
let ext_lines = ctx.systems().flat_map(System::line_types).join(", "); let ext_lines = ctx.systems().flat_map(System::line_types).join(", ");
return Err(vec![mk_err( return Err(vec![mk_err(
intern!(str: "Unrecognized line type"), intern!(str: "Unrecognized line type"),
format!("Line types are: const, mod, macro, grammar, {ext_lines}"), format!("Line types are: const, mod, macro, grammar, {ext_lines}"),
[Pos::Range(tail.prev().range.clone()).into()] [Pos::Range(tail.prev().range.clone()).into()],
)]) )]);
}; };
Ok(vec![Item { comments, pos: Pos::Range(tail.pos()), kind }]) Ok(vec![Item { comments, pos: Pos::Range(tail.pos()), kind }])
} }
pub fn parse_module( pub fn parse_module(ctx: &impl ParseCtx, tail: ParsSnippet) -> OrcRes<(Tok<String>, Module)> {
ctx: &impl ParseCtx,
tail: ParsSnippet,
) -> OrcRes<(Tok<String>, Module)> {
let (name, tail) = match try_pop_no_fluff(tail)? { let (name, tail) = match try_pop_no_fluff(tail)? {
(TokTree { tok: Token::Name(n), .. }, tail) => (n.clone(), tail), (TokTree { tok: Token::Name(n), .. }, tail) => (n.clone(), tail),
(tt, _) => (tt, _) =>
@@ -179,9 +175,3 @@ pub fn parse_const(tail: ParsSnippet) -> OrcRes<(Tok<String>, Vec<ParsTokTree>)>
try_pop_no_fluff(tail)?; try_pop_no_fluff(tail)?;
Ok((name, tail.iter().flat_map(strip_fluff).collect_vec())) Ok((name, tail.iter().flat_map(strip_fluff).collect_vec()))
} }
pub fn parse_macro(tail: ParsSnippet) -> OrcRes<Macro> {
let tail = expect_tok(tail, intern!(str: "prio"))?;
let (prio, tail) = ((), ());
todo!();
}

View File

@@ -1,6 +1,10 @@
use std::{io::{self, BufRead as _}, path::PathBuf, process, sync::Mutex, thread}; use std::io::{self, BufRead as _};
use std::path::PathBuf;
use std::sync::Mutex;
use std::{process, thread};
use orchid_base::{logging::Logger, msg::{recv_msg, send_msg}}; use orchid_base::logging::Logger;
use orchid_base::msg::{recv_msg, send_msg};
use crate::extension::ExtensionPort; use crate::extension::ExtensionPort;
@@ -21,9 +25,7 @@ impl Subprocess {
let stdin = child.stdin.take().unwrap(); let stdin = child.stdin.take().unwrap();
let stdout = child.stdout.take().unwrap(); let stdout = child.stdout.take().unwrap();
let child_stderr = child.stderr.take().unwrap(); let child_stderr = child.stderr.take().unwrap();
thread::Builder::new() thread::Builder::new().name(format!("stderr-fwd:{prog}")).spawn(move || {
.name(format!("stderr-fwd:{prog}"))
.spawn(move || {
let mut reader = io::BufReader::new(child_stderr); let mut reader = io::BufReader::new(child_stderr);
loop { loop {
let mut buf = String::new(); let mut buf = String::new();
@@ -33,13 +35,11 @@ impl Subprocess {
logger.log(buf); logger.log(buf);
} }
})?; })?;
Ok(Self{ child: Mutex::new(child), stdin: Mutex::new(stdin), stdout: Mutex::new(stdout) }) Ok(Self { child: Mutex::new(child), stdin: Mutex::new(stdin), stdout: Mutex::new(stdout) })
} }
} }
impl Drop for Subprocess { impl Drop for Subprocess {
fn drop(&mut self) { fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); }
self.child.lock().unwrap().wait().expect("Extension exited with error");
}
} }
impl ExtensionPort for Subprocess { impl ExtensionPort for Subprocess {
fn send(&self, msg: &[u8]) { send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap() } fn send(&self, msg: &[u8]) { send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap() }

View File

@@ -8,7 +8,6 @@ use orchid_base::location::Pos;
use orchid_base::name::Sym; use orchid_base::name::Sym;
use orchid_base::parse::{Comment, CompName}; use orchid_base::parse::{Comment, CompName};
use orchid_base::tree::{ttv_from_api, TokTree, Token}; use orchid_base::tree::{ttv_from_api, TokTree, Token};
use ordered_float::NotNan;
use crate::api; use crate::api;
use crate::expr::RtExpr; use crate::expr::RtExpr;
@@ -29,7 +28,6 @@ pub enum ItemKind {
Raw(Vec<ParsTokTree>), Raw(Vec<ParsTokTree>),
Member(Member), Member(Member),
Export(Tok<String>), Export(Tok<String>),
Rule(Macro),
Import(CompName), Import(CompName),
} }
@@ -38,7 +36,6 @@ impl Item {
let kind = match tree.kind { let kind = match tree.kind {
api::ItemKind::Raw(tokv) => ItemKind::Raw(ttv_from_api(tokv, &mut ())), api::ItemKind::Raw(tokv) => ItemKind::Raw(ttv_from_api(tokv, &mut ())),
api::ItemKind::Member(m) => ItemKind::Member(Member::from_api(m, sys)), api::ItemKind::Member(m) => ItemKind::Member(Member::from_api(m, sys)),
api::ItemKind::Rule(r) => ItemKind::Rule(Macro::from_api(r)),
api::ItemKind::Import(i) => ItemKind::Import(CompName::from_api(i)), api::ItemKind::Import(i) => ItemKind::Import(CompName::from_api(i)),
api::ItemKind::Export(e) => ItemKind::Export(deintern(e)), api::ItemKind::Export(e) => ItemKind::Export(deintern(e)),
}; };
@@ -95,22 +92,6 @@ impl Module {
} }
} }
#[derive(Debug)]
pub struct Macro {
pub priority: NotNan<f64>,
pub pattern: Vec<ParsTokTree>,
pub template: Vec<ParsTokTree>,
}
impl Macro {
pub fn from_api(m: api::Macro) -> Self {
Self {
priority: m.priority,
pattern: ttv_from_api(m.pattern, &mut ()),
template: ttv_from_api(m.template, &mut ()),
}
}
}
#[derive(Debug)] #[derive(Debug)]
pub struct LazyMemberHandle(api::TreeId, System); pub struct LazyMemberHandle(api::TreeId, System);
impl LazyMemberHandle { impl LazyMemberHandle {

View File

@@ -1,8 +1,8 @@
use std::env; use std::env;
use std::ffi::OsStr; use std::ffi::OsStr;
use std::fs::File; use std::fs::{DirEntry, File};
use std::io::{self, Read}; use std::io::{self, Read};
use std::path::PathBuf; use std::path::Path;
use std::process::ExitCode; use std::process::ExitCode;
use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::atomic::{AtomicBool, Ordering};
@@ -26,22 +26,8 @@ pub static EXIT_OK: AtomicBool = AtomicBool::new(true);
fn main() -> io::Result<ExitCode> { fn main() -> io::Result<ExitCode> {
let args = Args::parse(); let args = Args::parse();
match args.command { match args.command {
Commands::CheckApiRefs => check_api_refs(&args, env::current_dir()?)?, Commands::CheckApiRefs => walk_wsp(&mut |_| Ok(true), &mut |file| {
} if file.path().extension() == Some(OsStr::new("rs")) || file.file_name() == "lib.rs" {
Ok(if EXIT_OK.load(Ordering::Relaxed) { ExitCode::SUCCESS } else { ExitCode::FAILURE })
}
fn check_api_refs(args: &Args, dir: PathBuf) -> io::Result<()> {
for file in dir.read_dir()?.collect::<Result<Vec<_>, _>>()? {
if args.verbose {
eprintln!("Checking {}", file.path().to_string_lossy());
}
if file.metadata()?.is_dir() {
check_api_refs(args, file.path())?
}
if file.path().extension() != Some(OsStr::new("rs")) || file.file_name() == "lib.rs" {
continue;
}
let mut contents = String::new(); let mut contents = String::new();
File::open(file.path())?.read_to_string(&mut contents)?; File::open(file.path())?.read_to_string(&mut contents)?;
for (l, line) in contents.lines().enumerate() { for (l, line) in contents.lines().enumerate() {
@@ -56,4 +42,27 @@ fn check_api_refs(args: &Args, dir: PathBuf) -> io::Result<()> {
} }
} }
Ok(()) Ok(())
})?,
}
Ok(if EXIT_OK.load(Ordering::Relaxed) { ExitCode::SUCCESS } else { ExitCode::FAILURE })
}
fn walk_wsp(
dir_filter: &mut impl FnMut(&DirEntry) -> io::Result<bool>,
file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>,
) -> io::Result<()> {
return recurse(&env::current_dir()?, dir_filter, file_handler);
fn recurse(
dir: &Path,
dir_filter: &mut impl FnMut(&DirEntry) -> io::Result<bool>,
file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>,
) -> io::Result<()> {
for file in dir.read_dir()?.collect::<Result<Vec<_>, _>>()? {
if file.metadata()?.is_dir() && dir_filter(&file)? {
recurse(&file.path(), dir_filter, file_handler)?;
}
file_handler(file)?;
}
Ok(())
}
} }