-
Notifications
You must be signed in to change notification settings - Fork 127
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Split main.rs into lib.rs and bin/scryer-prolog.rs #838
Conversation
Impressive! Thank you a lot for working on this! I hope this makes it possible and attractive to embed Scryer Prolog more easily in Rust applications. |
@triska I think further work is necessary to make the library useful but this will at least get the work started |
I'm not sure allowing The crate |
The signal handler is now moved to the binary. Should I move the lib to its own package so that dependencies can be specified independently of the bin or is this ok? Instead of adding the |
Crate like I'm sorry, I should have reviewed everything. This should be the last remark, the workaround introduced by |
Removed the commit that introduced the workaround and reverted the removal of |
* makes most pub things in src/ pub(crate) as not to expose things accidentally * only those things needed by src/bin/scryer-prolog.rs and tests/scryer.rs should be pub * split src/main.rs into src/lib.rs and src/bin/scryer-prolog.rs * add tests folder and run most of the files in src/tests with cargo test added bytes method to Stream in src/machine/streams.rs to check if stdout is as expected
only commenting out the unused variant as `OptArgIndexKeyType` as it appears to mirror `OptArgIndexKey` and there List is not unused so this appears to be not yet used rather than obsolete
Rebased to fix conflicts |
Great, thanks very much! |
I am watching this work closely, I have naively tried to embed Scryer in my own Rust program (in a tokio task) and would like to report the following challenges:
I'm very thankful that such a comprehensive prolog interpreter is built in pure Rust, and I'm on my first handful of hours working with Scryer, so please understand my feedback through that lens. Perhaps I should try again with this branch, and report my findings.
Pseudo reproduction how I am trying to embed scryerThe reasoning behind using Tokio this way is that my parser will constantly receive user input in a prolog-like language, which will be parsed, and canonicalized and fed to a prolog engine (Scryer, in this evolution), which will then be queried, so the pipeline goes struct Engine {
parser_edits: Sender<String>,
prolog_expr: Sender<String>,
stop: tokio::sync::broadcast::Sender<()>,
stopper: tokio::sync::broadcast::Receiver<()>,
}
impl Engine {
pub fn new() -> Result<Arc<Self>, Error> {
let (stop, stopper) = tokio::sync::broadcast::channel(16);
let (parser_edits, edit_rx) = tokio::sync::mpsc::channel(16);
let (prolog_exprs, prolog_rx) = tokio::sync::mpsc::channel(16);
let Engine = Self {
parser_edits,
prolog_exprs,
stop,
stopper,
};
let Engine = Arc::new(Engine);
tokio::task::spawn(Engine.clone().start_parser(stop.subscribe(), edit_rx));
tokio::task::spawn(Engine.clone().start_wam(stop.subscribe(), prolog_rx));
Ok(Engine)
}
async fn shutdown(self: Arc<Self>) -> Result<(), Error> {
self.stop.send(());
// ..snip..
Ok(())
}
async fn start_parser(
self: Arc<Self>,
mut stop: tokio::sync::broadcast::Receiver<()>,
mut rx: Receiver<String>,
) {
// .. snip ..
loop {
tokio::select! {
_ = stop.recv() => {
// ..snip..
break
}
Some(msg) = rx.recv() => {
// ..snip..
}
}
}
}
async fn start_wam(
self: Arc<Self>,
mut stop: tokio::sync::broadcast::Receiver<()>,
mut rx: Receiver<String>,
) {
let file = "src/tests/helloworld.pl";
let input = Stream::from("");
let output = Stream::from(String::new());
let error = Stream::from(String::new());
let mut wam = self.tracer.in_span("initializing wam", |_cx| {
// https://github.com/mthom/scryer-prolog/blob/master/tests/scryer/helper.rs
Machine::new(input, output.clone(), error)
});
self.tracer.in_span("parsing test file", |_cx| {
wam.load_file(
file.into(),
Stream::from(
std::fs::read_to_string(AsRef::<std::path::Path>::as_ref(file)).unwrap(),
),
);
});
loop {
tokio::select! {
_ = stop.recv() => {
println!("stopping wam because stop signal received");
break
}
Some(msg) = rx.recv() => {
println!("received tokens = {:?}", msg);
}
}
}
println!("wam stopped");
}
}
let e = Engine.new
e.shutdown(); |
@leehambley: Thank you a lot for trying this! Could you please try this with the current Please see the recent announcement and its discussion. |
As requested by Issues #225, #570 and #765 this makes it possible to use scryer-prolog as a library,
currently this only exposes a minimal API to get the binary and some added tests working.