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:
22
.zed/settings.json
Normal file
22
.zed/settings.json
Normal 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
35
Cargo.lock
generated
@@ -236,12 +236,6 @@ version = "0.2.8"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6051f239ecec86fde3410901ab7860d458d160371533842974fc61f96d15879b"
|
||||
|
||||
[[package]]
|
||||
name = "convert_case"
|
||||
version = "0.4.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "6245d59a3e82a7fc217c5828a6692dbc6dfb63a0c8c90495621f7b9d79704a0e"
|
||||
|
||||
[[package]]
|
||||
name = "cpufeatures"
|
||||
version = "0.2.12"
|
||||
@@ -307,19 +301,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "digest"
|
||||
version = "0.10.7"
|
||||
@@ -513,7 +494,6 @@ checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92"
|
||||
name = "orchid-api"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"derive_more",
|
||||
"orchid-api-derive",
|
||||
"orchid-api-traits",
|
||||
"ordered-float",
|
||||
@@ -858,15 +838,6 @@ dependencies = [
|
||||
"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]]
|
||||
name = "ryu"
|
||||
version = "1.0.18"
|
||||
@@ -888,12 +859,6 @@ version = "4.1.0"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "1c107b6f4780854c8b126e228ea8869f4d7b71260f962fefb57b996b8959ba6b"
|
||||
|
||||
[[package]]
|
||||
name = "semver"
|
||||
version = "1.0.22"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "92d43fe69e652f3df9bdc2b85b2854a0825b86e4fb76bc44d945137d053639ca"
|
||||
|
||||
[[package]]
|
||||
name = "serde"
|
||||
version = "1.0.204"
|
||||
|
||||
@@ -25,5 +25,3 @@ pub fn hierarchy(input: TokenStream) -> TokenStream { hierarchy::derive(input) }
|
||||
pub fn coding(input: TokenStream) -> TokenStream {
|
||||
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
|
||||
|
||||
@@ -8,7 +8,7 @@ use std::rc::Rc;
|
||||
use std::sync::Arc;
|
||||
|
||||
use never::Never;
|
||||
use ordered_float::{FloatCore, NotNan};
|
||||
use ordered_float::NotNan;
|
||||
|
||||
use crate::encode_enum;
|
||||
|
||||
@@ -29,10 +29,10 @@ pub trait Coding: Encode + Decode + Clone {
|
||||
impl<T: Encode + Decode + Clone> Coding for T {}
|
||||
|
||||
macro_rules! num_impl {
|
||||
($number:ty, $size:expr) => {
|
||||
($number:ty) => {
|
||||
impl Decode for $number {
|
||||
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();
|
||||
<$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!(u64);
|
||||
@@ -57,8 +54,6 @@ num_impl!(i64);
|
||||
num_impl!(i32);
|
||||
num_impl!(i16);
|
||||
num_impl!(i8);
|
||||
num_impl!(f64, 8);
|
||||
num_impl!(f32, 4);
|
||||
|
||||
macro_rules! nonzero_impl {
|
||||
($name:ty) => {
|
||||
@@ -85,14 +80,26 @@ nonzero_impl!(std::num::NonZeroI128);
|
||||
impl<'a, T: Encode + ?Sized> Encode for &'a T {
|
||||
fn encode<W: Write + ?Sized>(&self, write: &mut W) { (**self).encode(write) }
|
||||
}
|
||||
impl<T: Decode + FloatCore> Decode for NotNan<T> {
|
||||
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
|
||||
NotNan::new(T::decode(read)).expect("Float was NaN")
|
||||
}
|
||||
}
|
||||
impl<T: Encode + FloatCore> Encode for NotNan<T> {
|
||||
fn encode<W: Write + ?Sized>(&self, write: &mut W) { self.as_ref().encode(write) }
|
||||
macro_rules! float_impl {
|
||||
($t:ty, $size:expr) => {
|
||||
impl Decode for NotNan<$t> {
|
||||
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
|
||||
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")
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
float_impl!(f64, 8);
|
||||
float_impl!(f32, 4);
|
||||
|
||||
impl Decode for String {
|
||||
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
|
||||
let len = u64::decode(read).try_into().unwrap();
|
||||
|
||||
@@ -4,6 +4,6 @@ mod hierarchy;
|
||||
mod relations;
|
||||
|
||||
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 relations::{Channel, MsgSet, Request};
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
use crate::helpers::enc_vec;
|
||||
|
||||
use super::coding::Coding;
|
||||
use crate::helpers::enc_vec;
|
||||
|
||||
pub trait Request: Coding + Sized + Send + 'static {
|
||||
type Response: Coding + Send + 'static;
|
||||
|
||||
@@ -9,4 +9,3 @@ edition = "2021"
|
||||
ordered-float = "4.2.0"
|
||||
orchid-api-traits = { version = "0.1.0", path = "../orchid-api-traits" }
|
||||
orchid-api-derive = { version = "0.1.0", path = "../orchid-api-derive" }
|
||||
derive_more = "0.99.17"
|
||||
|
||||
@@ -75,8 +75,6 @@ pub enum Clause {
|
||||
/// the atom must be trivial. This is always a newly constructed atom, if you
|
||||
/// want to reference an existing atom, use the corresponding [ExprTicket].
|
||||
/// 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),
|
||||
/// An atom, specifically an atom that already exists. This form is only ever
|
||||
/// returned from [Inspect], and it's borrowed from the expression being
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
mod atom;
|
||||
pub use atom::{
|
||||
Atom, AtomData, AtomDrop, AtomId, AtomPrint, AtomReq, AtomSame, CallRef, Command, FinalCall, Fwd,
|
||||
Fwded, LocalAtom, NextStep, DeserAtom, SerializeAtom
|
||||
Atom, AtomData, AtomDrop, AtomId, AtomPrint, AtomReq, AtomSame, CallRef, Command, DeserAtom,
|
||||
FinalCall, Fwd, Fwded, LocalAtom, NextStep, SerializeAtom,
|
||||
};
|
||||
mod error;
|
||||
pub use error::{ErrId, ErrLocation, OrcError, OrcResult};
|
||||
@@ -25,11 +25,11 @@ pub use proto::{
|
||||
HostExtNotif, HostExtReq, HostHeader, HostMsgSet, Ping,
|
||||
};
|
||||
mod system;
|
||||
pub use system::{SysReq, NewSystem, SysDeclId, SysId, SystemDecl, SystemDrop, SystemInst};
|
||||
pub use system::{NewSystem, SysDeclId, SysId, SysReq, SystemDecl, SystemDrop, SystemInst};
|
||||
mod tree;
|
||||
pub use tree::{
|
||||
CompName, GetMember, Item, ItemKind, Macro, Member, MemberKind, Module, Paren, Placeholder,
|
||||
PlaceholderKind, Token, TokenTree, TreeId, TreeTicket,
|
||||
CompName, GetMember, Item, ItemKind, Member, MemberKind, Module, Paren, Token, TokenTree, TreeId,
|
||||
TreeTicket,
|
||||
};
|
||||
mod vfs;
|
||||
pub use vfs::{EagerVfs, GetVfs, Loaded, VfsId, VfsRead, VfsReq};
|
||||
|
||||
@@ -146,7 +146,7 @@ impl MsgSet for HostMsgSet {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use orchid_api_traits::enc_vec;
|
||||
use ordered_float::NotNan;
|
||||
use ordered_float::NotNan;
|
||||
use system::{SysDeclId, SystemDecl};
|
||||
|
||||
use super::*;
|
||||
|
||||
@@ -4,7 +4,6 @@ use std::sync::Arc;
|
||||
|
||||
use orchid_api_derive::{Coding, Hierarchy};
|
||||
use orchid_api_traits::Request;
|
||||
use ordered_float::NotNan;
|
||||
|
||||
use crate::error::OrcError;
|
||||
use crate::interner::{TStr, TStrv};
|
||||
@@ -41,9 +40,6 @@ pub enum Token {
|
||||
BR,
|
||||
/// ( Round parens ), [ Square brackets ] or { Curly braces }
|
||||
S(Paren, Vec<TokenTree>),
|
||||
/// A placeholder in a macro. This variant is forbidden everywhere outside
|
||||
/// line parser output
|
||||
Ph(Placeholder),
|
||||
/// A new atom
|
||||
Atom(Atom),
|
||||
/// Anchor to insert a subtree
|
||||
@@ -55,19 +51,6 @@ pub enum Token {
|
||||
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)]
|
||||
pub enum Paren {
|
||||
Round,
|
||||
@@ -75,13 +58,6 @@ pub enum Paren {
|
||||
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)]
|
||||
pub struct TreeId(pub NonZeroU64);
|
||||
|
||||
@@ -97,7 +73,6 @@ pub enum ItemKind {
|
||||
Member(Member),
|
||||
Raw(Vec<TokenTree>),
|
||||
Export(TStr),
|
||||
Rule(Macro),
|
||||
Import(CompName),
|
||||
}
|
||||
|
||||
|
||||
@@ -2,9 +2,9 @@ use std::sync::Arc;
|
||||
|
||||
use itertools::Itertools;
|
||||
|
||||
use crate::api;
|
||||
use crate::interner::{deintern, Tok};
|
||||
use crate::location::Pos;
|
||||
use crate::api;
|
||||
|
||||
/// A point of interest in resolving the error, such as the point where
|
||||
/// processing got stuck, a command that is likely to be incorrect
|
||||
|
||||
@@ -7,7 +7,7 @@ use std::{fmt, hash};
|
||||
|
||||
use hashbrown::{HashMap, HashSet};
|
||||
use itertools::Itertools as _;
|
||||
use orchid_api_traits::{Encode, Decode, Request};
|
||||
use orchid_api_traits::{Decode, Encode, Request};
|
||||
|
||||
use crate::api;
|
||||
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) }
|
||||
}
|
||||
impl<T: Interned + Decode> Decode for Tok<T> {
|
||||
fn decode<R: std::io::Read + ?Sized>(read: &mut R) -> Self {
|
||||
intern(&T::decode(read))
|
||||
}
|
||||
fn decode<R: std::io::Read + ?Sized>(read: &mut R) -> Self { intern(&T::decode(read)) }
|
||||
}
|
||||
|
||||
pub trait Interned: Eq + hash::Hash + Clone + Internable<Interned = Self> {
|
||||
|
||||
@@ -93,7 +93,7 @@ impl<T: NameIndex> Index<T> for PathSlice {
|
||||
mod idx_impls {
|
||||
use std::ops;
|
||||
|
||||
use super::{NameIndex, PathSlice, conv_range};
|
||||
use super::{conv_range, NameIndex, PathSlice};
|
||||
use crate::interner::Tok;
|
||||
|
||||
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>(
|
||||
range: impl RangeBounds<T>
|
||||
range: impl RangeBounds<T>,
|
||||
) -> (Bound<U>, Bound<U>) {
|
||||
(conv_bound(range.start_bound()), conv_bound(range.end_bound()))
|
||||
}
|
||||
|
||||
@@ -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>(
|
||||
snip: Snippet<'a, 'b, A, X>, tok: Tok<String>
|
||||
snip: Snippet<'a, 'b, A, X>,
|
||||
tok: Tok<String>,
|
||||
) -> OrcRes<Snippet<'a, 'b, A, X>> {
|
||||
let (head, tail) = try_pop_no_fluff(snip)?;
|
||||
match &head.tok {
|
||||
@@ -151,8 +152,8 @@ pub fn expect_tok<'a, 'b, A: AtomInTok, X: fmt::Display>(
|
||||
t => Err(vec![mk_err(
|
||||
intern!(str: "Expected specific keyword"),
|
||||
format!("Expected {tok} but found {t}"),
|
||||
[Pos::Range(head.range.clone()).into()]
|
||||
)])
|
||||
[Pos::Range(head.range.clone()).into()],
|
||||
)]),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -277,9 +278,9 @@ impl CompName {
|
||||
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use never::Never;
|
||||
use never::Never;
|
||||
|
||||
use super::Snippet;
|
||||
use super::Snippet;
|
||||
|
||||
fn _covary_snip_a<'a, 'b>(x: Snippet<'static, 'b, Never, ()>) -> Snippet<'a, 'b, Never, ()> { x }
|
||||
fn _covary_snip_b<'a, 'b>(x: Snippet<'a, 'static, Never, ()>) -> Snippet<'a, 'b, Never, ()> { x }
|
||||
|
||||
@@ -14,7 +14,8 @@ pub struct ReplyToken;
|
||||
|
||||
trait_set! {
|
||||
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> =
|
||||
for<'a> FnMut(<T::In as Channel>::Notif, ReqNot<T>) + DynClone + Send + Sync + 'static;
|
||||
}
|
||||
|
||||
@@ -1,34 +1,6 @@
|
||||
use std::fmt::Display;
|
||||
|
||||
pub use api::Paren;
|
||||
|
||||
use crate::api;
|
||||
use crate::interner::{deintern, Tok};
|
||||
|
||||
pub const PARENS: &[(char, char, Paren)] =
|
||||
&[('(', ')', 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),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,9 +12,9 @@ use trait_set::trait_set;
|
||||
|
||||
use crate::api;
|
||||
use crate::error::OrcErr;
|
||||
use crate::interner::{deintern, intern, Tok};
|
||||
use crate::interner::{deintern, Tok};
|
||||
use crate::name::{NameLike, VName};
|
||||
use crate::tokens::{OwnedPh, PARENS};
|
||||
use crate::tokens::PARENS;
|
||||
|
||||
trait_set! {
|
||||
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 }| {
|
||||
let tok = match 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.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::Lambda(arg) => Token::LambdaHead(ttv_from_api(arg, ctx)),
|
||||
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::Comment(c) => Token::Comment(c.clone()),
|
||||
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) =>
|
||||
api::Token::Lambda(arg.iter().map(|t| t.to_api(do_extra)).collect_vec()),
|
||||
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::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()),
|
||||
@@ -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;
|
||||
|
||||
#[derive(Clone, Debug)]
|
||||
@@ -186,7 +155,6 @@ pub enum Token<'a, A: AtomInTok, X> {
|
||||
BR,
|
||||
S(Paren, Vec<TokTree<'a, A, X>>),
|
||||
Atom(A),
|
||||
Ph(OwnedPh),
|
||||
Bottom(Vec<OrcErr>),
|
||||
Slot(TreeHandle<'a>),
|
||||
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::NS => f.write_str("::"),
|
||||
Self::Name(n) => f.write_str(n),
|
||||
Self::Ph(ph) => write!(f, "{ph}"),
|
||||
Self::Slot(th) => write!(f, "{th}"),
|
||||
Self::S(p, b) => {
|
||||
let (lp, rp, _) = PARENS.iter().find(|(_, _, par)| par == p).unwrap();
|
||||
|
||||
@@ -63,7 +63,7 @@ impl<A: Atomic + AtomicFeaturesImpl<A::Variant> + ?Sized> AtomicFeatures for A {
|
||||
}
|
||||
|
||||
pub fn get_info<A: AtomCard>(
|
||||
sys: &(impl DynSystemCard + ?Sized)
|
||||
sys: &(impl DynSystemCard + ?Sized),
|
||||
) -> (api::AtomId, &'static dyn AtomDynfo) {
|
||||
atom_info_for(sys, TypeId::of::<A>()).unwrap_or_else(|| {
|
||||
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 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> {
|
||||
|
||||
@@ -64,7 +64,11 @@ impl<T: OwnedAtom> AtomDynfo for OwnedAtomDynfo<T> {
|
||||
fn drop(&self, AtomCtx(_, id, ctx): AtomCtx) {
|
||||
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();
|
||||
id.encode(write);
|
||||
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)
|
||||
}
|
||||
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)
|
||||
}
|
||||
fn dyn_command(self: Box<Self>, ctx: SysCtx) -> OrcRes<Option<GenExpr>> { self.command(ctx) }
|
||||
|
||||
@@ -49,7 +49,7 @@ impl<T: ThinAtom> AtomDynfo for ThinAtomDynfo<T> {
|
||||
req: &mut dyn std::io::Read,
|
||||
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)
|
||||
}
|
||||
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>> {
|
||||
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);
|
||||
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)]
|
||||
fn call(&self, arg: ExprHandle) -> GenExpr { bot(err_not_callable()) }
|
||||
#[allow(unused_variables)]
|
||||
|
||||
@@ -127,7 +127,7 @@ fn extension_main_logic(data: ExtensionData) {
|
||||
};
|
||||
let mut tia_ctx = TIACtxImpl{
|
||||
lazy: &mut lazy_mems,
|
||||
ctx: ctx.clone(),
|
||||
sys: ctx.clone(),
|
||||
basepath: &[],
|
||||
path: Substack::Bottom,
|
||||
};
|
||||
@@ -156,9 +156,12 @@ fn extension_main_logic(data: ExtensionData) {
|
||||
Some(MemberRecord::Gen(path, cb)) => (path, cb),
|
||||
};
|
||||
let tree = cb.build(path.clone());
|
||||
let ctx = SysCtx::new(*sys_id, &sys.cted, &logger, req.reqnot());
|
||||
let reply_tree = tree.into_api(&mut TIACtxImpl{ ctx: ctx.clone(), lazy, path: Substack::Bottom, basepath: &path });
|
||||
req.handle(get_tree, &reply_tree)
|
||||
req.handle(get_tree, &tree.into_api(&mut TIACtxImpl{
|
||||
sys: SysCtx::new(*sys_id, &sys.cted, &logger, req.reqnot()),
|
||||
path: Substack::Bottom,
|
||||
basepath: &path,
|
||||
lazy,
|
||||
}))
|
||||
}
|
||||
api::HostExtReq::VfsReq(api::VfsReq::GetVfs(get_vfs@api::GetVfs(sys_id))) => {
|
||||
let systems_g = systems.lock().unwrap();
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use orchid_base::interner::Tok;
|
||||
use std::borrow::Cow;
|
||||
use std::collections::HashMap;
|
||||
use std::io;
|
||||
@@ -9,6 +8,7 @@ use lazy_static::lazy_static;
|
||||
use never::Never;
|
||||
use orchid_api_traits::Encode;
|
||||
use orchid_base::error::OrcRes;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::name::Sym;
|
||||
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>;
|
||||
}
|
||||
|
||||
lazy_static!{
|
||||
lazy_static! {
|
||||
static ref FUNS: Mutex<HashMap<Sym, (u8, Arc<dyn FunCB>)>> = Mutex::default();
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub(crate) struct Fun{
|
||||
pub(crate) struct Fun {
|
||||
path: Sym,
|
||||
args: Vec<ExprHandle>,
|
||||
arity: u8,
|
||||
@@ -64,8 +64,8 @@ impl OwnedAtom for Fun {
|
||||
if new_args.len() == self.arity.into() {
|
||||
(self.fun)(new_args).to_expr()
|
||||
} else {
|
||||
Self {
|
||||
args: new_args, arity: self.arity, fun: self.fun.clone(), path: self.path.clone() }.to_expr()
|
||||
Self { args: new_args, arity: self.arity, fun: self.fun.clone(), path: self.path.clone() }
|
||||
.to_expr()
|
||||
}
|
||||
}
|
||||
fn call(self, arg: ExprHandle) -> GenExpr { self.call_ref(arg) }
|
||||
@@ -83,10 +83,10 @@ impl OwnedAtom for Fun {
|
||||
|
||||
mod expr_func_derives {
|
||||
use orchid_base::error::OrcRes;
|
||||
use crate::func_atom::GenExpr;
|
||||
|
||||
use super::ExprFunc;
|
||||
use crate::conv::{TryFromExpr, ToExpr};
|
||||
use crate::func_atom::ExprHandle;
|
||||
use crate::conv::{ToExpr, TryFromExpr};
|
||||
use crate::func_atom::{ExprHandle, GenExpr};
|
||||
|
||||
macro_rules! expr_func_derive {
|
||||
($arity: tt, $($t:ident),*) => {
|
||||
@@ -106,15 +106,15 @@ mod expr_func_derives {
|
||||
}
|
||||
};
|
||||
}
|
||||
expr_func_derive!(1, A);
|
||||
expr_func_derive!(2, A, B);
|
||||
expr_func_derive!(3, A, B, C);
|
||||
expr_func_derive!(4, A, B, C, D);
|
||||
expr_func_derive!(5, A, B, C, D, E);
|
||||
expr_func_derive!(6, A, B, C, D, E, F);
|
||||
expr_func_derive!(7, A, B, C, D, E, F, G);
|
||||
expr_func_derive!(8, A, B, C, D, E, F, G, H);
|
||||
expr_func_derive!(9, A, B, C, D, E, F, G, H, I);
|
||||
expr_func_derive!(1, A);
|
||||
expr_func_derive!(2, A, B);
|
||||
expr_func_derive!(3, A, B, C);
|
||||
expr_func_derive!(4, A, B, C, D);
|
||||
expr_func_derive!(5, A, B, C, D, E);
|
||||
expr_func_derive!(6, A, B, C, D, E, F);
|
||||
expr_func_derive!(7, A, B, C, D, E, F, G);
|
||||
expr_func_derive!(8, A, B, C, D, E, F, G, H);
|
||||
expr_func_derive!(9, A, B, C, D, E, F, G, H, I);
|
||||
expr_func_derive!(10, A, B, C, D, E, F, G, H, I, J);
|
||||
expr_func_derive!(11, A, B, C, D, E, F, G, H, I, J, K);
|
||||
expr_func_derive!(12, A, B, C, D, E, F, G, H, I, J, K, L);
|
||||
|
||||
@@ -55,17 +55,12 @@ pub trait Lexer: Send + Sync + Sized + Default + 'static {
|
||||
|
||||
pub trait DynLexer: Send + Sync + 'static {
|
||||
fn char_filter(&self) -> &'static [RangeInclusive<char>];
|
||||
fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>)
|
||||
-> OrcRes<(&'a str, GenTokTree<'a>)>;
|
||||
fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)>;
|
||||
}
|
||||
|
||||
impl<T: Lexer> DynLexer for T {
|
||||
fn char_filter(&self) -> &'static [RangeInclusive<char>] { T::CHAR_FILTER }
|
||||
fn lex<'a>(
|
||||
&self,
|
||||
tail: &'a str,
|
||||
ctx: &'a LexContext<'a>,
|
||||
) -> OrcRes<(&'a str, GenTokTree<'a>)> {
|
||||
fn lex<'a>(&self, tail: &'a str, ctx: &'a LexContext<'a>) -> OrcRes<(&'a str, GenTokTree<'a>)> {
|
||||
T::lex(tail, ctx)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -34,7 +34,9 @@ pub trait DynSystemCard: Send + Sync + 'static {
|
||||
/// 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<&'static dyn AtomDynfo>] { &[/*Some(Fun::INFO)*/] }
|
||||
fn general_atoms() -> &'static [Option<&'static dyn AtomDynfo>] {
|
||||
&[/*Some(Fun::INFO)*/]
|
||||
}
|
||||
|
||||
pub fn atom_info_for(
|
||||
sys: &(impl DynSystemCard + ?Sized),
|
||||
|
||||
@@ -8,8 +8,7 @@ use itertools::Itertools;
|
||||
use orchid_base::interner::{intern, Tok};
|
||||
use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::tree::{ttv_to_api, TokTree, Token};
|
||||
use ordered_float::NotNan;
|
||||
use orchid_base::tree::{TokTree, Token};
|
||||
use substack::Substack;
|
||||
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)) }
|
||||
}
|
||||
|
||||
#[derive(Clone)]
|
||||
pub struct GenMacro {
|
||||
pub pattern: Vec<GenTokTree<'static>>,
|
||||
pub priority: NotNan<f64>,
|
||||
pub template: Vec<GenTokTree<'static>>,
|
||||
}
|
||||
|
||||
pub struct GenItem {
|
||||
pub item: GenItemKind,
|
||||
pub comments: Vec<(String, Pos)>,
|
||||
@@ -43,11 +35,6 @@ pub struct GenItem {
|
||||
impl GenItem {
|
||||
pub fn into_api(self, ctx: &mut impl TreeIntoApiCtx) -> api::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(
|
||||
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 {
|
||||
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)
|
||||
}
|
||||
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 {
|
||||
val.comments.extend(cmts.into_iter().map(|c| (c.to_string(), Pos::Inherit)));
|
||||
@@ -122,7 +97,6 @@ impl Clone for LazyMemberFactory {
|
||||
pub enum GenItemKind {
|
||||
Member(GenMember),
|
||||
Raw(Vec<GenTokTree<'static>>),
|
||||
Rule(GenMacro),
|
||||
}
|
||||
impl GenItemKind {
|
||||
pub fn at(self, position: Pos) -> GenItem {
|
||||
@@ -140,7 +114,7 @@ impl GenMember {
|
||||
api::Member {
|
||||
name: self.name.marker(),
|
||||
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 ctx: SysCtx,
|
||||
pub sys: SysCtx,
|
||||
pub basepath: &'a [Tok<String>],
|
||||
pub path: Substack<'a, Tok<String>>,
|
||||
pub lazy: &'b mut HashMap<api::TreeId, MemberRecord>,
|
||||
}
|
||||
|
||||
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 {
|
||||
TIACtxImpl {
|
||||
ctx: self.ctx.clone(),
|
||||
sys: self.sys.clone(),
|
||||
lazy: self.lazy,
|
||||
basepath: self.basepath,
|
||||
path: self.path.push(seg)
|
||||
path: self.path.push(seg),
|
||||
}
|
||||
}
|
||||
fn with_lazy(&mut self, fac: LazyMemberFactory) -> api::TreeId {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
use orchid_base::intern;
|
||||
use std::collections::VecDeque;
|
||||
use std::num::NonZero;
|
||||
use std::ops::{Deref, Range};
|
||||
@@ -14,12 +13,12 @@ use itertools::Itertools;
|
||||
use lazy_static::lazy_static;
|
||||
use orchid_api_traits::{enc_vec, Decode, Request};
|
||||
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::interner::{deintern, intern, Tok};
|
||||
use orchid_base::logging::Logger;
|
||||
use orchid_base::reqnot::{ReqNot, Requester as _};
|
||||
use orchid_base::tree::{ttv_from_api, AtomInTok};
|
||||
use orchid_base::{clone, intern};
|
||||
use ordered_float::NotNan;
|
||||
use substack::{Stackframe, Substack};
|
||||
|
||||
@@ -135,9 +134,7 @@ pub struct ExtensionData {
|
||||
logger: Logger,
|
||||
}
|
||||
impl Drop for ExtensionData {
|
||||
fn drop(&mut self) {
|
||||
self.reqnot.notify(api::HostExtNotif::Exit);
|
||||
}
|
||||
fn drop(&mut self) { self.reqnot.notify(api::HostExtNotif::Exit); }
|
||||
}
|
||||
|
||||
fn acq_expr(sys: api::SysId, extk: api::ExprTicket) {
|
||||
@@ -156,7 +153,6 @@ fn rel_expr(sys: api::SysId, extk: api::ExprTicket) {
|
||||
#[derive(Clone)]
|
||||
pub struct Extension(Arc<ExtensionData>);
|
||||
impl Extension {
|
||||
|
||||
pub fn new_process(port: Arc<dyn ExtensionPort>, logger: Logger) -> io::Result<Self> {
|
||||
port.send(&enc_vec(&api::HostHeader { log_strategy: logger.strat() }));
|
||||
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::ExternStrv(vi) =>
|
||||
req.handle(vi, &Arc::new(deintern(vi.0).iter().map(|t| t.marker()).collect_vec())),
|
||||
}
|
||||
},
|
||||
api::ExtHostReq::Fwd(fw @ api::Fwd(atom, _body)) => {
|
||||
let sys = System::resolve(atom.owner).unwrap();
|
||||
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.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);
|
||||
req.handle(ins, &api::Details{
|
||||
req.handle(ins, &api::Details {
|
||||
refcount: 1,
|
||||
expr: api::Expr{
|
||||
expr: api::Expr {
|
||||
location: api::Location::None,
|
||||
clause: api::Clause::Bottom(vec![
|
||||
mk_err(
|
||||
intern!(str: "Unsupported"),
|
||||
"Inspecting clauses is unsupported at the moment",
|
||||
[]
|
||||
[],
|
||||
)
|
||||
.to_api()
|
||||
])
|
||||
}
|
||||
.to_api(),
|
||||
]),
|
||||
},
|
||||
})
|
||||
}
|
||||
},
|
||||
},
|
||||
),
|
||||
systems: eh.systems.into_iter().map(|decl| SystemCtor { decl, ext: weak.clone() }).collect(),
|
||||
@@ -223,12 +219,14 @@ impl Extension {
|
||||
let weak = Arc::downgrade(&ret);
|
||||
thread::Builder::new()
|
||||
.name(format!("host-end:{}", eh.name))
|
||||
.spawn::<_, Option<()>>(move || loop {
|
||||
// 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
|
||||
// until the
|
||||
let msg = port.receive()?;
|
||||
weak.upgrade()?.reqnot.receive(msg);
|
||||
.spawn::<_, Option<()>>(move || {
|
||||
loop {
|
||||
// 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 until the
|
||||
let msg = port.receive()?;
|
||||
weak.upgrade()?.reqnot.receive(msg);
|
||||
}
|
||||
})
|
||||
.unwrap();
|
||||
Ok(Self(ret))
|
||||
|
||||
@@ -7,7 +7,7 @@ use orchid_base::intern;
|
||||
use orchid_base::interner::{deintern, intern, Tok};
|
||||
use orchid_base::location::Pos;
|
||||
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::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 {
|
||||
let tok = match &api.token {
|
||||
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::Lambda(arg) =>
|
||||
ParsTok::LambdaHead(arg.iter().map(|t| tt_to_owned(t, ctx)).collect()),
|
||||
|
||||
@@ -5,5 +5,5 @@ pub mod expr;
|
||||
pub mod extension;
|
||||
pub mod lex;
|
||||
pub mod parse;
|
||||
pub mod tree;
|
||||
pub mod subprocess;
|
||||
pub mod tree;
|
||||
|
||||
@@ -7,12 +7,13 @@ use orchid_base::intern;
|
||||
use orchid_base::interner::Tok;
|
||||
use orchid_base::location::Pos;
|
||||
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 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>;
|
||||
|
||||
@@ -115,26 +116,21 @@ pub fn parse_item_2(
|
||||
} else if discr == intern!(str: "const") {
|
||||
let (name, val) = parse_const(tail)?;
|
||||
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())) {
|
||||
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 {
|
||||
let ext_lines = ctx.systems().flat_map(System::line_types).join(", ");
|
||||
return Err(vec![mk_err(
|
||||
intern!(str: "Unrecognized line type"),
|
||||
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 }])
|
||||
}
|
||||
|
||||
pub fn parse_module(
|
||||
ctx: &impl ParseCtx,
|
||||
tail: ParsSnippet,
|
||||
) -> OrcRes<(Tok<String>, Module)> {
|
||||
pub fn parse_module(ctx: &impl ParseCtx, tail: ParsSnippet) -> OrcRes<(Tok<String>, Module)> {
|
||||
let (name, tail) = match try_pop_no_fluff(tail)? {
|
||||
(TokTree { tok: Token::Name(n), .. }, tail) => (n.clone(), tail),
|
||||
(tt, _) =>
|
||||
@@ -179,9 +175,3 @@ pub fn parse_const(tail: ParsSnippet) -> OrcRes<(Tok<String>, Vec<ParsTokTree>)>
|
||||
try_pop_no_fluff(tail)?;
|
||||
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!();
|
||||
}
|
||||
@@ -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;
|
||||
|
||||
@@ -21,25 +25,21 @@ impl Subprocess {
|
||||
let stdin = child.stdin.take().unwrap();
|
||||
let stdout = child.stdout.take().unwrap();
|
||||
let child_stderr = child.stderr.take().unwrap();
|
||||
thread::Builder::new()
|
||||
.name(format!("stderr-fwd:{prog}"))
|
||||
.spawn(move || {
|
||||
let mut reader = io::BufReader::new(child_stderr);
|
||||
loop {
|
||||
let mut buf = String::new();
|
||||
if 0 == reader.read_line(&mut buf).unwrap() {
|
||||
break;
|
||||
}
|
||||
logger.log(buf);
|
||||
thread::Builder::new().name(format!("stderr-fwd:{prog}")).spawn(move || {
|
||||
let mut reader = io::BufReader::new(child_stderr);
|
||||
loop {
|
||||
let mut buf = String::new();
|
||||
if 0 == reader.read_line(&mut buf).unwrap() {
|
||||
break;
|
||||
}
|
||||
})?;
|
||||
Ok(Self{ child: Mutex::new(child), stdin: Mutex::new(stdin), stdout: Mutex::new(stdout) })
|
||||
logger.log(buf);
|
||||
}
|
||||
})?;
|
||||
Ok(Self { child: Mutex::new(child), stdin: Mutex::new(stdin), stdout: Mutex::new(stdout) })
|
||||
}
|
||||
}
|
||||
impl Drop for Subprocess {
|
||||
fn drop(&mut self) {
|
||||
self.child.lock().unwrap().wait().expect("Extension exited with error");
|
||||
}
|
||||
fn drop(&mut self) { self.child.lock().unwrap().wait().expect("Extension exited with error"); }
|
||||
}
|
||||
impl ExtensionPort for Subprocess {
|
||||
fn send(&self, msg: &[u8]) { send_msg(&mut *self.stdin.lock().unwrap(), msg).unwrap() }
|
||||
|
||||
@@ -8,7 +8,6 @@ use orchid_base::location::Pos;
|
||||
use orchid_base::name::Sym;
|
||||
use orchid_base::parse::{Comment, CompName};
|
||||
use orchid_base::tree::{ttv_from_api, TokTree, Token};
|
||||
use ordered_float::NotNan;
|
||||
|
||||
use crate::api;
|
||||
use crate::expr::RtExpr;
|
||||
@@ -29,7 +28,6 @@ pub enum ItemKind {
|
||||
Raw(Vec<ParsTokTree>),
|
||||
Member(Member),
|
||||
Export(Tok<String>),
|
||||
Rule(Macro),
|
||||
Import(CompName),
|
||||
}
|
||||
|
||||
@@ -38,7 +36,6 @@ impl Item {
|
||||
let kind = match tree.kind {
|
||||
api::ItemKind::Raw(tokv) => ItemKind::Raw(ttv_from_api(tokv, &mut ())),
|
||||
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::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)]
|
||||
pub struct LazyMemberHandle(api::TreeId, System);
|
||||
impl LazyMemberHandle {
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
use std::env;
|
||||
use std::ffi::OsStr;
|
||||
use std::fs::File;
|
||||
use std::fs::{DirEntry, File};
|
||||
use std::io::{self, Read};
|
||||
use std::path::PathBuf;
|
||||
use std::path::Path;
|
||||
use std::process::ExitCode;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
|
||||
@@ -26,34 +26,43 @@ pub static EXIT_OK: AtomicBool = AtomicBool::new(true);
|
||||
fn main() -> io::Result<ExitCode> {
|
||||
let args = Args::parse();
|
||||
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" {
|
||||
let mut contents = String::new();
|
||||
File::open(file.path())?.read_to_string(&mut contents)?;
|
||||
for (l, line) in contents.lines().enumerate() {
|
||||
if line.trim().starts_with("use") {
|
||||
if let Some(c) = line.find("orchid_api") {
|
||||
if Some(c) != line.find("orchid_api_") {
|
||||
let dname = file.path().to_string_lossy().to_string();
|
||||
eprintln!("orchid_api imported in {dname} at {};{}", l + 1, c + 1)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
})?,
|
||||
}
|
||||
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();
|
||||
File::open(file.path())?.read_to_string(&mut contents)?;
|
||||
for (l, line) in contents.lines().enumerate() {
|
||||
if line.trim().starts_with("use") {
|
||||
if let Some(c) = line.find("orchid_api") {
|
||||
if Some(c) != line.find("orchid_api_") {
|
||||
let dname = file.path().to_string_lossy().to_string();
|
||||
eprintln!("orchid_api imported in {dname} at {};{}", l + 1, c + 1)
|
||||
}
|
||||
}
|
||||
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(())
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user