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:
@@ -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};
|
||||
|
||||
@@ -114,7 +113,7 @@ impl fmt::Display for AtomHand {
|
||||
/// - send a message
|
||||
/// - wait for a message to arrive
|
||||
/// - wait for the extension to stop after exit (this is the implicit Drop)
|
||||
///
|
||||
///
|
||||
/// There are no ordering guarantees about these
|
||||
pub trait ExtensionPort: Send + Sync {
|
||||
fn send(&self, msg: &[u8]);
|
||||
@@ -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",
|
||||
[]
|
||||
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() }
|
||||
@@ -50,4 +50,4 @@ impl ExtensionPort for Subprocess {
|
||||
Err(e) => panic!("Failed to read from stdout: {}, {e}", e.kind()),
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user