shift to builtins

This commit is contained in:
Mark Thom
2018-05-08 22:38:49 -06:00
parent 24d6fb16a8
commit b09c20670b
10 changed files with 86 additions and 122 deletions

View File

@@ -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> ");

View File

@@ -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<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),
@@ -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())

View File

@@ -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 }
}
*/

View File

@@ -550,7 +550,7 @@ fn compile_query(terms: Vec<QueryTerm>, queue: Vec<TopLevel>, 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<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();
@@ -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 {

View File

@@ -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();
}
}

View File

@@ -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(())

View File

@@ -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) =>

View File

@@ -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(),

View File

@@ -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<R: Read> TopLevelWorker<R> {
};
}
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)
}