Revert "remove Term"

This reverts commit 3b5879841aedecba5057c70c71da0ba23e5cd84a.
This commit is contained in:
Mark Thom
2025-03-15 13:19:26 -07:00
committed by Mark Thom
parent eef7b06919
commit 9e1e99f961
53 changed files with 3726 additions and 4517 deletions

View File

@@ -15,28 +15,12 @@ use crate::types::*;
use indexmap::IndexSet;
use std::cell::Cell;
use std::collections::VecDeque;
use std::convert::TryFrom;
use std::fmt;
use std::ops::{Deref, DerefMut};
impl TermWriteResult {
pub(super) fn from(heap: &mut Heap, value: HeapCellValue) -> Result<Self, usize> {
let focus = heap.index_of(value)?;
let mut stack = Stack::uninitialized();
heap[0] = value;
let inverse_var_locs = inverse_var_locs_from_iter(stackful_preorder_iter::<NonListElider>(
heap, &mut stack, 0,
));
Ok(Self {
focus,
inverse_var_locs,
})
}
}
use std::rc::Rc;
/*
* The loader compiles Prolog terms read from a TermStream instance,
@@ -194,18 +178,18 @@ impl CompilationTarget {
}
pub struct PredicateQueue {
pub predicates: Vec<TermWriteResult>,
pub compilation_target: CompilationTarget,
pub(super) predicates: Vec<Term>,
pub(super) compilation_target: CompilationTarget,
}
impl PredicateQueue {
#[inline]
pub(super) fn push(&mut self, term_write_result: TermWriteResult) {
self.predicates.push(term_write_result);
pub(super) fn push(&mut self, clause: Term) {
self.predicates.push(clause);
}
#[inline]
pub(crate) fn first(&self) -> Option<&TermWriteResult> {
pub(crate) fn first(&self) -> Option<&Term> {
self.predicates.first()
}
@@ -416,7 +400,7 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
#[inline(always)]
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState {
loader.term_stream.lexer_parser.machine_st
loader.term_stream.parser.lexer.machine_st
}
#[inline(always)]
@@ -508,9 +492,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
}
#[inline]
pub(super) fn machine_heap(&mut self) -> &mut Heap {
&mut LS::machine_st(&mut self.payload).heap
pub(crate) fn read_term_from_heap(&mut self, r: RegType) -> Term {
let machine_st = LS::machine_st(&mut self.payload);
let cell = machine_st[r];
machine_st.read_term_from_heap(cell)
}
pub(crate) fn load(mut self) -> Result<LS::Evacuable, SessionError> {
@@ -527,30 +513,18 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let compilation_target = &load_state.compilation_target;
let composite_op_dir = self.wam_prelude.composite_op_dir(compilation_target);
let mut term = load_state.term_stream.next(&composite_op_dir)?;
let predicate_focus_opt = load_state
.predicates
.first()
.map(|term_write_result| term_write_result.focus);
let term = load_state.term_stream.next(&composite_op_dir)?;
let machine_st = LS::machine_st(&mut self.payload);
let term_key_opt = clause_predicate_key(&machine_st.heap, term.focus);
if !term.is_consistent(&load_state.predicates) {
self.compile_and_submit()?;
}
if let Some(predicate_focus) = predicate_focus_opt {
let predicate_key_opt = clause_predicate_key(&machine_st.heap, predicate_focus);
debug_assert!(predicate_key_opt.is_some());
if term_key_opt != predicate_key_opt {
self.compile_and_submit()?;
let term = match term {
Term::Clause(_, name, terms) if name == atom!(":-") && terms.len() == 1 => {
return Ok(Some(setup_declaration(self, terms)?));
}
}
if Some((atom!(":-"), 1)) == term_key_opt {
let machine_st = LS::machine_st(&mut self.payload);
term.focus = term_nth_arg(&machine_st.heap, term.focus, 1).unwrap();
return Ok(Some(setup_declaration(self, term)?));
}
term => term,
};
self.payload.predicates.push(term);
}
@@ -788,7 +762,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
) => {
remove_constant_indices(
constant,
&overlapping_constants,
overlapping_constants,
indexing_code,
clause_loc - index_loc, // WAS: &inner_index_locs,
);
@@ -1071,73 +1045,30 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let machine_st = LS::machine_st(&mut self.payload);
let cell = machine_st[r];
let focus = machine_st.heap.cell_len();
machine_st
.heap
.push_cell(cell)
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
let export_list = FocusedHeapRefMut {
heap: &mut machine_st.heap,
focus,
};
let export_list = machine_st.read_term_from_heap(cell);
let export_list = setup_module_export_list(export_list)?;
Ok(export_list.into_iter().collect())
}
fn clause_clause(&mut self, cell: HeapCellValue) -> Result<TermWriteResult, CompilationError> {
let machine_st = LS::machine_st(&mut self.payload);
let focus = machine_st.heap.cell_len();
fn add_clause_clause(&mut self, term: Term) -> Result<(), CompilationError> {
match term {
Term::Clause(_, atom!(":-"), mut terms) if terms.len() == 2 => {
let body = terms.pop().unwrap();
let head = terms.pop().unwrap();
read_heap_cell!(cell,
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(machine_st.heap[s])
.get_name_and_arity();
let mut writer = machine_st.heap.reserve(4)
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
writer.write_with(|section| {
section.push_cell(str_loc_as_cell!(focus+1));
section.push_cell(atom_as_cell!(atom!("clause"), 2));
match (name, arity) {
(atom!(":-"), 2) => {
section.push_cell(heap_loc_as_cell!(s+1));
section.push_cell(heap_loc_as_cell!(s+2));
}
_ => {
section.push_cell(str_loc_as_cell!(s));
section.push_cell(atom_as_cell!(atom!("true")));
}
}
});
self.payload.clause_clauses.push((head, body));
}
(HeapCellValueTag::Atom, (name, arity)) => {
if arity == 0 {
let mut writer = machine_st.heap.reserve(4)
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
writer.write_with(|section| {
section.push_cell(str_loc_as_cell!(focus+1));
section.push_cell(atom_as_cell!(atom!("clause"), 2));
section.push_cell(atom_as_cell!(name));
section.push_cell(atom_as_cell!(atom!("true")));
});
} else {
return Err(CompilationError::InadmissibleFact);
}
head @ (Term::Clause(..) | Term::Literal(_, Literal::Atom(_))) => {
let body = Term::Literal(Cell::default(), Literal::Atom(atom!("true")));
self.payload.clause_clauses.push((head, body));
}
_ => {
return Err(CompilationError::InadmissibleFact);
}
);
}
Ok(
TermWriteResult::from(&mut machine_st.heap, heap_loc_as_cell!(focus))
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?,
)
Ok(())
}
fn add_extensible_predicate_declaration(
@@ -1355,11 +1286,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
)
}
fn add_clause_clause_if_dynamic(&mut self, value: HeapCellValue) -> Result<(), SessionError> {
let machine_st = LS::machine_st(&mut self.payload);
let key_opt = clause_predicate_key_from_heap(&machine_st.heap, value);
if let Some((predicate_name, predicate_arity)) = key_opt {
fn add_clause_clause_if_dynamic(&mut self, term: &Term) -> Result<(), SessionError> {
if let Some(predicate_name) = ClauseInfo::name(term) {
let predicate_arity = ClauseInfo::arity(term);
let predicates_compilation_target = self.payload.predicates.compilation_target;
let is_dynamic = self
@@ -1373,8 +1302,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.unwrap_or(false);
if is_dynamic {
let clause_clause_term = self.clause_clause(value)?;
self.payload.clause_clauses.push(clause_clause_term);
self.add_clause_clause(term.clone())?;
}
}
@@ -1440,6 +1368,90 @@ impl<'a> MachinePreludeView<'a> {
}
}
impl MachineState {
pub(super) fn read_term_from_heap(&mut self, term_addr: HeapCellValue) -> Term {
let mut term_stack = vec![];
self.heap[0] = term_addr;
let mut iter =
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, 0);
while let Some(addr) = iter.next() {
let addr = unmark_cell_bits!(addr);
if let Ok(literal) = Literal::try_from(addr) {
term_stack.push(Term::Literal(Cell::default(), literal));
} else {
read_heap_cell!(addr,
(HeapCellValueTag::Lis) => {
use crate::parser::parser::as_partial_string;
let tail = term_stack.pop().unwrap();
let head = term_stack.pop().unwrap();
match as_partial_string(head, tail) {
Ok((string, Some(tail))) => {
term_stack.push(Term::PartialString(Cell::default(), Rc::new(string), tail));
}
Ok((string, None)) => {
term_stack.push(Term::CompleteString(Cell::default(), Rc::new(string)));
}
Err(cons_term) => term_stack.push(cons_term),
}
}
(HeapCellValueTag::StackVar, h) => {
term_stack.push(Term::Var(Cell::default(), VarPtr::from(format!("s_{}", h))));
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar, h) => {
term_stack.push(Term::Var(Cell::default(), VarPtr::from(format!("_{}", h))));
}
(HeapCellValueTag::Atom, (name, arity)) => {
let h = iter.focus().value() as usize;
let mut arity = arity;
let value = iter.heap[h.saturating_sub(1)];
if let Some(idx) = get_structure_index(value) {
term_stack.push(Term::Literal(Cell::default(), Literal::CodeIndex(idx)));
arity += 1;
}
if arity == 0 {
term_stack.push(Term::Literal(Cell::default(), Literal::Atom(name)));
} else {
let subterms = term_stack
.drain(term_stack.len() - arity ..)
.collect();
term_stack.push(Term::Clause(Cell::default(), name, subterms));
}
}
(HeapCellValueTag::PStrLoc, h) => {
let HeapStringScan { string, .. } = iter.heap.scan_slice_to_str(h);
let tail = term_stack.pop().unwrap();
term_stack.push(if matches!(tail, Term::Literal(_, Literal::Atom(atom!("[]")))) {
Term::CompleteString(
Cell::default(),
Rc::new(string.to_owned()),
)
} else {
Term::PartialString(
Cell::default(),
Rc::new(string.to_owned()),
Box::new(tail),
)
});
}
_ => {
}
);
}
}
debug_assert!(term_stack.len() == 1);
term_stack.pop().unwrap()
}
}
impl Machine {
pub(crate) fn use_module(&mut self) -> CallResult {
let subevacuable_addr = self
@@ -1600,15 +1612,11 @@ impl Machine {
}
pub(crate) fn add_term_expansion_clause(&mut self) -> CallResult {
let value = self.machine_st.registers[1];
let term = resource_error_call_result!(
self.machine_st,
TermWriteResult::from(&mut self.machine_st.heap, value)
);
let mut loader = self.loader_from_heap_evacuable(temp_v!(2));
let add_clause = || {
let term = loader.read_term_from_heap(temp_v!(1));
loader.incremental_compile_clause(
(atom!("term_expansion"), 2),
term,
@@ -1629,37 +1637,30 @@ impl Machine {
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
let compilation_target = match target_module_name {
atom!("user") => CompilationTarget::User,
_ => CompilationTarget::Module(target_module_name),
};
let value = self.machine_st.registers[2];
let term = resource_error_call_result!(
self.machine_st,
TermWriteResult::from(&mut self.machine_st.heap, value)
);
let add_clause = || {
let indexing_arg_opt = match term_predicate_key(&self.machine_st.heap, term.focus) {
Some((atom!(":-"), _)) => term_nth_arg(&self.machine_st.heap, term.focus, 1)
.and_then(|h| term_nth_arg(&self.machine_st.heap, h, 1)),
Some(_) => term_nth_arg(&self.machine_st.heap, term.focus, 1),
let term = loader.read_term_from_heap(temp_v!(2));
let indexing_arg = match term.name() {
Some(atom!(":-")) => term.first_arg().and_then(Term::first_arg),
Some(_) => term.first_arg(),
None => None,
};
let key_opt = indexing_arg_opt.and_then(|indexing_term_loc| {
term_predicate_key(&self.machine_st.heap, indexing_term_loc)
});
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
if let Some((name, arity)) = key_opt {
loader
.wam_prelude
.indices
.goal_expansion_indices
.insert((name, arity));
if let Some(indexing_term) = indexing_arg {
if let Some(indexing_name) = indexing_term.name() {
loader
.wam_prelude
.indices
.goal_expansion_indices
.insert((indexing_name, indexing_term.arity()));
}
}
loader.incremental_compile_clause(
@@ -1964,21 +1965,29 @@ impl Machine {
};
let stub_gen = || functor_stub(key.0, key.1);
let assert_clause = self.machine_st.registers[2];
let key_opt = clause_predicate_key_from_heap(&self.machine_st.heap, assert_clause);
let head = self.deref_register(2);
let mut compile_assert = |assert_clause, key_opt| {
if head.is_var() {
let err = self.machine_st.instantiation_error();
return Err(self.machine_st.error_form(err, stub_gen()));
}
let mut compile_assert = || {
let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> =
Loader::new(self, LiveTermStream::new(ListingSource::User));
loader.payload.compilation_target = compilation_target;
let (name, arity) = if let Some(key) = key_opt {
key
let head =
LiveLoadAndMachineState::machine_st(&mut loader.payload).read_term_from_heap(head);
let name = if let Some(name) = head.name() {
name
} else {
return Err(SessionError::from(CompilationError::InvalidRuleHead));
};
let arity = head.arity();
let is_builtin = loader.wam_prelude.indices.builtin_property((name, arity));
let is_dynamic_predicate = loader
@@ -2010,39 +2019,39 @@ impl Machine {
return LiveLoadAndMachineState::evacuate(loader);
}
let body = loader.read_term_from_heap(temp_v!(3));
let asserted_clause = Term::Clause(
Cell::default(),
atom!(":-"),
vec![head.clone(), body.clone()],
);
// if a new predicate was just created, make it dynamic.
loader.add_dynamic_predicate(compilation_target, name, arity)?;
let machine_st = LiveLoadAndMachineState::machine_st(&mut loader.payload);
// let asserted_clause = loader.copy_term_from_heap(assert_clause);
let term = TermWriteResult::from(&mut machine_st.heap, assert_clause)
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
loader.incremental_compile_clause(
(name, arity),
term,
asserted_clause,
compilation_target,
false,
append_or_prepend,
)?;
let clause_clause_term = loader.clause_clause(assert_clause)?;
// the global clock is incremented after each assertion.
LiveLoadAndMachineState::machine_st(&mut loader.payload).global_clock += 1;
loader.compile_clause_clauses(
(name, arity),
compilation_target,
vec![clause_clause_term],
std::iter::once((head, body)),
append_or_prepend,
)?;
LiveLoadAndMachineState::evacuate(loader)
};
match compile_assert(assert_clause, key_opt) {
match compile_assert() {
Ok(_) => Ok(()),
Err(SessionError::CompilationError(
CompilationError::InvalidRuleHead | CompilationError::InadmissibleFact,
@@ -2244,23 +2253,11 @@ impl Machine {
};
let mut loader = self.loader_from_heap_evacuable(temp_v!(4));
let predicate_focus_opt = loader
.payload
.predicates
.first()
.map(|term_write_result| term_write_result.focus);
let is_consistent = if let Some(predicate_focus) = predicate_focus_opt {
let machine_st = LiveLoadAndMachineState::machine_st(&mut loader.payload);
clause_predicate_key(&machine_st.heap, predicate_focus) == Some(key)
} else {
true
};
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail =
(!loader.payload.predicates.is_empty()
&& loader.payload.predicates.compilation_target != compilation_target)
|| !is_consistent;
|| !key.is_consistent(&loader.payload.predicates);
let result = LiveLoadAndMachineState::evacuate(loader);
self.restore_load_state_payload(result)
@@ -2467,17 +2464,11 @@ impl<'a> Loader<'a, LiveLoadAndMachineState<'a>> {
self.payload.predicates.compilation_target = compilation_target;
}
let machine_st = LiveLoadAndMachineState::machine_st(&mut self.payload);
let value = machine_st.store(MachineState::deref(machine_st, machine_st[term_reg]));
self.add_clause_clause_if_dynamic(value)?;
let machine_st = LiveLoadAndMachineState::machine_st(&mut self.payload);
let term = TermWriteResult::from(&mut machine_st.heap, value)
.map_err(|_err_loc| ParserError::ResourceError(ParserErrorSrc::default()))?;
let term = self.read_term_from_heap(term_reg);
self.add_clause_clause_if_dynamic(&term)?;
self.payload.term_stream.term_queue.push_back(term);
self.load()
}
}