move to a predicate-based module system, move to loader.[rs|pl]-based compilation, add support for incremental clause compilation

This commit is contained in:
Mark Thom
2021-01-30 14:32:47 -07:00
parent b33158b92e
commit a4d15bfb88
55 changed files with 10501 additions and 7601 deletions

View File

@@ -6,14 +6,16 @@ use crate::clause_types::*;
use crate::forms::*;
use crate::heap_print::*;
use crate::instructions::*;
use crate::machine;
use crate::machine::code_repo::CodeRepo;
use crate::machine::copier::*;
use crate::machine::code_walker::*;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::machine::machine_state::*;
use crate::machine::preprocessor::to_op_decl;
use crate::machine::streams::*;
use crate::machine::toplevel::to_op_decl;
use crate::ordered_float::OrderedFloat;
use crate::read::readline;
use crate::rug::Integer;
@@ -402,9 +404,7 @@ impl MachineState {
}
}
let mode =
atom_from!(self, indices, self.store(self.deref(self[temp_v!(2)])));
let mode = atom_from!(self, self.store(self.deref(self[temp_v!(2)])));
let mut open_options = fs::OpenOptions::new();
let (is_input_file, in_append_mode) =
@@ -560,7 +560,7 @@ impl MachineState {
let spec = get_clause_spec(
name.clone(),
*arity,
composite_op!(&indices.op_dir),
&CompositeOpDir::new(&indices.op_dir, None),
);
let addr = self.heap.to_unifiable(HeapCellValue::DBRef(
@@ -681,11 +681,11 @@ impl MachineState {
let mut parser = Parser::new(
&mut stream,
indices.atom_tbl.clone(),
self.atom_tbl.clone(),
self.machine_flags(),
);
match parser.read_term(composite_op!(&indices.op_dir)) {
match parser.read_term(&CompositeOpDir::new(&indices.op_dir, None)) {
Err(err) => {
let h = self.heap.h();
let err = MachineError::syntax_error(h, err);
@@ -792,6 +792,7 @@ impl MachineState {
current_output_stream: &mut Stream,
) -> CallResult {
match ct {
/*
&SystemClauseType::AbolishClause => {
let p = self.cp;
let trans_type = DynamicTransactionType::Abolish;
@@ -806,6 +807,7 @@ impl MachineState {
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
}
*/
&SystemClauseType::BindFromRegister => {
let reg = self.store(self.deref(self[temp_v!(2)]));
let n =
@@ -833,6 +835,7 @@ impl MachineState {
self.fail = true;
}
/*
&SystemClauseType::AssertDynamicPredicateToFront => {
let p = self.cp;
let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Front);
@@ -841,19 +844,21 @@ impl MachineState {
return Ok(());
}
&SystemClauseType::AssertDynamicPredicateToBack => {
let p = self.cp;
let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Back);
// let p = self.cp;
// let trans_type = DynamicTransactionType::Assert(DynamicAssertPlace::Back);
self.p = CodePtr::DynamicTransaction(trans_type, p);
// self.p = CodePtr::DynamicTransaction(trans_type, p);
self.p = CodePtr::REPL(REPLCodePtr::UserAssertz, self.cp);
return Ok(());
}
*/
&SystemClauseType::CurrentHostname => {
match hostname::get().ok() {
Some(host) => {
match host.into_string().ok() {
Some(host) => {
let hostname = self.heap.to_unifiable(
HeapCellValue::Atom(clause_name!(host, indices.atom_tbl), None)
HeapCellValue::Atom(clause_name!(host, self.atom_tbl), None)
);
self.unify(self[temp_v!(1)], hostname);
@@ -1016,6 +1021,7 @@ impl MachineState {
return Err(err);
}
};
let chars = self.heap.put_complete_string(current);
self.unify(self[temp_v!(1)], chars);
@@ -1092,11 +1098,13 @@ impl MachineState {
return Ok(());
}
}
/*
&SystemClauseType::AtEndOfExpansion => {
if self.cp == LocalCodePtr::TopLevel(0, 0) {
self.at_end_of_expansion = true;
}
}
*/
&SystemClauseType::AtomChars => {
let a1 = self[temp_v!(1)];
@@ -1139,7 +1147,7 @@ impl MachineState {
if &string == "[]" {
self.unify(addr, Addr::EmptyList);
} else {
let chars = clause_name!(string, indices.atom_tbl);
let chars = clause_name!(string, self.atom_tbl);
let atom = self.heap.to_unifiable(
HeapCellValue::Atom(chars, None)
);
@@ -1254,7 +1262,7 @@ impl MachineState {
}
let string = self.heap.to_unifiable(
HeapCellValue::Atom(clause_name!(chars, indices.atom_tbl), None)
HeapCellValue::Atom(clause_name!(chars, self.atom_tbl), None)
);
self.bind(addr.as_var().unwrap(), string);
@@ -1281,7 +1289,7 @@ impl MachineState {
clause_name!("[]")
}
Addr::Char(c) => {
clause_name!(c.to_string(), indices.atom_tbl)
clause_name!(c.to_string(), self.atom_tbl)
}
_ => {
unreachable!()
@@ -1858,6 +1866,7 @@ impl MachineState {
}
}
}
/*
&SystemClauseType::ModuleAssertDynamicPredicateToFront => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleAssert(DynamicAssertPlace::Front);
@@ -1872,6 +1881,7 @@ impl MachineState {
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
}
*/
&SystemClauseType::LiftedHeapLength => {
let a1 = self[temp_v!(1)];
let lh_len = Addr::Usize(self.lifted_heap.h());
@@ -2854,6 +2864,7 @@ impl MachineState {
self.unify(Addr::Char(c), a1);
}
/*
&SystemClauseType::GetModuleClause => {
let module = self[temp_v!(3)];
let head = self[temp_v!(1)];
@@ -2944,20 +2955,24 @@ impl MachineState {
_ => unreachable!(),
};
}
*/
&SystemClauseType::HeadIsDynamic => {
let head = self[temp_v!(1)];
let module_name = atom_from!(
self,
self.store(self.deref(
self[temp_v!(1)]
))
);
self.fail = !match self.store(self.deref(head)) {
self.fail = !match self.store(self.deref(self[temp_v!(2)])) {
Addr::Str(s) => match &self.heap[s] {
&HeapCellValue::NamedStr(arity, ref name, ..) => indices
.get_clause_subsection(name.owning_module(), name.clone(), arity)
.is_some(),
&HeapCellValue::NamedStr(arity, ref name, ..) =>
indices.is_dynamic_predicate(module_name, (name.clone(), arity)),
_ => unreachable!(),
},
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(name, _) = &self.heap[h] {
indices.get_clause_subsection(name.owning_module(), name.clone(), 0)
.is_some()
if let HeapCellValue::Atom(name, _) = &self.heap[h] {
indices.is_dynamic_predicate(module_name, (name.clone(), 0))
} else {
unreachable!()
}
@@ -3111,21 +3126,27 @@ impl MachineState {
return self.module_lookup(
indices,
call_policy,
(name, arity + narity),
module_name,
true,
current_input_stream,
current_output_stream,
);
} else {
unreachable!()
}
}
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(name, _) = self.heap.clone(h) {
if let HeapCellValue::Atom(name, _) = self.heap.clone(h) {
return self.module_lookup(
indices,
call_policy,
(name.clone(), narity),
module_name,
true,
current_input_stream,
current_output_stream,
);
} else {
unreachable!()
@@ -3160,6 +3181,7 @@ impl MachineState {
}
}
}
/*
&SystemClauseType::ExpandGoal => {
self.p = CodePtr::Local(LocalCodePtr::UserGoalExpansion(0));
return Ok(());
@@ -3168,6 +3190,7 @@ impl MachineState {
self.p = CodePtr::Local(LocalCodePtr::UserTermExpansion(0));
return Ok(());
}
*/
&SystemClauseType::GetNextDBRef => {
let a1 = self[temp_v!(1)];
@@ -3185,7 +3208,7 @@ impl MachineState {
let spec = get_clause_spec(
name.clone(),
*arity,
composite_op!(&indices.op_dir),
&CompositeOpDir::new(&indices.op_dir, None),
);
let db_ref = DBRef::NamedPred(name.clone(), *arity, spec);
@@ -3429,7 +3452,7 @@ impl MachineState {
let op = match self.store(self.deref(op)) {
Addr::Char(c) =>
clause_name!(c.to_string(), indices.atom_tbl),
clause_name!(c.to_string(), self.atom_tbl),
Addr::Con(h) if self.heap.atom_at(h) =>
if let HeapCellValue::Atom(ref name, _) = &self.heap[h] {
name.clone()
@@ -3440,16 +3463,18 @@ impl MachineState {
unreachable!(),
};
let module = op.owning_module();
let result = to_op_decl(priority, specifier.as_str(), op)
.map_err(SessionError::from)
.and_then(|op_decl| {
if op_decl.0 == 0 {
.and_then(|mut op_decl| {
if op_decl.prec == 0 {
Ok(op_decl.remove(&mut indices.op_dir))
} else {
let spec = get_desc(op_decl.name(), composite_op!(&indices.op_dir));
op_decl.submit(module, spec, &mut indices.op_dir)
let spec = get_op_desc(
op_decl.name.clone(),
&CompositeOpDir::new(&indices.op_dir, None),
);
op_decl.submit(spec, &mut indices.op_dir)
}
});
@@ -3493,10 +3518,10 @@ impl MachineState {
let mut heap_pstr_iter =
self.heap_pstr_iter(Addr::PStrLocation(h, n));
let file_spec =
let file_spec =
clause_name!(
heap_pstr_iter.to_string(),
indices.atom_tbl.clone()
self.atom_tbl
);
self.stream_from_file_spec(file_spec, indices, &options)?
@@ -3901,65 +3926,18 @@ impl MachineState {
}
};
}
&SystemClauseType::ModuleOf => {
let module = self.store(self.deref(self[temp_v!(2)]));
match module {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(name, _) = self.heap.clone(h) {
let module = self.heap.to_unifiable(
HeapCellValue::Atom(
name.owning_module(),
None
),
);
let target = self[temp_v!(1)];
self.unify(target, module);
} else {
unreachable!()
}
}
Addr::Str(s) => match self.heap.clone(s) {
HeapCellValue::NamedStr(_, name, ..) => {
let module = self.heap.to_unifiable(
HeapCellValue::Atom(
name.owning_module(),
None
),
);
let target = self[temp_v!(1)];
self.unify(target, module);
}
HeapCellValue::Addr(addr) if addr.is_ref() => {
let err = MachineError::uninstantiation_error(addr);
let stub = MachineError::functor_stub(
clause_name!("$module_of"),
2,
);
return Err(self.error_form(err, stub));
}
_ => {
unreachable!()
}
},
_ => {
self.fail = true;
}
};
}
&SystemClauseType::NoSuchPredicate => {
let head = self[temp_v!(1)];
let module_name = atom_from!(self, self.store(self.deref(self[temp_v!(1)])));
self.fail = match self.store(self.deref(head)) {
self.fail = match self.store(self.deref(self[temp_v!(2)])) {
Addr::Str(s) => match &self.heap[s] {
&HeapCellValue::NamedStr(arity, ref name, ref spec) => {
let module = name.owning_module();
indices.predicate_exists(name.clone(), module, arity, spec.clone())
indices.get_predicate_code_index(
name.clone(),
arity,
module_name,
spec.clone(),
).is_some()
}
_ => {
unreachable!()
@@ -3967,14 +3945,14 @@ impl MachineState {
},
Addr::Con(h) if self.heap.atom_at(h) => {
if let &HeapCellValue::Atom(ref name, ref spec) = &self.heap[h] {
let module = name.owning_module();
let spec = fetch_atom_op_spec(
name.clone(),
spec.clone(),
&indices.op_dir,
);
indices.predicate_exists(name.clone(), module, 0, spec)
indices.get_predicate_code_index(name.clone(), 0, module_name, spec)
.is_some()
} else {
unreachable!()
}
@@ -4116,6 +4094,7 @@ impl MachineState {
&SystemClauseType::REPL(repl_code_ptr) => {
return self.repl_redirect(repl_code_ptr);
}
/*
&SystemClauseType::ModuleRetractClause => {
let p = self.cp;
let trans_type = DynamicTransactionType::ModuleRetract;
@@ -4130,6 +4109,7 @@ impl MachineState {
self.p = CodePtr::DynamicTransaction(trans_type, p);
return Ok(());
}
*/
&SystemClauseType::ReturnFromVerifyAttr => {
let e = self.e;
let frame_len = self.stack.index_and_frame(e).prelude.univ_prelude.num_cells;
@@ -4326,6 +4306,7 @@ impl MachineState {
self.unify(a1, a2);
}
/*
&SystemClauseType::GetClause => {
let head = self[temp_v!(1)];
@@ -4343,14 +4324,14 @@ impl MachineState {
}
},
Addr::Con(h) if self.heap.atom_at(h) => {
if let &HeapCellValue::Atom(ref name, _) = &self.heap[h] {
if let &HeapCellValue::Atom(ref name, _) = &self.heap[h] {
indices.get_clause_subsection(
name.owning_module(),
name.clone(),
0,
)
} else {
unreachable!()
unreachable!()
}
}
_ => {
@@ -4372,6 +4353,7 @@ impl MachineState {
}
}
}
*/
&SystemClauseType::GetCutPoint => {
let a1 = self[temp_v!(1)];
let a2 = Addr::CutPoint(self.b0);
@@ -4524,7 +4506,7 @@ impl MachineState {
let term_write_result =
match self.read(
Stream::from(chars),
indices.atom_tbl.clone(),
self.atom_tbl.clone(),
&indices.op_dir,
) {
Ok(term_write_result) => {
@@ -4595,10 +4577,11 @@ impl MachineState {
let mut rand = RANDOM_STATE.borrow_mut();
rand.seed(&seed);
}
&SystemClauseType::SkipMaxList =>
&SystemClauseType::SkipMaxList => {
if let Err(err) = self.skip_max_list() {
return Err(err);
},
}
}
&SystemClauseType::Sleep => {
let time = self.store(self.deref(self[temp_v!(1)]));
@@ -4695,11 +4678,10 @@ impl MachineState {
let stream =
match TcpStream::connect(&socket_addr).map_err(|e| e.kind()) {
Ok(tcp_stream) => {
let socket_addr = clause_name!(socket_addr, indices.atom_tbl.clone());
let socket_addr = clause_name!(socket_addr, self.atom_tbl);
let mut stream =
{ let tls = match self.store(self.deref(self[temp_v!(8)])) {
let mut stream = {
let tls = match self.store(self.deref(self[temp_v!(8)])) {
Addr::Con(h) if self.heap.atom_at(h) => {
if let HeapCellValue::Atom(ref atom, _) = &self.heap[h] {
atom.as_str()
@@ -4711,6 +4693,7 @@ impl MachineState {
unreachable!()
}
};
match tls {
"false" => { Stream::from_tcp_stream(socket_addr, tcp_stream) }
"true" => { let connector = TlsConnector::new().unwrap();
@@ -4724,6 +4707,7 @@ impl MachineState {
_ => { unreachable!() }
}
};
stream.options = options;
if let Some(ref alias) = &stream.options.alias {
@@ -4877,7 +4861,7 @@ impl MachineState {
match tcp_listener.accept().ok() {
Some((tcp_stream, socket_addr)) => {
let client =
clause_name!(format!("{}", socket_addr), indices.atom_tbl);
clause_name!(format!("{}", socket_addr), self.atom_tbl);
let mut tcp_stream =
Stream::from_tcp_stream(client.clone(), tcp_stream);
@@ -5226,8 +5210,13 @@ impl MachineState {
self.fail = self.structural_eq_test();
}
&SystemClauseType::WAMInstructions => {
let name = self[temp_v!(1)];
let arity = self[temp_v!(2)];
let module_name = atom_from!(
self,
self.store(self.deref(self[temp_v!(1)]))
);
let name = self[temp_v!(2)];
let arity = self[temp_v!(3)];
let name = match self.store(self.deref(name)) {
Addr::Con(h) if self.heap.atom_at(h) => {
@@ -5257,51 +5246,84 @@ impl MachineState {
}
};
let first_idx = match indices
.code_dir
.get(&(name.clone(), arity.to_usize().unwrap()))
{
Some(ref idx) if idx.local().is_some() => {
if let Some(idx) = idx.local() {
idx
} else {
unreachable!()
let key = (name.clone(), arity.to_usize().unwrap());
let first_idx = match module_name.as_str() {
"user" => indices.code_dir.get(&key),
_ => match indices.modules.get(&module_name) {
Some(module) => module.code_dir.get(&key),
None => {
let stub = MachineError::functor_stub(key.0, key.1);
let h = self.heap.h();
let err = MachineError::session_error(
h,
SessionError::from(
CompilationError::InvalidModuleResolution(
module_name
)
),
);
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
}
}
_ => {
let arity = arity.to_usize().unwrap();
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h();
let err = MachineError::existence_error(
h,
ExistenceError::Procedure(name, arity),
);
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
}
},
};
let first_idx =
match first_idx {
Some(ref idx) if idx.local().is_some() => {
if let Some(idx) = idx.local() {
idx
} else {
unreachable!()
}
}
_ => {
let arity = arity.to_usize().unwrap();
let stub = MachineError::functor_stub(name.clone(), arity);
let h = self.heap.h();
let err = MachineError::existence_error(
h,
ExistenceError::Procedure(name, arity),
);
let err = self.error_form(err, stub);
self.throw_exception(err);
return Ok(());
}
};
let mut h = self.heap.h();
let mut functors = vec![];
let mut functor_list = vec![];
walk_code(
&code_repo.code,
first_idx,
|instr| {
let section = instr.to_functor(h);
functors.push(Addr::HeapCell(h));
let old_len = functors.len();
instr.enqueue_functors(h, &mut functors);
let new_len = functors.len();
h += section.len();
self.heap.extend(section.into_iter());
for index in old_len .. new_len {
functor_list.push(Addr::HeapCell(h));
h += functors[index].len();
}
},
);
let listing = Addr::HeapCell(self.heap.to_list(functors.into_iter()));
let listing_var = self[temp_v!(3)];
for functor in functors {
self.heap.extend(functor.into_iter());
}
let listing = Addr::HeapCell(self.heap.to_list(functor_list.into_iter()));
let listing_var = self[temp_v!(4)];
self.unify(listing, listing_var);
}
@@ -5831,6 +5853,53 @@ impl MachineState {
self.unify(self[temp_v!(2)], cstr);
}
}
&SystemClauseType::LoadLibraryAsStream => {
let library_name =
atom_from!(
self,
self.store(self.deref(self[temp_v!(1)]))
);
use crate::LIBRARIES;
match LIBRARIES.borrow().get(library_name.as_str()) {
Some(library) => {
let var_ref = Ref::HeapCell(self.heap.push(
HeapCellValue::Stream(Stream::from(*library))
));
self.bind(var_ref, self[temp_v!(2)]);
let mut path_buf = machine::current_dir();
path_buf.push("/lib");
path_buf.push(library_name.as_str());
let library_path_str = path_buf.to_str().unwrap();
let library_path =
clause_name!(library_path_str.to_string(), self.atom_tbl);
let library_path_ref = Ref::HeapCell(
self.heap.push(HeapCellValue::Atom(library_path, None))
);
self.bind(library_path_ref, self[temp_v!(3)]);
}
None => {
return Err(
self.error_form(
MachineError::existence_error(
self.heap.h(),
ExistenceError::ModuleSource(
ModuleSource::Library(library_name)
),
),
MachineError::functor_stub(clause_name!("load"), 1),
)
);
}
}
}
};
return_from_clause!(self.last_call, self)
@@ -5905,7 +5974,7 @@ impl MachineState {
} else {
let mut avec = Vec::new();
for attr in node.attributes() {
let chars = clause_name!(String::from(attr.name()), indices.atom_tbl);
let chars = clause_name!(String::from(attr.name()), self.atom_tbl);
let name = self.heap.to_unifiable(
HeapCellValue::Atom(chars, None)
);
@@ -5926,7 +5995,7 @@ impl MachineState {
}
let children = Addr::HeapCell(self.heap.to_list(cvec.into_iter()));
let chars = clause_name!(String::from(node.tag_name().name()), indices.atom_tbl);
let chars = clause_name!(String::from(node.tag_name().name()), self.atom_tbl);
let tag = self.heap.to_unifiable(
HeapCellValue::Atom(chars, None)
);
@@ -5955,7 +6024,7 @@ impl MachineState {
Some(name) => {
let mut avec = Vec::new();
for attr in node.attrs() {
let chars = clause_name!(String::from(attr.0), indices.atom_tbl);
let chars = clause_name!(String::from(attr.0), self.atom_tbl);
let name = self.heap.to_unifiable(
HeapCellValue::Atom(chars, None)
);
@@ -5976,7 +6045,7 @@ impl MachineState {
}
let children = Addr::HeapCell(self.heap.to_list(cvec.into_iter()));
let chars = clause_name!(String::from(name), indices.atom_tbl);
let chars = clause_name!(String::from(name), self.atom_tbl);
let tag = self.heap.to_unifiable(
HeapCellValue::Atom(chars, None)
);