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

@@ -1,14 +1,21 @@
use crate::parser::ast::*;
use crate::parser::lexer::Lexer;
use crate::parser::parser::*;
use crate::atom_table::*;
use crate::forms::*;
use crate::iterators::*;
use crate::machine::heap::*;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::machine::machine_state::MachineState;
use crate::machine::streams::*;
use crate::parser::char_reader::*;
use crate::parser::lexer::LexerParser;
#[cfg(feature = "repl")]
use crate::repl_helper::Helper;
use crate::types::*;
use fxhash::FxBuildHasher;
#[cfg(feature = "repl")]
use rustyline::error::ReadlineError;
@@ -17,13 +24,16 @@ use rustyline::history::DefaultHistory;
#[cfg(feature = "repl")]
use rustyline::{Config, Editor};
use std::collections::VecDeque;
use std::io::{Cursor, Read};
#[cfg(feature = "repl")]
use std::io::{Error, ErrorKind};
use std::sync::Arc;
type SubtermDeque = VecDeque<(usize, usize)>;
pub(crate) fn devour_whitespace<R: CharRead>(
lexer: &mut LexerParser<'_, R>,
lexer: &mut Lexer<'_, R>,
) -> Result<bool, ParserError> {
match lexer.scan_for_layout() {
Err(e) if e.is_unexpected_eof() => Ok(true),
@@ -32,16 +42,18 @@ pub(crate) fn devour_whitespace<R: CharRead>(
}
}
pub(crate) fn error_after_read_term(
pub(crate) fn error_after_read_term<R>(
err: ParserError,
prior_num_lines_read: usize,
parser: &Parser<R>,
) -> CompilationError {
if err.is_unexpected_eof() {
let ParserErrorSrc { line_num, col_num } = err.err_src();
let line_num = parser.lexer.line_num;
let col_num = parser.lexer.col_num;
// rough overlap with errors 8.14.1.3 k) & l) of the ISO standard here
if !(line_num == prior_num_lines_read && col_num == 0) {
return CompilationError::from(ParserError::IncompleteReduction(err.err_src()));
return CompilationError::from(ParserError::IncompleteReduction(line_num, col_num));
}
}
@@ -49,37 +61,27 @@ pub(crate) fn error_after_read_term(
}
impl MachineState {
pub(crate) fn read<R: CharRead>(
&mut self,
inner: R,
op_dir: &OpDir,
) -> Result<(TermWriteResult, usize), ParserError> {
let mut lexer_parser = LexerParser::new(inner, self);
let op_dir = CompositeOpDir::new(op_dir, None);
let term_result = lexer_parser.read_term(&op_dir, Tokens::Default);
let lines_read = lexer_parser.line_num();
term_result.map(|term| (term, lines_read))
}
pub(crate) fn read_to_heap(
pub(crate) fn read(
&mut self,
mut inner: Stream,
op_dir: &OpDir,
) -> Result<TermWriteResult, CompilationError> {
let prior_num_lines_read = inner.lines_read();
let term = match self.read(inner, op_dir) {
Ok((term, num_lines_read)) => {
inner.add_lines_read(num_lines_read);
term
}
Err(e) => {
return Err(error_after_read_term(e, prior_num_lines_read));
}
let (term, num_lines_read) = {
let prior_num_lines_read = inner.lines_read();
let mut parser = Parser::new(inner, self);
let op_dir = CompositeOpDir::new(op_dir, None);
parser.add_lines_read(prior_num_lines_read);
let term = parser
.read_term(&op_dir, Tokens::Default)
.map_err(|err| error_after_read_term(err, prior_num_lines_read, &parser))?; // CompilationError::from
(term, parser.lines_read() - prior_num_lines_read)
};
Ok(term)
inner.add_lines_read(num_lines_read);
write_term_to_heap(&term, &mut self.heap)
}
}
@@ -278,6 +280,7 @@ impl CharRead for ReadlineStream {
}
}
}
#[inline]
fn consume(&mut self, nread: usize) {
self.pending_input.consume(nread);
@@ -288,3 +291,217 @@ impl CharRead for ReadlineStream {
self.pending_input.put_back_char(c);
}
}
#[inline]
pub(crate) fn write_term_to_heap(
term: &Term,
heap: &mut Heap,
) -> Result<TermWriteResult, CompilationError> {
let term_writer = TermWriter::new(heap);
term_writer.write_term_to_heap(term)
}
#[derive(Debug)]
struct TermWriter<'a> {
heap: &'a mut Heap,
queue: SubtermDeque,
var_dict: HeapVarDict,
}
#[derive(Debug)]
pub struct TermWriteResult {
pub heap_loc: usize,
pub var_dict: HeapVarDict,
}
impl<'a> TermWriter<'a> {
#[inline]
fn new(heap: &'a mut Heap) -> Self {
TermWriter {
heap,
queue: SubtermDeque::new(),
var_dict: HeapVarDict::with_hasher(FxBuildHasher::default()),
}
}
#[inline]
fn modify_head_of_queue(&mut self, term: &TermRef, h: usize) {
if let Some((arity, site_h)) = self.queue.pop_front() {
self.heap[site_h] = self.term_as_addr(term, h);
if arity > 1 {
self.queue.push_front((arity - 1, site_h + 1));
}
}
}
#[inline]
fn push_stub_addr(&mut self) -> Result<(), CompilationError> {
let h = self.heap.cell_len();
self.push_cell(heap_loc_as_cell!(h))
}
#[inline]
fn push_cell(&mut self, cell: HeapCellValue) -> Result<(), CompilationError> {
self.heap
.push_cell(cell)
.map_err(|h| CompilationError::FiniteMemoryInHeap(h))
}
fn term_as_addr(&mut self, term: &TermRef, h: usize) -> HeapCellValue {
match term {
&TermRef::Cons(..) => list_loc_as_cell!(h),
&TermRef::AnonVar(_) | &TermRef::Var(..) => heap_loc_as_cell!(h),
TermRef::PartialString(..) | TermRef::CompleteString(..) => heap_loc_as_cell!(h),
&TermRef::Literal(_, _, literal) => HeapCellValue::from(*literal),
&TermRef::Clause(_, _, _, subterms) if subterms.is_empty() => heap_loc_as_cell!(h),
&TermRef::Clause(..) => str_loc_as_cell!(h),
}
}
fn write_term_to_heap(mut self, term: &Term) -> Result<TermWriteResult, CompilationError> {
let heap_loc = self.heap.cell_len();
for term in breadth_first_iter(term, RootIterationPolicy::Iterated) {
let h = self.heap.cell_len();
match &term {
&TermRef::Cons(Level::Root, ..) => {
self.queue.push_back((2, h + 1));
self.push_cell(list_loc_as_cell!(h + 1))?;
self.push_stub_addr()?;
self.push_stub_addr()?;
continue;
}
&TermRef::Cons(..) => {
self.queue.push_back((2, h));
self.push_stub_addr()?;
self.push_stub_addr()?;
}
&TermRef::Clause(Level::Root, _, name, subterms) => {
if subterms.len() > MAX_ARITY {
return Err(CompilationError::ExceededMaxArity);
}
self.push_cell(if subterms.is_empty() {
heap_loc_as_cell!(heap_loc + 1)
} else {
str_loc_as_cell!(heap_loc + 1)
})?;
self.queue.push_back((subterms.len(), h + 2));
let named = atom_as_cell!(name, subterms.len());
self.push_cell(named)?;
for _ in 0..subterms.len() {
self.push_stub_addr()?;
}
continue;
}
&TermRef::Clause(_, _, name, subterms) => {
self.queue.push_back((subterms.len(), h + 1));
let named = atom_as_cell!(name, subterms.len());
self.push_cell(named)?;
for _ in 0..subterms.len() {
self.push_stub_addr()?;
}
}
&TermRef::AnonVar(Level::Root) | TermRef::Literal(Level::Root, ..) => {
let addr = self.term_as_addr(&term, h);
self.push_cell(addr)?;
}
&TermRef::Var(Level::Root, _, ref var_ptr) => {
let addr = self.term_as_addr(&term, h);
self.var_dict.insert(VarKey::VarPtr(var_ptr.clone()), addr);
self.push_cell(addr)?;
}
&TermRef::AnonVar(_) => {
if let Some((arity, site_h)) = self.queue.pop_front() {
self.var_dict
.insert(VarKey::AnonVar(h), heap_loc_as_cell!(site_h));
if arity > 1 {
self.queue.push_front((arity - 1, site_h + 1));
}
}
continue;
}
TermRef::CompleteString(lvl, _, src) => {
let cell = self
.heap
.allocate_cstr(src)
.map_err(CompilationError::FiniteMemoryInHeap)?;
let h = self.heap.cell_len();
self.push_cell(cell)?;
if !matches!(lvl, Level::Root) {
self.modify_head_of_queue(&term, h);
}
continue;
}
TermRef::PartialString(lvl, _, src, _) => {
if let Level::Root = lvl {
self.push_stub_addr()?;
}
let cell = self
.heap
.allocate_pstr(src)
.map_err(CompilationError::FiniteMemoryInHeap)?;
let tail_h = self.heap.cell_len();
self.push_stub_addr()?;
if let Level::Root = lvl {
self.heap[h] = cell;
} else {
self.push_cell(cell)?;
};
self.queue.push_back((1, tail_h));
if !matches!(lvl, Level::Root) {
self.modify_head_of_queue(&term, tail_h + 1);
}
continue;
}
TermRef::Var(.., var) => {
if let Some((arity, site_h)) = self.queue.pop_front() {
let var_key = VarKey::VarPtr(var.clone());
if let Some(addr) = self.var_dict.get(&var_key).cloned() {
self.heap[site_h] = addr;
} else {
self.var_dict.insert(var_key, heap_loc_as_cell!(site_h));
}
if arity > 1 {
self.queue.push_front((arity - 1, site_h + 1));
}
}
continue;
}
_ => {}
};
self.modify_head_of_queue(&term, h);
}
Ok(TermWriteResult {
heap_loc,
var_dict: self.var_dict,
})
}
}