#[macro_use] extern crate downcast;
extern crate termion;
+#[macro_use]
mod prolog;
use prolog::ast::*;
#[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");
}
}
+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> ");
// 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;
}
};
self.insert_dir_entry(name, arity, code_data.clone());
true
} else {
- false
+ found_op
}
}
return EvalSession::from(SessionError::ModuleDoesNotContainExport);
}
}
-
+
EvalSession::EntrySuccess
}
(">", 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),
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!("=="),
&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<Fixity>) -> 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),
("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())
]
}
-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()));
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()));
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())));
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();
(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 }
-}
+*/
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);
}
let mut module: Option<Module> = 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();
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 {
self.heap.append(err);
self.registers[1] = Addr::HeapCell(h);
- self.goto_throw();
+
+ self.set_ball();
+ self.unwind_stack();
}
}
},
&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(())
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);
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) =>
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(),
-Subproject commit 1b3bcc77f2b9d264c9753653ae87bfa3b4c11081
+Subproject commit 51e38dd24252431432ec7deb5ad80e2fc11a5753
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);
};
}
- 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)
}