]> Repositorios git - scryer-prolog.git/commitdiff
move more of the toplevel from rust into prolog
authorMark Thom <[email protected]>
Sat, 16 Nov 2019 07:26:15 +0000 (00:26 -0700)
committerMark Thom <[email protected]>
Sat, 16 Nov 2019 07:26:15 +0000 (00:26 -0700)
16 files changed:
src/prolog/clause_types.rs
src/prolog/instructions.rs
src/prolog/machine/attributed_variables.rs
src/prolog/machine/compile.rs
src/prolog/machine/machine_errors.rs
src/prolog/machine/machine_indices.rs
src/prolog/machine/machine_state.rs
src/prolog/machine/machine_state_impl.rs
src/prolog/machine/mod.rs
src/prolog/machine/project_attributes.pl
src/prolog/machine/system_calls.rs
src/prolog/machine/term_expansion.rs
src/prolog/machine/toplevel.rs
src/prolog/macros.rs
src/prolog/toplevel.pl
src/prolog/write.rs

index cd1dd14b264418c77048f2fff51d9a116c09b5ef..8f67177deca88189641a2e999c5b14009ecda94d 100644 (file)
@@ -162,8 +162,7 @@ pub enum SystemClauseType {
     AtomChars,
     AtomCodes,
     AtomLength,
-    ModuleAssertDynamicPredicateToFront,
-    ModuleAssertDynamicPredicateToBack,
+    CallAttributeGoals,
     CharCode,
     CharsToNumber,
     CodesToNumber,
@@ -176,6 +175,7 @@ pub enum SystemClauseType {
     EnqueueAttributedVar,
     ExpandGoal,
     ExpandTerm,
+    FetchAttributeGoals,
     FetchGlobalVar,
     FetchGlobalVarWithOffset,
     GetChar,
@@ -200,6 +200,8 @@ pub enum SystemClauseType {
     InstallSCCCleaner,
     InstallInferenceCounter,
     LiftedHeapLength,
+    ModuleAssertDynamicPredicateToFront,
+    ModuleAssertDynamicPredicateToBack,
     ModuleOf,
     ModuleRetractClause,
     NoSuchPredicate,
@@ -229,8 +231,8 @@ pub enum SystemClauseType {
     GetDoubleQuotes,
     InstallNewBlock,
     Maybe,
+    RawInputReadChar,
     ResetBlock,
-    ReturnFromAttributeGoals,
     ReturnFromVerifyAttr,
     SetBall,
     SetCutPointByDefault(RegType),
@@ -257,20 +259,12 @@ impl SystemClauseType {
             &SystemClauseType::AtomChars => clause_name!("$atom_chars"),
             &SystemClauseType::AtomCodes => clause_name!("$atom_codes"),
             &SystemClauseType::AtomLength => clause_name!("$atom_length"),
-            &SystemClauseType::ModuleAssertDynamicPredicateToFront => {
-                clause_name!("$module_asserta")
-            }
-            &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
-                clause_name!("$module_assertz")
-            }
+            &SystemClauseType::CallAttributeGoals => clause_name!("$call_attribute_goals"),
             &SystemClauseType::CharCode => clause_name!("$char_code"),
             &SystemClauseType::CharsToNumber => clause_name!("$chars_to_number"),
             &SystemClauseType::CodesToNumber => clause_name!("$codes_to_number"),
             &SystemClauseType::CheckCutPoint => clause_name!("$check_cp"),
             &SystemClauseType::REPL(REPLCodePtr::CompileBatch) => clause_name!("$compile_batch"),
-            &SystemClauseType::REPL(REPLCodePtr::SubmitQueryAndPrintResults) => {
-                clause_name!("$submit_query_and_print_results")
-            }
            &SystemClauseType::REPL(REPLCodePtr::UseModule) => clause_name!("$use_module"),
            &SystemClauseType::REPL(REPLCodePtr::UseQualifiedModule) => {
                clause_name!("$use_qualified_module")
@@ -289,6 +283,7 @@ impl SystemClauseType {
             &SystemClauseType::EnqueueAttributedVar => clause_name!("$enqueue_attr_var"),
             &SystemClauseType::ExpandTerm => clause_name!("$expand_term"),
             &SystemClauseType::ExpandGoal => clause_name!("$expand_goal"),
+            &SystemClauseType::FetchAttributeGoals => clause_name!("$fetch_attribute_goals"),
             &SystemClauseType::FetchGlobalVar => clause_name!("$fetch_global_var"),
             &SystemClauseType::FetchGlobalVarWithOffset => {
                 clause_name!("$fetch_global_var_with_offset")
@@ -327,11 +322,18 @@ impl SystemClauseType {
             }
             &SystemClauseType::LiftedHeapLength => clause_name!("$lh_length"),
             &SystemClauseType::Maybe => clause_name!("maybe"),
+            &SystemClauseType::ModuleAssertDynamicPredicateToFront => {
+                clause_name!("$module_asserta")
+            }
+            &SystemClauseType::ModuleAssertDynamicPredicateToBack => {
+                clause_name!("$module_assertz")
+            }
             &SystemClauseType::ModuleHeadIsDynamic => clause_name!("$module_head_is_dynamic"),
             &SystemClauseType::ModuleOf => clause_name!("$module_of"),
             &SystemClauseType::NoSuchPredicate => clause_name!("$no_such_predicate"),
             &SystemClauseType::NumberToChars => clause_name!("$number_to_chars"),
             &SystemClauseType::NumberToCodes => clause_name!("$number_to_codes"),
+            &SystemClauseType::RawInputReadChar => clause_name!("$raw_input_read_char"),
             &SystemClauseType::RedoAttrVarBindings => clause_name!("$redo_attr_var_bindings"),
             &SystemClauseType::RemoveCallPolicyCheck => clause_name!("$remove_call_policy_check"),
             &SystemClauseType::RemoveInferenceCounter => clause_name!("$remove_inference_counter"),
@@ -357,9 +359,6 @@ impl SystemClauseType {
             &SystemClauseType::ResetGlobalVarAtOffset => clause_name!("$reset_global_var_at_offset"),
             &SystemClauseType::RetractClause => clause_name!("$retract_clause"),
             &SystemClauseType::ResetBlock => clause_name!("$reset_block"),
-            &SystemClauseType::ReturnFromAttributeGoals => {
-                clause_name!("$return_from_attribute_goals")
-            }
             &SystemClauseType::ReturnFromVerifyAttr => clause_name!("$return_from_verify_attr"),
             &SystemClauseType::SetBall => clause_name!("$set_ball"),
             &SystemClauseType::SetCutPointByDefault(_) => clause_name!("$set_cp_by_default"),
@@ -387,6 +386,7 @@ impl SystemClauseType {
             ("$module_assertz", 5) => Some(SystemClauseType::ModuleAssertDynamicPredicateToBack),
             ("$asserta", 4) => Some(SystemClauseType::AssertDynamicPredicateToFront),
             ("$assertz", 4) => Some(SystemClauseType::AssertDynamicPredicateToBack),
+            ("$call_attribute_goals", 2) => Some(SystemClauseType::CallAttributeGoals),
             ("$char_code", 2) => Some(SystemClauseType::CharCode),
             ("$chars_to_number", 2) => Some(SystemClauseType::CharsToNumber),
             ("$codes_to_number", 2) => Some(SystemClauseType::CodesToNumber),
@@ -404,6 +404,7 @@ impl SystemClauseType {
             ("$enqueue_attr_var", 1) => Some(SystemClauseType::EnqueueAttributedVar),
             ("$expand_term", 2) => Some(SystemClauseType::ExpandTerm),
             ("$expand_goal", 2) => Some(SystemClauseType::ExpandGoal),
+            ("$fetch_attribute_goals", 1) => Some(SystemClauseType::FetchAttributeGoals),
             ("$fetch_global_var", 2) => Some(SystemClauseType::FetchGlobalVar),
             ("$fetch_global_var_with_offset", 3) => Some(SystemClauseType::FetchGlobalVarWithOffset),
             ("$get_char", 1) => Some(SystemClauseType::GetChar),
@@ -449,13 +450,13 @@ impl SystemClauseType {
             ("$get_current_block", 1) => Some(SystemClauseType::GetCurrentBlock),
             ("$get_cp", 1) => Some(SystemClauseType::GetCutPoint),
             ("$install_new_block", 1) => Some(SystemClauseType::InstallNewBlock),
+            ("$raw_input_read_char", 1) => Some(SystemClauseType::RawInputReadChar),
             ("$read_query_term", 2) => Some(SystemClauseType::ReadQueryTerm),
             ("$read_term", 2) => Some(SystemClauseType::ReadTerm),
             ("$reset_block", 1) => Some(SystemClauseType::ResetBlock),
             ("$reset_global_var_at_key", 1) => Some(SystemClauseType::ResetGlobalVarAtKey),
             ("$reset_global_var_at_offset", 3) => Some(SystemClauseType::ResetGlobalVarAtOffset),
             ("$retract_clause", 4) => Some(SystemClauseType::RetractClause),
-            ("$return_from_attribute_goals", 0) => Some(SystemClauseType::ReturnFromAttributeGoals),
             ("$return_from_verify_attr", 0) => Some(SystemClauseType::ReturnFromVerifyAttr),
             ("$set_ball", 1) => Some(SystemClauseType::SetBall),
             ("$set_cp_by_default", 1) => Some(SystemClauseType::SetCutPointByDefault(temp_v!(1))),
@@ -464,9 +465,6 @@ impl SystemClauseType {
             ("$skip_max_list", 4) => Some(SystemClauseType::SkipMaxList),
             ("$store_global_var", 2) => Some(SystemClauseType::StoreGlobalVar),
             ("$store_global_var_with_offset", 2) => Some(SystemClauseType::StoreGlobalVarWithOffset),
-            ("$submit_query_and_print_results", 2) => Some(SystemClauseType::REPL(
-                REPLCodePtr::SubmitQueryAndPrintResults,
-            )),
             ("$term_variables", 2) => Some(SystemClauseType::TermVariables),
             ("$truncate_lh_to", 1) => Some(SystemClauseType::TruncateLiftedHeapTo),
             ("$unwind_stack", 0) => Some(SystemClauseType::UnwindStack),
index 75a7d8935ab1efcf1f988df8f653d43ee8064f00..ef919e55e6a3337712a5b91cdfce1e06fcc584d5 100644 (file)
@@ -364,14 +364,6 @@ pub enum ControlInstruction {
 }
 
 impl ControlInstruction {
-    pub fn is_jump_instr(&self) -> bool {
-        match self {
-            &ControlInstruction::CallClause(..) => true,
-            &ControlInstruction::JmpBy(..) => true,
-            _ => false,
-        }
-    }
-
     pub fn to_functor(&self) -> MachineStub {
         match self {
             &ControlInstruction::Allocate(num_frames) => {
index 80fd11bcfd58c2cf13e3f60ac9146bd2cf3beb08..992ba98d66eefe0909211fe2f4553c90a9dc75df 100644 (file)
@@ -1,7 +1,5 @@
 use crate::prolog::machine::*;
 
-use indexmap::IndexSet;
-
 use std::vec::IntoIter;
 
 pub static VERIFY_ATTRS: &str = include_str!("attributed_variables.pl");
@@ -101,35 +99,6 @@ impl MachineState {
         attr_vars.into_iter()
     }
 
-    fn populate_project_attr_lists(&mut self) -> (Addr, Addr) {
-        let mut query_vars = IndexSet::new();
-        let attr_vars = self.gather_attr_vars_created_since(0);
-
-        for (_, addr) in self.heap_locs.iter() {
-            let iter = self.acyclic_pre_order_iter(addr.clone());
-
-            for value in iter {
-                match value {
-                    HeapCellValue::Addr(Addr::HeapCell(h)) => {
-                        query_vars.insert(Addr::HeapCell(h));
-                    }
-                    HeapCellValue::Addr(Addr::StackCell(fr, sc)) => {
-                        query_vars.insert(Addr::StackCell(fr, sc));
-                    }
-                    HeapCellValue::Addr(Addr::AttrVar(h)) => {
-                        query_vars.insert(Addr::AttrVar(h));
-                    }
-                    _ => {}
-                };
-            }
-        }
-
-        let query_var_list = Addr::HeapCell(self.heap.to_list(query_vars.into_iter()));
-        let attr_var_list = Addr::HeapCell(self.heap.to_list(attr_vars));
-
-        (query_var_list, attr_var_list)
-    }
-
     pub(super) fn verify_attr_interrupt(&mut self, p: usize) {
         self.allocate(self.num_of_args + 2);
 
@@ -149,57 +118,4 @@ impl MachineState {
         self.b0 = self.b;
         self.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
     }
-
-    fn print_attribute_goals_string(&mut self, op_dir: &OpDir) -> String {
-        let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
-
-        if attr_goals.is_empty() {
-            return String::from("");
-        }
-
-        attr_goals.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
-        self.term_dedup(&mut attr_goals);
-
-        let mut output = PrinterOutputter::new();
-
-        for goal_addr in attr_goals {
-            let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
-            printer.see_all_locs();
-
-            printer.numbervars = false;
-            printer.quoted = true;
-
-            output = printer.print(goal_addr);
-            output.append(", ");
-        }
-
-        // cut trailing ", "
-        let output_len = output.len();
-        output.truncate(output_len - 2);
-
-        output.result()
-    }
-}
-
-impl Machine {
-    pub fn attribute_goals(&mut self) -> String {
-        let p = self.machine_st.attr_var_init.project_attrs_loc;
-        let (query_vars, attr_vars) = self.machine_st.populate_project_attr_lists();
-
-        self.machine_st.allocate(0);
-
-        self.machine_st[temp_v!(1)] = query_vars;
-        self.machine_st[temp_v!(2)] = attr_vars;
-
-        self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(p));
-        self.machine_st.query_stepper(
-            &mut self.indices,
-            &mut self.policies,
-            &mut self.code_repo,
-            &mut readline::input_stream(),
-        );
-               
-        self.machine_st
-            .print_attribute_goals_string(&self.indices.op_dir)
-    }
 }
index 25ab171a49d47bd4631ecf769c1168333cc32186..0f959a6e74226e0f73aedbe9789835aafea56975 100644 (file)
@@ -243,40 +243,6 @@ fn compile_query(
     Ok((code, cg.take_vars()))
 }
 
-fn compile_decl(
-    wam: &mut Machine,
-    compiler: &mut ListingCompiler,
-    decl: Declaration,
-) -> Result<IndexStore, SessionError> {
-    let flags = wam.machine_flags();
-    let mut indices = default_index_store!(wam.indices.atom_tbl.clone());
-
-    compiler.process_decl(decl, wam, &mut indices, flags)?;
-
-    Ok(indices)
-}
-
-pub fn compile_term(wam: &mut Machine, packet: TopLevelPacket) -> EvalSession {
-    match packet {
-        TopLevelPacket::Query(terms, queue) => {
-            match compile_query(terms, queue, wam.machine_flags()) {
-                Ok((code, vars)) => wam.submit_query(code, vars),
-                Err(e) => EvalSession::from(e),
-            }
-        }
-        TopLevelPacket::Decl(TopLevel::Declaration(decl), _) => {
-            let mut compiler = ListingCompiler::new(&wam.code_repo, false, clause_name!("user"));
-            let indices = try_eval_session!(compile_decl(wam, &mut compiler, decl));
-
-            try_eval_session!(wam.check_toplevel_code(&indices));
-            add_toplevel_code(wam, vec![], indices);
-
-            EvalSession::EntrySuccess
-        }
-        _ => EvalSession::from(SessionError::UserPrompt),
-    }
-}
-
 fn add_hooks_to_mockup(
     code_repo: &mut CodeRepo,
     hook: CompileTimeHook,
index fe6483032620430d65ce36116d5c8e22d18610a2..6ef4ed9f971b5f2cf7ed2d7ec19666ccf336955b 100644 (file)
@@ -537,15 +537,11 @@ pub enum SessionError {
     NamelessEntry,
     OpIsInfixAndPostFix(ClauseName),
     ParserError(ParserError),
-    UserPrompt,
 }
 
 pub enum EvalSession {
     EntrySuccess,
     Error(SessionError),
-    InitialQuerySuccess(AllocVarDict),
-    QueryFailure,
-    SubsequentQuerySuccess,
 }
 
 impl From<SessionError> for EvalSession {
index 40fda8a7b7702559cc1898bac8811a42c8ee577b..ef3b7d2c21e1b906e1a394fa47736cef48e9ec06 100644 (file)
@@ -300,7 +300,6 @@ pub enum DynamicTransactionType {
 #[derive(Clone, Copy, PartialOrd, Ord, PartialEq, Eq)]
 pub enum REPLCodePtr {
     CompileBatch,
-    SubmitQueryAndPrintResults,
     UseModule,
     UseQualifiedModule,
     UseModuleFromFile,
@@ -468,13 +467,7 @@ pub struct IndexStore {
     pub(super) op_dir: OpDir,
 }
 
-impl IndexStore {
-    pub fn reset_global_variable_offsets(&mut self) {
-        for (_, ref mut offset) in self.global_variables.values_mut() {
-            *offset = None;
-        }
-    }
-    
+impl IndexStore {    
     pub fn predicate_exists(
         &self,
         name: ClauseName,
index 318d8c135d376ddb9f4a9ab0435097bf331b8fcd..8bcd20188c399c4412517ac5d75696fbf3450bf2 100644 (file)
@@ -318,7 +318,7 @@ impl MachineState {
         Ok(codes)
     }
 
-    fn call_at_index(&mut self, arity: usize, p: usize) {
+    pub(super) fn call_at_index(&mut self, arity: usize, p: usize) {
         self.cp.assign_if_local(self.p.clone() + 1);
         self.num_of_args = arity;
         self.b0 = self.b;
index 0bbdcf38cdb2657c9ab476d3903307b282d8b90f..7392d65c234246a1f6884a99edab990000308a7a 100644 (file)
@@ -6,7 +6,6 @@ use crate::prolog::arithmetic::*;
 use crate::prolog::clause_types::*;
 use crate::prolog::forms::*;
 use crate::prolog::heap_iter::*;
-use crate::prolog::heap_print::*;
 use crate::prolog::instructions::*;
 use crate::prolog::machine::INTERRUPT;
 use crate::prolog::machine::and_stack::*;
@@ -27,7 +26,6 @@ use indexmap::{IndexMap, IndexSet};
 use std::cmp::{max, min, Ordering};
 use std::f64;
 use std::mem;
-use std::rc::Rc;
 
 macro_rules! try_numeric_result {
     ($s: ident, $e: expr, $caller: expr) => {{
@@ -208,39 +206,6 @@ impl MachineState {
         }
     }
 
-    pub(super) fn print_var_eq<Outputter>(
-        &self,
-        var: Rc<Var>,
-        addr: Addr,
-        op_dir: &OpDir,
-        mut output: Outputter,
-    ) -> Outputter
-    where
-        Outputter: HCValueOutputter,
-    {
-        let orig_len = output.len();
-
-        output.begin_new_var();
-
-        output.append(var.as_str());
-        output.append(" = ");
-
-        let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
-
-        printer.numbervars = false;
-        printer.quoted = true;
-
-        let mut output = printer.print(addr);
-
-        let bad_ending = format!("= {}", &var);
-
-        if output.ends_with(&bad_ending) {
-            output.truncate(orig_len);
-        }
-
-        output
-    }
-
     pub(super) fn unify_strings(
         &mut self,
         pdl: &mut Vec<Addr>,
index ecf15caaa7b9b11a85c0f8f3932f054c0c5a0acd..f97afc2048aa0d05a30124d1a9b804377241cfc5 100644 (file)
@@ -2,13 +2,11 @@ use prolog_parser::ast::*;
 use prolog_parser::tabled_rc::*;
 
 use crate::prolog::clause_types::*;
-use crate::prolog::fixtures::*;
 use crate::prolog::forms::*;
 use crate::prolog::heap_print::*;
 use crate::prolog::instructions::*;
 use crate::prolog::machine::heap::Heap;
 use crate::prolog::read::*;
-use crate::prolog::write::{next_keypress, ContinueResult};
 
 mod and_stack;
 mod attributed_variables;
@@ -36,21 +34,18 @@ use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 use crate::prolog::machine::machine_state::*;
 use crate::prolog::machine::modules::*;
-use crate::prolog::machine::toplevel::stream_to_toplevel;
 use crate::prolog::read::PrologStream;
 
 use indexmap::IndexMap;
 
 use std::collections::VecDeque;
 use std::fs::File;
-use std::io::{stdout, Read, Write};
+use std::io::Read;
 use std::mem;
 use std::ops::Index;
 use std::rc::Rc;
 use std::sync::atomic::AtomicBool;
 
-use termion::raw::IntoRawMode;
-
 pub struct MachinePolicies {
     call_policy: Box<dyn CallPolicy>,
     cut_policy: Box<dyn CutPolicy>,
@@ -198,10 +193,23 @@ impl Machine {
         }
     }
 
-    fn compile_top_level(&mut self) {
+    fn compile_top_level(&mut self) -> Result<(), SessionError>
+    {
         self.toplevel_idx = self.code_repo.code.len();
         compile_user_module(self, parsing_stream(TOPLEVEL.as_bytes()),
                             true, clause_name!("toplevel.pl"));
+
+        if let Some(module) = self.indices.take_module(clause_name!("$toplevel")) {
+            self.indices.use_module(
+                &mut self.code_repo,
+                self.machine_st.flags,
+                &module,
+            )?;
+
+            Ok(self.indices.insert_module(module))
+        } else {
+            Err(SessionError::ModuleNotFound)
+        }
     }
 
     fn compile_scryerrc(&mut self) {
@@ -235,7 +243,7 @@ impl Machine {
        self.machine_st.reset();
 
        self.code_repo.cached_query = code;
-       self.run_query(&AllocVarDict::new());
+       self.run_query();
 
         let result = self.machine_st.fail;
        self.absorb_snapshot(old_machine_st);
@@ -261,7 +269,7 @@ impl Machine {
        self.machine_st[temp_v!(1)] = list_addr;
         self.machine_st.p = CodePtr::Local(LocalCodePtr::DirEntry(self.toplevel_idx));
 
-        self.run_query(&AllocVarDict::new());
+        self.run_query();
     }
 
     pub fn new(prolog_stream: PrologStream) -> Self {
@@ -296,7 +304,10 @@ impl Machine {
         compile_user_module(&mut wam, parsing_stream(SI.as_bytes()), true,
                             clause_name!("si"));
 
-        wam.compile_top_level();
+        if wam.compile_top_level().is_err() {
+            panic!("Loading '$toplevel' module failed");
+        }
+        
         wam.compile_scryerrc();
 
         wam
@@ -378,17 +389,6 @@ impl Machine {
         self.code_repo.code.extend(code.into_iter());
     }
 
-    pub fn submit_query(&mut self, code: Code, alloc_locs: AllocVarDict) -> EvalSession {
-        self.code_repo.cached_query = code;
-        self.run_query(&alloc_locs);
-
-        if self.machine_st.fail {
-            EvalSession::QueryFailure
-        } else {
-            EvalSession::InitialQuerySuccess(alloc_locs)
-        }
-    }
-
     fn throw_session_error(&mut self, err: SessionError, key: PredicateKey) {
         let h = self.machine_st.heap.h;
 
@@ -537,6 +537,7 @@ impl Machine {
                     self.throw_session_error(e, (clause_name!("repl"), 0));
                 }
             }
+            /*
             REPLCodePtr::SubmitQueryAndPrintResults => {
                 let term = self.machine_st[temp_v!(1)].clone();
                 let stub = MachineError::functor_stub(clause_name!("repl"), 0);
@@ -593,6 +594,7 @@ impl Machine {
                 self.indices.reset_global_variable_offsets();
                 self.policies = policies;
             }
+            */
            REPLCodePtr::UseModule =>
                self.use_module(ModuleSource::Library),
            REPLCodePtr::UseModuleFromFile =>
@@ -662,20 +664,7 @@ impl Machine {
         self.machine_st.lifted_heap = mem::replace(&mut snapshot.lifted_heap, vec![]);
     }
 
-    fn propagate_exception_to_toplevel(&mut self, snapshot: MachineState) {
-        let ball = self.machine_st.ball.take();
-
-        self.absorb_snapshot(snapshot);
-        self.machine_st.ball = ball;
-
-        let h = self.machine_st.heap.h;
-        let stub = self.machine_st.ball.copy_and_align(h);
-
-        self.machine_st.throw_exception(stub);
-
-        return;
-    }
-
+/*
     fn handle_eval_session(&mut self, result: EvalSession, snapshot: MachineState) {
         match result {
             EvalSession::InitialQuerySuccess(alloc_locs) => loop {
@@ -795,24 +784,13 @@ impl Machine {
 
         self.absorb_snapshot(snapshot);
     }
+*/
 
-    pub(super) fn run_query(&mut self, alloc_locs: &AllocVarDict) {
+    pub(super) fn run_query(&mut self) {
        self.machine_st.cp = LocalCodePtr::TopLevel(0, self.code_repo.size_of_cached_query());
         let end_ptr = CodePtr::Local(self.machine_st.cp);
 
         while self.machine_st.p < end_ptr {
-            if let CodePtr::Local(LocalCodePtr::TopLevel(mut cn, p)) = self.machine_st.p {
-                match &self.code_repo[LocalCodePtr::TopLevel(cn, p)] {
-                    &Line::Control(ref ctrl_instr) if ctrl_instr.is_jump_instr() => {
-                        self.machine_st.record_var_places(cn, alloc_locs);
-                        cn += 1;
-                    }
-                    _ => {}
-                }
-
-                self.machine_st.p = top_level_code_ptr!(cn, p);
-            }
-
             self.machine_st.query_stepper(
                 &mut self.indices,
                 &mut self.policies,
@@ -831,63 +809,18 @@ impl Machine {
                     self.dynamic_transaction(trans_type, p);
 
                     if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
-                        if self.machine_st.heap_locs.is_empty() {
-                            self.machine_st.record_var_places(0, alloc_locs);
-                        }
-
                         self.code_repo.cached_query = cached_query;
                         break;
                     }
 
                     self.code_repo.cached_query = cached_query;
                 }
-                _ => {
-                    if self.machine_st.heap_locs.is_empty() {
-                        self.machine_st.record_var_places(0, alloc_locs);
-                    }
-
-                    break;
-                }
+                _ =>
+                    break                
             };
         }
     }
 
-    pub fn continue_query(&mut self, alloc_locs: &AllocVarDict) -> EvalSession {
-        if !self.or_stack_is_empty() {
-            let b = self.machine_st.b - 1;
-            self.machine_st.p = self.machine_st.or_stack[b].bp.clone();
-
-            if let CodePtr::Local(LocalCodePtr::TopLevel(_, 0)) = self.machine_st.p {
-                self.machine_st.fail = true;
-                return EvalSession::QueryFailure;
-            }
-
-            self.run_query(alloc_locs);
-
-            if self.machine_st.fail {
-                EvalSession::QueryFailure
-            } else {
-                EvalSession::SubsequentQuerySuccess
-            }
-        } else {
-            EvalSession::QueryFailure
-        }
-    }
-
-    pub fn toplevel_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
-    where
-        Outputter: HCValueOutputter,
-    {
-        for (var, addr) in self.machine_st.heap_locs.iter() {
-            let addr = self.machine_st.store(self.machine_st.deref(addr.clone()));
-            output = self
-                .machine_st
-                .print_var_eq(var.clone(), addr, &self.indices.op_dir, output);
-        }
-
-        output
-    }
-
     #[cfg(test)]
     pub fn test_heap_view<Outputter>(&self, mut output: Outputter) -> Outputter
     where
@@ -904,63 +837,9 @@ impl Machine {
 
         output
     }
-
-    pub fn or_stack_is_empty(&self) -> bool {
-        self.machine_st.b == 0
-    }
 }
 
 impl MachineState {
-    fn record_var_places(&mut self, chunk_num: usize, alloc_locs: &AllocVarDict) {
-        for (var, var_data) in alloc_locs {
-            match var_data {
-                &VarData::Perm(p) if p > 0 => {
-                    if !self.heap_locs.contains_key(var) {
-                        let e = self.e;
-                        let r = var_data.as_reg_type().reg_num();
-                        let addr = self.and_stack[e][r].clone();
-
-                        self.heap_locs.insert(var.clone(), addr);
-                    }
-                }
-                &VarData::Temp(cn, _, _) if cn == chunk_num => {
-                    let r = var_data.as_reg_type();
-
-                    if r.reg_num() != 0 {
-                        let addr = self[r].clone();
-                        self.heap_locs.insert(var.clone(), addr);
-                    }
-                }
-                _ => {}
-            }
-        }
-    }
-
-    fn print_query(&mut self, addr: Addr, op_dir: &OpDir) -> PrinterOutputter {
-        let flags = self.flags;
-
-        let mut output = {
-            self.flags = MachineFlags {
-                double_quotes: DoubleQuotes::Atom,
-            };
-
-            let output = PrinterOutputter::new();
-            let mut printer = HCPrinter::from_heap_locs(&self, op_dir, output);
-
-            printer.quoted = true;
-            printer.numbervars = false;
-            printer.drop_toplevel_spec();
-
-            printer.see_all_locs();
-            printer.print(addr)
-        };
-
-        self.flags = flags;
-
-        output.append(".");
-        output
-    }
-
     fn dispatch_instr(
         &mut self,
         instr: &Line,
index 3b399f98358a8dc4a71fe490a451cfbec2d0efa0..7349bdf5095e3e8a4f68602d89a4b475f5cfd546 100644 (file)
@@ -1,10 +1,9 @@
-driver(QueryVars, AttrVars) :-
+'$attribute_goals_driver'(QueryVars, AttrVars) :-
     gather_modules(AttrVars, Modules0, _),
     sort(Modules0, Modules),
     call_project_attributes(Modules, QueryVars, AttrVars),
     call_attribute_goals(Modules, call_query_var_goals, QueryVars),
-    call_attribute_goals(Modules, call_attr_var_goals, AttrVars),
-    '$return_from_attribute_goals'.
+    call_attribute_goals(Modules, call_attr_var_goals, AttrVars).
 
 enqueue_goals(Goals0) :-
     nonvar(Goals0),
index 483ceeebd1a357ec957c9160cd958c6d998eafbd..cd49431310b951a9b58b600aa8f9cd2026b37cea 100644 (file)
@@ -22,11 +22,34 @@ use crate::ref_thread_local::RefThreadLocal;
 use indexmap::{IndexMap, IndexSet};
 
 use std::collections::VecDeque;
-use std::io::{stdout, Write};
+use std::io::{stdin, stdout, Write};
 use std::iter::once;
 use std::mem;
 use std::rc::Rc;
 
+use crate::termion::event::Key;
+use crate::termion::input::TermRead;
+use crate::termion::raw::IntoRawMode;
+
+pub enum ContinueResult {
+    ContinueQuery,
+    Conclude,
+}
+
+pub fn next_keypress() -> ContinueResult {
+    let stdin = stdin();
+
+    for c in stdin.keys() {
+        match c.unwrap() {
+            Key::Char(' ') | Key::Char(';') => return ContinueResult::ContinueQuery,
+            Key::Char('.') => return ContinueResult::Conclude,
+            _ => {}
+        }
+    }
+
+    ContinueResult::Conclude
+}
+
 struct BrentAlgState {
     hare: usize,
     tortoise: usize,
@@ -716,6 +739,17 @@ impl MachineState {
 
                 self.unify(a2, Addr::Con(Constant::Integer(len)));
             }
+            &SystemClauseType::CallAttributeGoals => {
+                let p = self.attr_var_init.project_attrs_loc;
+
+                if self.last_call {
+                    self.execute_at_index(2, p);
+                } else {
+                    self.call_at_index(2, p);
+                }
+
+                return Ok(());
+            }
             &SystemClauseType::CharsToNumber => {
                 let stub = MachineError::functor_stub(clause_name!("number_chars"), 2);
 
@@ -1329,6 +1363,17 @@ impl MachineState {
             &SystemClauseType::TruncateIfNoLiftedHeapGrowth => {
                 self.truncate_if_no_lifted_heap_diff(|_| Addr::Con(Constant::EmptyList))
             }
+            &SystemClauseType::FetchAttributeGoals => {
+                let mut attr_goals = mem::replace(&mut self.attr_var_init.attribute_goals, vec![]);
+
+                attr_goals.sort_unstable_by(|a1, a2| self.compare_term_test(a1, a2));
+                self.term_dedup(&mut attr_goals);
+
+                let attr_goals = Addr::HeapCell(self.heap.to_list(attr_goals.into_iter()));
+                let target = self[temp_v!(1)].clone();
+
+                self.unify(attr_goals, target);
+            }
             &SystemClauseType::GetAttributedVariableList => {
                 let attr_var = self.store(self.deref(self[temp_v!(1)].clone()));
                 let attr_var_list = match attr_var {
@@ -1370,6 +1415,18 @@ impl MachineState {
 
                         self.unify(var_list_addr, list_addr);
                     }
+                    Addr::Con(Constant::Integer(n)) => {
+                        if let Some(b) = n.to_usize() {
+                            let iter = self.gather_attr_vars_created_since(b);
+
+                            let var_list_addr = Addr::HeapCell(self.heap.to_list(iter));
+                            let list_addr = self[temp_v!(2)].clone();
+                            
+                            self.unify(var_list_addr, list_addr);
+                        } else {
+                            self.fail = true;
+                        }
+                    }
                     _ => self.fail = true,
                 }
             }
@@ -1685,11 +1742,6 @@ impl MachineState {
                 self.p = CodePtr::DynamicTransaction(trans_type, p);
                 return Ok(());
             }
-            &SystemClauseType::ReturnFromAttributeGoals => {
-                self.deallocate();                
-                self.p = CodePtr::Local(LocalCodePtr::TopLevel(0, 0));
-                return Ok(());
-            }
             &SystemClauseType::ReturnFromVerifyAttr => {
                 let e = self.e;
                 let frame_len = self.and_stack[e].len();
@@ -1839,6 +1891,21 @@ impl MachineState {
             &SystemClauseType::InstallNewBlock => {
                 self.install_new_block(temp_v!(1));
             }
+            &SystemClauseType::RawInputReadChar => {
+               let keypress = {
+                   let mut raw_stdout = stdout().into_raw_mode().unwrap();
+                   raw_stdout.flush().unwrap();
+                   next_keypress()
+               };
+
+                let c = match keypress {
+                    ContinueResult::ContinueQuery => ';',
+                    ContinueResult::Conclude => '.'
+                };
+
+                let target = self[temp_v!(1)].clone();
+                self.unify(Addr::Con(Constant::Char(c)), target);
+            }
             &SystemClauseType::ReadQueryTerm => {
                 readline::set_prompt(true);
                 let result = self.read_term(current_input_stream, indices);
index d2bc1362ac36e5e9a5245cde07e9380d227f72ec..1c45b49ed99a872d0c18e16b01486a16a6c39d98 100644 (file)
@@ -136,11 +136,6 @@ impl<'a, R: Read> TermStream<'a, R> {
     pub fn top_level_terms(&mut self) -> Vec<(Term, usize, usize)> {
         mem::replace(&mut self.top_level_terms, vec![])
     }
-    
-    #[inline]
-    pub fn add_to_top(&mut self, buf: &str) {
-        self.parser.add_to_top(buf);
-    }
 
     #[inline]
     pub fn incr_expansion_lens(&mut self, hook: CompileTimeHook, len: usize, queue_len: usize) {
index c54e05152e0fac83d84d700a611f7e9d25f800a6..542dd13181ccb913edd4c18a0fa99b6933642cee 100644 (file)
@@ -303,13 +303,6 @@ fn is_consistent(tl: &TopLevel, clauses: &Vec<PredicateClause>) -> bool {
     }
 }
 
-fn deque_to_packet(head: TopLevel, deque: VecDeque<TopLevel>) -> TopLevelPacket {
-    match head {
-        TopLevel::Query(query) => TopLevelPacket::Query(query, deque),
-        tl => TopLevelPacket::Decl(tl, deque),
-    }
-}
-
 fn merge_clauses(tls: &mut VecDeque<TopLevel>) -> Result<TopLevel, ParserError> {
     let mut clauses: Vec<PredicateClause> = vec![];
 
@@ -496,11 +489,6 @@ fn setup_declaration<'a, 'b, 'c, R: Read>(
     }
 }
 
-pub enum TopLevelPacket {
-    Query(Vec<QueryTerm>, VecDeque<TopLevel>),
-    Decl(TopLevel, VecDeque<TopLevel>),
-}
-
 struct RelationWorker {
     flags: MachineFlags,
     dynamic_clauses: Vec<(Term, Term)>, // Head, Body.
@@ -902,39 +890,6 @@ impl RelationWorker {
     }
 }
 
-pub fn stream_to_toplevel<R: Read>(
-    mut buffer: ParsingStream<R>,
-    wam: &mut Machine,
-) -> Result<TopLevelPacket, SessionError> {
-    let flags = wam.machine_flags();
-    let mut term_stream = TermStream::new(
-        &mut buffer,
-        wam.indices.atom_tbl(),
-        wam.machine_flags(),
-        wam,
-    );
-
-    term_stream.add_to_top("?- ");
-
-    let term = term_stream.read_term(&OpDir::new())?;
-    let mut code_dir = CodeDir::new();
-
-    let line_num = term_stream.line_num();
-    let col_num  = term_stream.col_num();
-
-    let mut rel_worker = RelationWorker::new(flags, line_num, col_num);
-    let mut indices = CompositeIndices::new(
-        &mut term_stream,
-        IndexSource::TermStream,
-        Some(IndexSource::Local(&mut code_dir))
-    );
-
-    let tl = rel_worker.try_term_to_tl(&mut indices, term, true)?;
-    let queue = rel_worker.parse_queue(&mut indices)?;
-
-    Ok(deque_to_packet(tl, queue))
-}
-
 pub type DynamicClauseMap = IndexMap<(ClauseName, usize), Vec<(Term, Term)>>;
 
 pub struct TopLevelBatchWorker<'a, R: Read> {
index ec17b8e105607ee72488c6b9b9d028a27e889cef..0db0299969ba96a5d2c91896a85fe492882e01e5 100644 (file)
@@ -262,12 +262,6 @@ macro_rules! put_constant {
     };
 }
 
-macro_rules! top_level_code_ptr {
-    ($p:expr, $q_sz:expr) => {
-        CodePtr::Local(LocalCodePtr::TopLevel($p, $q_sz))
-    };
-}
-
 macro_rules! get_level_and_unify {
     ($r: expr) => {
         Line::Cut(CutInstruction::GetLevelAndUnify($r))
index 26b5a8626d58e1511a022f31d463beb9e11a93cb..d8e36a3d074db60c415435b66fa6a8adbcfd38a6 100644 (file)
@@ -1,12 +1,13 @@
-/*
- *  inserting the modules should not result in the insertion of
- *  code. this is because they're already loaded by this point -- see
- *  Machine::new.
-*/
+:- module('$toplevel', ['$repl'/1, consult/1, use_module/1, use_module/2]).
 
 :- use_module(library(lists)).
 :- use_module(library(si)).
 
+% internal operators defined for spacing purposes.
+:- op(1200, xf, ('.')).
+:- op(700, xfx, (' = ')).
+:- op(1000, xfy, (', ')).
+
 '$repl'(ListOfModules) :-
     maplist('$use_list_of_modules', ListOfModules),
     false.
     '$submit_query_and_print_results'(Term, VarList),
     !.
 
+'$submit_query_and_print_results'(Term0, VarList) :-
+    (  expand_goals(Term0, Term) -> true
+    ;  Term = Term0
+    ),
+    (  '$get_b_value'(B), call(Term), '$write_eqs_and_read_input'(B, VarList), !
+    ;  write('false.'), nl
+    ).
+
+'$write_eqs_and_read_input'(B, VarList) :-
+    sort(VarList, SortedVarList),
+    '$get_b_value'(B0),
+    '$gather_goals'(SortedVarList, VarList, Goals),
+    (  B0 == B ->
+       (  Goals == [] ->
+         write('true.'), nl
+       ;  thread_goals(Goals, ThreadedGoals, (', ')),
+         write_term((ThreadedGoals)., [quoted(false), variable_names(VarList)]),
+         nl
+       )
+    ;  repeat,
+       thread_goals(Goals, ThreadedGoals, (', ')),
+       write_term(ThreadedGoals, [quoted(false), variable_names(VarList)]),
+       '$raw_input_read_char'(C),
+       (  C == (';'), !,
+         write_term(' ;', [quoted(false)]), nl, false
+       ;  C == ('.'), !,
+         write_term(' ...', [quoted(false)]), nl
+       )
+    ).
+
+'$gather_query_vars'([_ = Var | Vars], QueryVars) :-
+    (  var(Var) ->
+       QueryVars = [Var | QueryVars1],
+       '$gather_query_vars'(Vars, QueryVars1)
+    ;  '$gather_query_vars'(Vars, QueryVars)
+    ).
+'$gather_query_vars'([], []).
+
+'$gather_goals'([], VarList, Goals) :-
+    '$get_attr_var_queue_beyond'(0, AttrVars),
+    '$gather_query_vars'(VarList, QueryVars),
+    '$call_attribute_goals'(QueryVars, AttrVars),
+    '$fetch_attribute_goals'(Goals).
+'$gather_goals'([Var = Value | Pairs], VarList, Goals) :-
+    (  nonvar(Value) ->
+       Goals = [Var ' = ' Value | Goals0],
+       '$gather_goals'(Pairs, VarList, Goals0)
+    ;  '$gather_goals'(Pairs, VarList, Goals)
+    ).
+
 '$print_exception'(E) :-
     write_term('caught: ', [quoted(false)]),
     writeq(E),
@@ -102,40 +153,50 @@ user:term_expansion(Term0, (:- initialization(ExpandedGoals))) :-
     expand_goals(Goals, ExpandedGoals),
     Goals \== ExpandedGoals.
 
-expand_goals(Goals, ExpandedGoals) :-
-    nonvar(Goals),
+expand_goals(UnexpandedGoals, ExpandedGoals) :-
+    nonvar(UnexpandedGoals),
     var(ExpandedGoals),
+    (  expand_goal(UnexpandedGoals, Goals) -> true
+    ;  Goals = UnexpandedGoals
+    ),
     (  Goals = (Goal0, Goals0) ->
        (  expand_goal(Goal0, Goal1) ->
          Expanded = true,
          expand_goals(Goals0, Goals1),
-         thread_goals(Goal1, ExpandedGoals, Goals1)
+         thread_goals(Goal1, ExpandedGoals, Goals1, (','))
        ;  expand_goals(Goals0, Goals1),
          ExpandedGoals = (Goal0, Goals1)
        )
-    ;  expand_goal(Goals, ExpandedGoals0) ->
-       thread_goals(ExpandedGoals0, ExpandedGoals)
+    ;  Goals = (Goals0 -> Goals1) ->
+       expand_goals(Goals0, ExpandedGoals0),
+       expand_goals(Goals1, ExpandedGoals1),
+       ExpandedGoals = (ExpandedGoals0 -> ExpandedGoals1)
+    ;  Goals = (Goals0 ; Goals1) ->
+       expand_goals(Goals0, ExpandedGoals0),
+       expand_goals(Goals1, ExpandedGoals1),
+       ExpandedGoals = (ExpandedGoals0 ; ExpandedGoals1)
+    ;  thread_goals(Goals, ExpandedGoals, (','))
     ;  Goals = ExpandedGoals
     ).
 
-thread_goals(Goals0, Goals1, Hole) :-
+thread_goals(Goals0, Goals1, Hole, Functor) :-
     nonvar(Goals0),
     (  Goals0 = [G | Gs] ->
        (  Gs == [] ->
-         Goals1 = (G, Hole)
-       ;  Goals1 = (G, Goals2),
-         thread_goals(Gs, Goals2, Hole)
+         Goals1 =.. [Functor, G, Hole]
+       ;  Goals1 =.. [Functor, G, Goals2],
+         thread_goals(Gs, Goals2, Hole, Functor)
        )
-    ;  Goals1 = (Goals0, Hole)
+    ;  Goals1 =.. [Functor, Goals0, Hole]
     ).
 
-thread_goals(Goals0, Goals1) :-
+thread_goals(Goals0, Goals1, Functor) :-
     nonvar(Goals0),
     (  Goals0 = [G | Gs] ->
        (  Gs = [] ->
          Goals1 = G
-       ;  Goals1 = (G, Goals2),
-         thread_goals(Gs, Goals2)
+       ;  Goals1 =.. [Functor, G, Goals2],
+         thread_goals(Gs, Goals2, Functor)
        )
     ;  Goals1 = Goals0
     ).
index 03a884c8a3679e10589117933b3c4098c22175ba..2d552522bd7b7d1f260a922107dd8ef8a3402c4a 100644 (file)
@@ -4,11 +4,7 @@ use crate::prolog::instructions::*;
 use crate::prolog::machine::machine_errors::*;
 use crate::prolog::machine::machine_indices::*;
 
-use termion::event::Key;
-use termion::input::TermRead;
-
 use std::fmt;
-use std::io::stdin;
 
 impl fmt::Display for LocalCodePtr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
@@ -29,10 +25,8 @@ impl fmt::Display for LocalCodePtr {
 impl fmt::Display for REPLCodePtr {
     fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
         match self {
-            REPLCodePtr::CompileBatch => write!(f, "REPLCodePtr::CompileBatch"),
-            REPLCodePtr::SubmitQueryAndPrintResults => {
-                write!(f, "REPLCodePtr::SubmitQueryAndPrintResults")
-            }
+            REPLCodePtr::CompileBatch =>
+                write!(f, "REPLCodePtr::CompileBatch"),
            REPLCodePtr::UseModule =>
                write!(f, "REPLCodePtr::UseModule"),
            REPLCodePtr::UseQualifiedModule =>
@@ -275,7 +269,6 @@ impl fmt::Display for SessionError {
                 write!(f, "the predicate head is not an atom or clause.")
             }
             &SessionError::ParserError(ref e) => write!(f, "syntax_error({})", e.as_str()),
-            &SessionError::UserPrompt => write!(f, "enter predicate at [user] prompt"),
         }
     }
 }
@@ -422,22 +415,3 @@ impl fmt::Display for Level {
         }
     }
 }
-
-pub enum ContinueResult {
-    ContinueQuery,
-    Conclude,
-}
-
-pub fn next_keypress() -> ContinueResult {
-    let stdin = stdin();
-
-    for c in stdin.keys() {
-        match c.unwrap() {
-            Key::Char(' ') | Key::Char(';') => return ContinueResult::ContinueQuery,
-            Key::Char('.') => return ContinueResult::Conclude,
-            _ => {}
-        }
-    }
-
-    ContinueResult::Conclude
-}