WIP: refactor to generalize Machine::run_top_level()
This commit is contained in:
@@ -5,10 +5,12 @@ pub mod code_walker;
|
||||
#[macro_use]
|
||||
pub mod loader;
|
||||
pub mod compile;
|
||||
pub mod config;
|
||||
pub mod copier;
|
||||
pub mod dispatch;
|
||||
pub mod gc;
|
||||
pub mod heap;
|
||||
pub mod lib_machine;
|
||||
pub mod load_state;
|
||||
pub mod machine_errors;
|
||||
pub mod machine_indices;
|
||||
@@ -53,6 +55,7 @@ use std::path::PathBuf;
|
||||
use std::sync::atomic::AtomicBool;
|
||||
use tokio::runtime::Runtime;
|
||||
|
||||
use self::config::MachineConfig;
|
||||
use self::parsed_results::*;
|
||||
|
||||
lazy_static! {
|
||||
@@ -221,23 +224,18 @@ impl Machine {
|
||||
|
||||
pub fn load_file(&mut self, path: &str, stream: Stream) {
|
||||
self.machine_st.registers[1] = stream_as_cell!(stream);
|
||||
self.machine_st.registers[2] = atom_as_cell!(
|
||||
self.machine_st.atom_tbl.build_with(path)
|
||||
);
|
||||
self.machine_st.registers[2] = atom_as_cell!(self.machine_st.atom_tbl.build_with(path));
|
||||
|
||||
self.run_module_predicate(atom!("loader"), (atom!("file_load"), 2));
|
||||
}
|
||||
|
||||
fn load_top_level(&mut self) {
|
||||
fn load_top_level(&mut self, program: &'static str) {
|
||||
let mut path_buf = current_dir();
|
||||
|
||||
path_buf.push("src/toplevel.pl");
|
||||
|
||||
let path = path_buf.to_str().unwrap();
|
||||
let toplevel_stream = Stream::from_static_string(
|
||||
include_str!("../toplevel.pl"),
|
||||
&mut self.machine_st.arena,
|
||||
);
|
||||
let toplevel_stream = Stream::from_static_string(program, &mut self.machine_st.arena);
|
||||
|
||||
self.load_file(path, toplevel_stream);
|
||||
|
||||
@@ -292,7 +290,7 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn run_top_level(&mut self) {
|
||||
pub fn run_top_level(&mut self, module_name: Atom, key: PredicateKey) {
|
||||
let mut arg_pstrs = vec![];
|
||||
|
||||
for arg in env::args() {
|
||||
@@ -303,15 +301,12 @@ impl Machine {
|
||||
));
|
||||
}
|
||||
|
||||
self.machine_st.registers[1] = heap_loc_as_cell!(
|
||||
iter_to_heap_list(&mut self.machine_st.heap, arg_pstrs.into_iter())
|
||||
);
|
||||
self.machine_st.registers[1] = heap_loc_as_cell!(iter_to_heap_list(
|
||||
&mut self.machine_st.heap,
|
||||
arg_pstrs.into_iter()
|
||||
));
|
||||
|
||||
self.run_module_predicate(atom!("$toplevel"), (atom!("$repl"), 1));
|
||||
}
|
||||
|
||||
pub fn run_input_once(&mut self) {
|
||||
self.run_module_predicate(atom!("$toplevel"), (atom!("run_input_once"), 0));
|
||||
self.run_module_predicate(module_name, key);
|
||||
}
|
||||
|
||||
pub fn set_user_input(&mut self, input: String) {
|
||||
@@ -328,24 +323,6 @@ impl Machine {
|
||||
self.load_file(module_name, stream);
|
||||
}
|
||||
|
||||
pub fn run_query(&mut self, query: String) -> QueryResult{
|
||||
self.set_user_input(query);
|
||||
self.run_input_once();
|
||||
self.parse_output()
|
||||
}
|
||||
|
||||
pub fn parse_output(&self) -> QueryResult {
|
||||
let output = self.get_user_output();
|
||||
output.split(";")
|
||||
.map(|s| s.trim())
|
||||
.map(|s| s.replace(".", ""))
|
||||
.filter(|s| !s.is_empty())
|
||||
.map(QueryResultLine::try_from)
|
||||
.filter_map(Result::ok)
|
||||
.collect::<Vec<QueryResultLine>>()
|
||||
.into()
|
||||
}
|
||||
|
||||
pub(crate) fn configure_modules(&mut self) {
|
||||
fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) {
|
||||
for arity in 1..66 {
|
||||
@@ -461,18 +438,26 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn new() -> Self {
|
||||
pub fn new(config: MachineConfig) -> Self {
|
||||
use ref_thread_local::RefThreadLocal;
|
||||
|
||||
let args = MachineArgs::new();
|
||||
let mut machine_st = MachineState::new();
|
||||
|
||||
let user_input = Stream::stdin(&mut machine_st.arena, args.add_history);
|
||||
let user_output = Stream::stdout(&mut machine_st.arena);
|
||||
let user_error = Stream::stderr(&mut machine_st.arena);
|
||||
let (user_input, user_output, user_error) = match config.streams {
|
||||
config::StreamConfig::Stdio => (
|
||||
Stream::stdin(&mut machine_st.arena, args.add_history),
|
||||
Stream::stdout(&mut machine_st.arena),
|
||||
Stream::stderr(&mut machine_st.arena),
|
||||
),
|
||||
config::StreamConfig::Memory => (
|
||||
Stream::Null(StreamOptions::default()),
|
||||
Stream::from_owned_string("".to_owned(), &mut machine_st.arena),
|
||||
Stream::stderr(&mut machine_st.arena),
|
||||
),
|
||||
};
|
||||
|
||||
let runtime = tokio::runtime::Runtime::new()
|
||||
.unwrap();
|
||||
let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||
|
||||
let mut wam = Machine {
|
||||
machine_st,
|
||||
@@ -555,7 +540,7 @@ impl Machine {
|
||||
}
|
||||
|
||||
wam.load_special_forms();
|
||||
wam.load_top_level();
|
||||
wam.load_top_level(config.toplevel);
|
||||
wam.configure_streams();
|
||||
|
||||
wam
|
||||
@@ -936,40 +921,3 @@ impl Machine {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
#[test]
|
||||
fn programatic_query() {
|
||||
let mut machine = Machine::with_test_streams();
|
||||
|
||||
machine.load_module_string("facts", String::from(r#"
|
||||
triple("a", "p1", "b").
|
||||
triple("a", "p2", "b").
|
||||
"#));
|
||||
|
||||
let query = String::from(r#"triple("a",P,"b")."#);
|
||||
let output = machine.run_query(query);
|
||||
assert_eq!(output, QueryResult::Matches(vec![
|
||||
QueryMatch::from(btreemap!{
|
||||
"P" => Value::from("p1"),
|
||||
}),
|
||||
QueryMatch::from(btreemap!{
|
||||
"P" => Value::from("p2"),
|
||||
}),
|
||||
]));
|
||||
|
||||
assert_eq!(
|
||||
machine.run_query(String::from(r#"triple("a","p1","b")."#)),
|
||||
QueryResult::True
|
||||
);
|
||||
|
||||
assert_eq!(
|
||||
machine.run_query(String::from(r#"triple("x","y","z")."#)),
|
||||
QueryResult::False
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user