From: Mark Thom Date: Wed, 9 May 2018 04:38:49 +0000 (-0600) Subject: shift to builtins X-Git-Tag: v0.8.110~465^2~16 X-Git-Url: https://git.sagredo.dev/?a=commitdiff_plain;h=b09c20670b075eeb983c0f4781be4a95c04e5186;p=scryer-prolog.git shift to builtins --- diff --git a/src/main.rs b/src/main.rs index da05f866..1e4a7e29 100644 --- a/src/main.rs +++ b/src/main.rs @@ -1,6 +1,7 @@ #[macro_use] extern crate downcast; extern crate termion; +#[macro_use] mod prolog; use prolog::ast::*; @@ -10,6 +11,7 @@ use prolog::machine::*; #[cfg(test)] mod tests; +pub static BUILTINS: &str = include_str!("./prolog/lib/builtins.pl"); pub static LISTS: &str = include_str!("./prolog/lib/lists.pl"); pub static CONTROL: &str = include_str!("./prolog/lib/control.pl"); pub static QUEUES: &str = include_str!("./prolog/lib/queues.pl"); @@ -33,12 +35,19 @@ fn load_init_str(wam: &mut Machine, src_str: &str) } } +fn load_init_str_and_include(wam: &mut Machine, src_str: &str, module: &'static str) +{ + load_init_str(wam, src_str); + wam.use_module_in_toplevel(clause_name!(module)); +} + fn prolog_repl() { let mut wam = Machine::new(); - load_init_str(&mut wam, LISTS); - load_init_str(&mut wam, CONTROL); - load_init_str(&mut wam, QUEUES); + load_init_str_and_include(&mut wam, BUILTINS, "builtins"); +// load_init_str(&mut wam, LISTS); +// load_init_str(&mut wam, CONTROL); +// load_init_str(&mut wam, QUEUES); loop { print!("prolog> "); diff --git a/src/prolog/ast.rs b/src/prolog/ast.rs index d3dcfc2c..969c587d 100644 --- a/src/prolog/ast.rs +++ b/src/prolog/ast.rs @@ -192,11 +192,13 @@ pub trait SubModuleUser { // returns true on successful import. fn import_decl(&mut self, name: ClauseName, arity: usize, submodule: &Module) -> bool { let name = name.defrock_brackets(); - + let mut found_op = false; + { let mut insert_op_dir = |fix| { if let Some(op_data) = submodule.op_dir.get(&(name.clone(), fix)) { self.op_dir().insert((name.clone(), fix), op_data.clone()); + found_op = true; } }; @@ -212,7 +214,7 @@ pub trait SubModuleUser { self.insert_dir_entry(name, arity, code_data.clone()); true } else { - false + found_op } } @@ -227,7 +229,7 @@ pub trait SubModuleUser { return EvalSession::from(SessionError::ModuleDoesNotContainExport); } } - + EvalSession::EntrySuccess } @@ -594,7 +596,7 @@ impl InlinedClauseType { (">", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThan)), ("<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThan)), (">=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::GreaterThanOrEqual)), - ("<=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)), + ("=<", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::LessThanOrEqual)), ("=\\=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::NotEqual)), ("=:=", 2) => Some(InlinedClauseType::CompareNumber(CompareNumberQT::Equal)), ("atom", 1) => Some(InlinedClauseType::IsAtom), @@ -808,14 +810,14 @@ impl ClauseType { pub fn name(&self) -> ClauseName { match self { - &ClauseType::AcyclicTerm => clause_name!("$acyclic_term"), + &ClauseType::AcyclicTerm => clause_name!("acyclic_term"), &ClauseType::Arg => clause_name!("arg"), &ClauseType::CallN => clause_name!("call"), &ClauseType::CallWithInferenceLimit => clause_name!("call_with_inference_limit"), &ClauseType::Catch => clause_name!("catch"), &ClauseType::Compare => clause_name!("compare"), &ClauseType::CompareTerm(qt) => clause_name!(qt.name()), - &ClauseType::CyclicTerm => clause_name!("$cyclic_term"), + &ClauseType::CyclicTerm => clause_name!("cyclic_term"), &ClauseType::Display => clause_name!("display"), &ClauseType::DuplicateTerm => clause_name!("duplicate_term"), &ClauseType::Eq => clause_name!("=="), @@ -823,26 +825,30 @@ impl ClauseType { &ClauseType::Ground => clause_name!("ground"), &ClauseType::Inlined(inlined) => clause_name!(inlined.name()), &ClauseType::Is => clause_name!("is"), - &ClauseType::KeySort => clause_name!("$keysort"), + &ClauseType::KeySort => clause_name!("keysort"), &ClauseType::NotEq => clause_name!("\\=="), &ClauseType::Op(ref name, ..) => name.clone(), &ClauseType::Named(ref name, ..) => name.clone(), &ClauseType::SetupCallCleanup => clause_name!("setup_call_cleanup"), &ClauseType::System(ref system) => system.name(), - &ClauseType::Sort => clause_name!("$sort"), + &ClauseType::Sort => clause_name!("sort"), &ClauseType::Throw => clause_name!("throw") } } pub fn from(name: ClauseName, arity: usize, fixity: Option) -> Self { + if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), arity) { + return ClauseType::Inlined(inlined_ct); + } + match (name.as_str(), arity) { - ("$acyclic_term", 1) => ClauseType::AcyclicTerm, + ("acyclic_term", 1) => ClauseType::AcyclicTerm, ("arg", 3) => ClauseType::Arg, ("call", _) => ClauseType::CallN, ("call_with_inference_limit", 3) => ClauseType::CallWithInferenceLimit, ("catch", 3) => ClauseType::Catch, ("compare", 3) => ClauseType::Compare, - ("$cyclic_term", 1) => ClauseType::CyclicTerm, + ("cyclic_term", 1) => ClauseType::CyclicTerm, ("@>", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThan), ("@<", 2) => ClauseType::CompareTerm(CompareTermQT::LessThan), ("@>=", 2) => ClauseType::CompareTerm(CompareTermQT::GreaterThanOrEqual), @@ -855,10 +861,10 @@ impl ClauseType { ("functor", 3) => ClauseType::Functor, ("ground", 1) => ClauseType::Ground, ("is", 2) => ClauseType::Is, - ("$keysort", 2) => ClauseType::KeySort, + ("keysort", 2) => ClauseType::KeySort, ("\\==", 2) => ClauseType::NotEq, ("setup_call_cleanup", 3) => ClauseType::SetupCallCleanup, - ("$sort", 2) => ClauseType::Sort, + ("sort", 2) => ClauseType::Sort, ("throw", 1) => ClauseType::Throw, _ => if let Some(fixity) = fixity { ClauseType::Op(name, fixity, CodeIndex::default()) diff --git a/src/prolog/builtins.rs b/src/prolog/builtins.rs index 6633904c..0222ecf7 100644 --- a/src/prolog/builtins.rs +++ b/src/prolog/builtins.rs @@ -739,17 +739,17 @@ fn get_builtins() -> Code { ] } -pub fn build_code_and_op_dirs() -> (CodeDir, OpDir) +pub fn default_op_dir() -> OpDir { - let mut code_dir = HashMap::new(); - let mut op_dir = HashMap::new(); - - let builtin = ClauseName::BuiltIn("builtin"); - - op_dir.insert((clause_name!(":-"), Fixity::In), (XFX, 1200, builtin.clone())); - op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX, 1200, builtin.clone())); - op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX, 1200, builtin.clone())); - + let mut op_dir = HashMap::new(); + let module_name = clause_name!("builtins"); + + op_dir.insert((clause_name!(":-"), Fixity::In), (XFX, 1200, module_name.clone())); + op_dir.insert((clause_name!(":-"), Fixity::Pre), (FX, 1200, module_name.clone())); + op_dir.insert((clause_name!("?-"), Fixity::Pre), (FX, 1200, module_name.clone())); + // op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400, module_name.clone())); + +/* // control operators. op_dir.insert((clause_name!("\\+"), Fixity::Pre), (FY, 900, builtin.clone())); op_dir.insert((clause_name!("="), Fixity::In), (XFX, 700, builtin.clone())); @@ -761,8 +761,7 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir) op_dir.insert((clause_name!("/\\"), Fixity::In), (YFX, 500, builtin.clone())); op_dir.insert((clause_name!("\\/"), Fixity::In), (YFX, 500, builtin.clone())); op_dir.insert((clause_name!("xor"), Fixity::In), (YFX, 500, builtin.clone())); - op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400, builtin.clone())); - op_dir.insert((clause_name!("/"), Fixity::In), (YFX, 400, builtin.clone())); + op_dir.insert((clause_name!("//"), Fixity::In), (YFX, 400, builtin.clone())); op_dir.insert((clause_name!("div"), Fixity::In), (YFX, 400, builtin.clone())); op_dir.insert((clause_name!("*"), Fixity::In), (YFX, 400, builtin.clone())); op_dir.insert((clause_name!("-"), Fixity::Pre), (FY, 200, builtin.clone())); @@ -819,7 +818,7 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir) code_dir.insert((clause_name!("integer"), 1), CodeIndex::from((163, builtin.clone()))); code_dir.insert((clause_name!("display"), 1), CodeIndex::from((208, builtin.clone()))); - code_dir.insert((clause_name!("is"), 2), CodeIndex::from((210, builtin.clone()))); + //code_dir.insert((clause_name!("is"), 2), CodeIndex::from((210, builtin.clone()))); code_dir.insert((clause_name!(">"), 2), CodeIndex::from((212, builtin.clone()))); code_dir.insert((clause_name!("<"), 2), CodeIndex::from((214, builtin.clone()))); code_dir.insert((clause_name!(">="), 2), CodeIndex::from((216, builtin.clone()))); @@ -851,14 +850,13 @@ pub fn build_code_and_op_dirs() -> (CodeDir, OpDir) code_dir.insert((clause_name!("\\=@="), 2), CodeIndex::from((408, builtin.clone()))); code_dir.insert((clause_name!("compare"), 3), CodeIndex::from((480, builtin.clone()))); code_dir.insert((clause_name!("atom"), 1), CodeIndex::from((481, builtin.clone()))); - code_dir.insert((clause_name!("sort"), 2), CodeIndex::from((483, builtin.clone()))); - code_dir.insert((clause_name!("keysort"), 2), CodeIndex::from((484, builtin.clone()))); - code_dir.insert((clause_name!("acyclic_term"), 1), CodeIndex::from((485, builtin.clone()))); - code_dir.insert((clause_name!("cyclic_term"), 1), CodeIndex::from((486, builtin.clone()))); (code_dir, op_dir) + */ + op_dir } +/* pub fn default_build() -> (Code, CodeDir, OpDir) { let builtin_code = get_builtins(); @@ -866,64 +864,4 @@ pub fn default_build() -> (Code, CodeDir, OpDir) (builtin_code, code_dir, op_dir) } - -#[allow(dead_code)] -pub fn builtin_module() -> Module -{ - let (code_dir, op_dir) = build_code_and_op_dirs(); - let mut module_decl = module_decl!(clause_name!("builtin"), - vec![(clause_name!("atomic"), 1), - (clause_name!("var"), 1), - (clause_name!("false"), 0), - (clause_name!("catch"), 3), - (clause_name!("throw"), 1), - (clause_name!("(\\+)"), 1), - (clause_name!("duplicate_term"), 2), - (clause_name!("(=)"), 2), - (clause_name!("true"), 0), - (clause_name!("(,)"), 2), - (clause_name!("(;)"), 2), - (clause_name!("->"), 2), - (clause_name!("functor"), 3), - (clause_name!("arg"), 3), - (clause_name!("(=..)"), 3), - (clause_name!("display"), 1), - (clause_name!("is"), 2), - (clause_name!("(>)"), 2), - (clause_name!("(<)"), 2), - (clause_name!("(>=)"), 2), - (clause_name!("(=<)"), 2), - (clause_name!("(=\\=)"), 2), - (clause_name!("(=:=)"), 2), - (clause_name!("(@>)"), 2), - (clause_name!("(@<)"), 2), - (clause_name!("(@>=)"), 2), - (clause_name!("(@=<)"), 2), - (clause_name!("(=@=)"), 2), - (clause_name!("(\\=@=)"), 2), - (clause_name!("(==)"), 2), - (clause_name!("(\\==)"), 2), - (clause_name!("length"), 2), - (clause_name!("compound"), 1), - (clause_name!("rational"), 1), - (clause_name!("integer"), 1), - (clause_name!("string"), 1), - (clause_name!("float"), 1), - (clause_name!("nonvar"), 1), - (clause_name!("ground"), 1), - (clause_name!("setup_call_cleanup"), 3), - (clause_name!("call_with_inference_limit"), 3), - (clause_name!("compare"), 3), - (clause_name!("atom"), 1), - (clause_name!("sort"), 2), - (clause_name!("keysort"), 2), - (clause_name!("acyclic_term"), 1), - (clause_name!("cyclic_term"), 1), - (clause_name!("$skip_max_list"), 4)]); - - for arity in 0 .. 63 { - module_decl.exports.push((clause_name!("call"), arity)); - } - - Module { module_decl, code_dir: as_module_code_dir(code_dir), op_dir } -} +*/ diff --git a/src/prolog/io.rs b/src/prolog/io.rs index e51635d3..eceacfa1 100644 --- a/src/prolog/io.rs +++ b/src/prolog/io.rs @@ -550,7 +550,7 @@ fn compile_query(terms: Vec, queue: Vec, code_size: usize, let mut code = try!(cg.compile_query(&terms)); compile_appendix(&mut code, queue)?; - + let query_info = QueryInfo {}; query_info.label_clauses(code_size, code_dir, &mut code); @@ -617,7 +617,9 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession } let mut module: Option = None; - let (mut code_dir, mut op_dir) = build_code_and_op_dirs(); + + let mut code_dir = CodeDir::new(); + let mut op_dir = default_op_dir(); let mut code = Vec::new(); @@ -630,10 +632,10 @@ pub fn compile_listing(wam: &mut Machine, src_str: &str) -> EvalSession return EvalSession::from(ParserError::ExpectedRel), TopLevelPacket::Decl(TopLevel::Declaration(Declaration::Module(module_decl)), _) => if module.is_none() { - let (builtin_code_dir, builtin_op_dir) = build_code_and_op_dirs(); + // let builtin_op_dir = default_module_setup(module_decl.name.clone()); - code_dir.extend(builtin_code_dir.into_iter()); - op_dir.extend(builtin_op_dir.into_iter()); + // code_dir.extend(builtin_code_dir.into_iter()); + // op_dir.extend(builtin_op_dir.into_iter()); module = Some(Module::new(module_decl)); } else { diff --git a/src/prolog/machine/machine_errors.rs b/src/prolog/machine/machine_errors.rs index e16111d8..984cf4d2 100644 --- a/src/prolog/machine/machine_errors.rs +++ b/src/prolog/machine/machine_errors.rs @@ -141,6 +141,8 @@ impl MachineState { self.heap.append(err); self.registers[1] = Addr::HeapCell(h); - self.goto_throw(); + + self.set_ball(); + self.unwind_stack(); } } diff --git a/src/prolog/machine/machine_state.rs b/src/prolog/machine/machine_state.rs index 90b80afc..f9dad13e 100644 --- a/src/prolog/machine/machine_state.rs +++ b/src/prolog/machine/machine_state.rs @@ -434,10 +434,16 @@ pub(crate) trait CallPolicy: Any { }, &ClauseType::CallN => if let Some((name, arity)) = machine_st.setup_call_n(arity) { - if let Some(idx) = code_dirs.get(name.clone(), arity, clause_name!("user")) { - self.context_call(machine_st, name, arity, idx, lco) - } else { - Err(machine_st.existence_error(name, arity)) + let user = clause_name!("user"); + + match ClauseType::from(name.clone(), arity, None) { + ClauseType::Op(..) | ClauseType::Named(..) => + if let Some(idx) = code_dirs.get(name.clone(), arity, user) { + self.context_call(machine_st, name, arity, idx, lco) + } else { + Err(machine_st.existence_error(name, arity)) + }, + ct => self.try_call_clause(machine_st, code_dirs, &ct, arity, lco), } } else { Ok(()) diff --git a/src/prolog/machine/machine_state_impl.rs b/src/prolog/machine/machine_state_impl.rs index 35534955..5665eea2 100644 --- a/src/prolog/machine/machine_state_impl.rs +++ b/src/prolog/machine/machine_state_impl.rs @@ -1041,7 +1041,15 @@ impl MachineState { self.p = CodePtr::DirEntry(59, clause_name!("builtin")); } - fn unwind_stack(&mut self) { + pub(super) fn set_ball(&mut self) { + let addr = self[temp_v!(1)].clone(); + self.ball.boundary = self.heap.h; + + let mut duplicator = DuplicateBallTerm::new(self); + duplicator.duplicate_term(addr); + } + + pub(super) fn unwind_stack(&mut self) { self.b = self.block; self.or_stack.truncate(self.b); @@ -1614,14 +1622,7 @@ impl MachineState { self.p += 1; }, &BuiltInInstruction::SetBall => { - let addr = self[temp_v!(1)].clone(); - self.ball.boundary = self.heap.h; - - { - let mut duplicator = DuplicateBallTerm::new(self); - duplicator.duplicate_term(addr); - }; - + self.set_ball(); self.p += 1; }, &BuiltInInstruction::SetCutPoint(r) => diff --git a/src/prolog/machine/mod.rs b/src/prolog/machine/mod.rs index 5df7085c..5377949e 100644 --- a/src/prolog/machine/mod.rs +++ b/src/prolog/machine/mod.rs @@ -70,14 +70,15 @@ impl<'a> SubModuleUser for MachineCodeIndex<'a> { impl Machine { pub fn new() -> Self { let atom_tbl = Rc::new(RefCell::new(HashSet::new())); - let (code, code_dir, op_dir) = default_build(); + let op_dir = default_op_dir(); //TODO: change to the builtins module once it's done. + //let (code, code_dir, op_dir) = default_build(); Machine { ms: MachineState::new(atom_tbl), call_policy: Box::new(DefaultCallPolicy {}), cut_policy: Box::new(DefaultCutPolicy {}), - code, - code_dir, + code: Code::new(), + code_dir: CodeDir::new(), term_dir: TermDir::new(), op_dir, modules: HashMap::new(), diff --git a/src/prolog/parser b/src/prolog/parser index 1b3bcc77..51e38dd2 160000 --- a/src/prolog/parser +++ b/src/prolog/parser @@ -1 +1 @@ -Subproject commit 1b3bcc77f2b9d264c9753653ae87bfa3b4c11081 +Subproject commit 51e38dd24252431432ec7deb5ad80e2fc11a5753 diff --git a/src/prolog/toplevel.rs b/src/prolog/toplevel.rs index abab0688..3c122dfc 100644 --- a/src/prolog/toplevel.rs +++ b/src/prolog/toplevel.rs @@ -393,17 +393,13 @@ impl RelationWorker { if name.as_str() == "!" || name.as_str() == "blocked_!" { Ok(QueryTerm::BlockedCut) } else { - Ok(QueryTerm::Clause(r, ClauseType::Named(name, CodeIndex::default()), - vec![])) + Ok(QueryTerm::Clause(r, ClauseType::Named(name, CodeIndex::default()), vec![])) }, Term::Var(_, ref v) if v.as_str() == "!" => Ok(QueryTerm::UnblockedCut(Cell::default())), Term::Clause(r, name, mut terms, fixity) => if let Some(system_ct) = SystemClauseType::from(name.as_str(), terms.len()) { Ok(QueryTerm::Clause(r, ClauseType::System(system_ct), terms)) - } - else if let Some(inlined_ct) = InlinedClauseType::from(name.as_str(), terms.len()) { - Ok(QueryTerm::Clause(r, ClauseType::Inlined(inlined_ct), terms)) } else if name.as_str() == ";" { if terms.len() == 2 { let term = Term::Clause(r, name.clone(), terms, fixity); @@ -612,7 +608,10 @@ impl TopLevelWorker { }; } - results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?)); + if !preds.is_empty() { + results.push(deque_to_packet(append_preds(&mut preds), rel_worker.parse_queue()?)); + } + Ok(results) }