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"
|
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"
|
||||||
|
|||||||
@@ -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
|
|
||||||
|
|||||||
@@ -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 {
|
||||||
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
|
($t:ty, $size:expr) => {
|
||||||
NotNan::new(T::decode(read)).expect("Float was NaN")
|
impl Decode for NotNan<$t> {
|
||||||
}
|
fn decode<R: Read + ?Sized>(read: &mut R) -> Self {
|
||||||
}
|
let mut bytes = [0u8; $size];
|
||||||
impl<T: Encode + FloatCore> Encode for NotNan<T> {
|
read.read_exact(&mut bytes).unwrap();
|
||||||
fn encode<W: Write + ?Sized>(&self, write: &mut W) { self.as_ref().encode(write) }
|
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 {
|
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();
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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"
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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};
|
||||||
|
|||||||
@@ -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::*;
|
||||||
|
|||||||
@@ -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),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -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
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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()))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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()],
|
||||||
)])
|
)]),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -277,9 +278,9 @@ impl CompName {
|
|||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod 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_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 }
|
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! {
|
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;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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> {
|
||||||
|
|||||||
@@ -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) }
|
||||||
|
|||||||
@@ -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)]
|
||||||
|
|||||||
@@ -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();
|
||||||
|
|||||||
@@ -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),*) => {
|
||||||
@@ -106,15 +106,15 @@ mod expr_func_derives {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
expr_func_derive!(1, A);
|
expr_func_derive!(1, A);
|
||||||
expr_func_derive!(2, A, B);
|
expr_func_derive!(2, A, B);
|
||||||
expr_func_derive!(3, A, B, C);
|
expr_func_derive!(3, A, B, C);
|
||||||
expr_func_derive!(4, A, B, C, D);
|
expr_func_derive!(4, A, B, C, D);
|
||||||
expr_func_derive!(5, A, B, C, D, E);
|
expr_func_derive!(5, A, B, C, D, E);
|
||||||
expr_func_derive!(6, A, B, C, D, E, F);
|
expr_func_derive!(6, A, B, C, D, E, F);
|
||||||
expr_func_derive!(7, A, B, C, D, E, F, G);
|
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!(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!(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!(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!(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);
|
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 {
|
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)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -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),
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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 || {
|
||||||
// thread will exit if either the peer exits or the extension object is dropped.
|
loop {
|
||||||
// It holds a strong reference to the port so the port's destructor will not be called
|
// thread will exit if either the peer exits or the extension object is dropped.
|
||||||
// until the
|
// It holds a strong reference to the port so the port's destructor will not be
|
||||||
let msg = port.receive()?;
|
// called until the
|
||||||
weak.upgrade()?.reqnot.receive(msg);
|
let msg = port.receive()?;
|
||||||
|
weak.upgrade()?.reqnot.receive(msg);
|
||||||
|
}
|
||||||
})
|
})
|
||||||
.unwrap();
|
.unwrap();
|
||||||
Ok(Self(ret))
|
Ok(Self(ret))
|
||||||
|
|||||||
@@ -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()),
|
||||||
|
|||||||
@@ -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;
|
||||||
|
|||||||
@@ -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!();
|
|
||||||
}
|
|
||||||
@@ -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,25 +25,21 @@ 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}"))
|
let mut reader = io::BufReader::new(child_stderr);
|
||||||
.spawn(move || {
|
loop {
|
||||||
let mut reader = io::BufReader::new(child_stderr);
|
let mut buf = String::new();
|
||||||
loop {
|
if 0 == reader.read_line(&mut buf).unwrap() {
|
||||||
let mut buf = String::new();
|
break;
|
||||||
if 0 == reader.read_line(&mut buf).unwrap() {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
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() }
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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,34 +26,43 @@ 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" {
|
||||||
|
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 })
|
Ok(if EXIT_OK.load(Ordering::Relaxed) { ExitCode::SUCCESS } else { ExitCode::FAILURE })
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_api_refs(args: &Args, dir: PathBuf) -> io::Result<()> {
|
fn walk_wsp(
|
||||||
for file in dir.read_dir()?.collect::<Result<Vec<_>, _>>()? {
|
dir_filter: &mut impl FnMut(&DirEntry) -> io::Result<bool>,
|
||||||
if args.verbose {
|
file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>,
|
||||||
eprintln!("Checking {}", file.path().to_string_lossy());
|
) -> io::Result<()> {
|
||||||
}
|
return recurse(&env::current_dir()?, dir_filter, file_handler);
|
||||||
if file.metadata()?.is_dir() {
|
fn recurse(
|
||||||
check_api_refs(args, file.path())?
|
dir: &Path,
|
||||||
}
|
dir_filter: &mut impl FnMut(&DirEntry) -> io::Result<bool>,
|
||||||
if file.path().extension() != Some(OsStr::new("rs")) || file.file_name() == "lib.rs" {
|
file_handler: &mut impl FnMut(DirEntry) -> io::Result<()>,
|
||||||
continue;
|
) -> io::Result<()> {
|
||||||
}
|
for file in dir.read_dir()?.collect::<Result<Vec<_>, _>>()? {
|
||||||
let mut contents = String::new();
|
if file.metadata()?.is_dir() && dir_filter(&file)? {
|
||||||
File::open(file.path())?.read_to_string(&mut contents)?;
|
recurse(&file.path(), dir_filter, file_handler)?;
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
file_handler(file)?;
|
||||||
}
|
}
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user