Skip to content

Commit 0557dea

Browse files
committed
Revert "remove Term"
This reverts commit 3b58798.
1 parent 981cc18 commit 0557dea

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

54 files changed

+3744
-4536
lines changed

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ license = "BSD-3-Clause"
1010
keywords = ["prolog", "prolog-interpreter", "prolog-system"]
1111
categories = ["command-line-utilities"]
1212
build = "build/main.rs"
13-
rust-version = "1.77"
13+
rust-version = "1.79"
1414

1515
[lib]
1616
crate-type = ["cdylib", "rlib"]

build/instructions_template.rs

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -194,9 +194,9 @@ enum ReplCodePtr {
194194
DynamicProperty,
195195
#[strum_discriminants(strum(props(Arity = "3", Name = "$abolish_clause")))]
196196
AbolishClause,
197-
#[strum_discriminants(strum(props(Arity = "2", Name = "$asserta")))]
197+
#[strum_discriminants(strum(props(Arity = "3", Name = "$asserta")))]
198198
Asserta,
199-
#[strum_discriminants(strum(props(Arity = "2", Name = "$assertz")))]
199+
#[strum_discriminants(strum(props(Arity = "3", Name = "$assertz")))]
200200
Assertz,
201201
#[strum_discriminants(strum(props(Arity = "4", Name = "$retract_clause")))]
202202
Retract,
@@ -3126,6 +3126,14 @@ pub fn generate_instructions_rs() -> TokenStream {
31263126
}
31273127
}
31283128

3129+
pub fn name(&self) -> Atom {
3130+
match self {
3131+
#(
3132+
#clause_type_name_arms,
3133+
)*
3134+
}
3135+
}
3136+
31293137
pub fn is_inbuilt(name: Atom, arity: usize) -> bool {
31303138
matches!((name, arity),
31313139
#(#is_inbuilt_arms)|*

src/allocator.rs

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,10 @@ use crate::parser::ast::*;
22

33
use crate::forms::*;
44
use crate::instructions::*;
5-
use crate::machine::heap::Heap;
65
use crate::targets::*;
76

7+
use std::cell::Cell;
8+
89
pub(crate) trait Allocator {
910
fn new() -> Self;
1011

@@ -18,35 +19,37 @@ pub(crate) trait Allocator {
1819
fn mark_non_var<'a, Target: CompilationTarget<'a>>(
1920
&mut self,
2021
lvl: Level,
21-
heap_loc: usize,
2222
context: GenContext,
23+
cell: &'a Cell<RegType>,
2324
code: &mut CodeDeque,
24-
) -> RegType;
25+
);
2526

2627
#[allow(clippy::too_many_arguments)]
2728
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
2829
&mut self,
2930
var_num: usize,
3031
lvl: Level,
31-
context: GenContext,
32+
cell: &Cell<VarReg>,
33+
term_loc: GenContext,
3234
code: &mut CodeDeque,
3335
r: RegType,
3436
is_new_var: bool,
35-
) -> RegType;
37+
);
3638

3739
fn mark_cut_var(&mut self, var_num: usize, chunk_num: usize) -> RegType;
3840

3941
fn mark_var<'a, Target: CompilationTarget<'a>>(
4042
&mut self,
4143
var_num: usize,
4244
lvl: Level,
45+
cell: &Cell<VarReg>,
4346
context: GenContext,
4447
code: &mut CodeDeque,
45-
) -> RegType;
48+
);
4649

4750
fn reset(&mut self);
4851
fn reset_arg(&mut self, arg_num: usize);
49-
fn reset_at_head(&mut self, heap: &mut Heap, head_loc: usize);
52+
fn reset_at_head(&mut self, args: &[Term]);
5053
fn reset_contents(&mut self);
5154

5255
fn advance_arg(&mut self);

src/arithmetic.rs

Lines changed: 144 additions & 92 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,6 @@ use crate::debray_allocator::*;
77
use crate::forms::*;
88
use crate::instructions::*;
99
use crate::iterators::*;
10-
use crate::machine::disjuncts::*;
11-
use crate::machine::stack::Stack;
1210
use crate::targets::QueryInstruction;
1311
use crate::types::*;
1412

@@ -22,6 +20,7 @@ use dashu::base::BitTest;
2220
use num_order::NumOrd;
2321
use ordered_float::{Float, OrderedFloat};
2422

23+
use std::cell::Cell;
2524
use std::cmp::{max, min, Ordering};
2625
use std::convert::TryFrom;
2726
use std::f64;
@@ -52,56 +51,127 @@ impl Default for ArithmeticTerm {
5251
}
5352
}
5453

54+
#[derive(Debug)]
55+
pub(crate) struct ArithInstructionIterator<'a> {
56+
state_stack: Vec<TermIterState<'a>>,
57+
}
58+
5559
pub(crate) type ArithCont = (CodeDeque, Option<ArithmeticTerm>);
5660

61+
impl<'a> ArithInstructionIterator<'a> {
62+
fn push_subterm(&mut self, lvl: Level, term: &'a Term) {
63+
self.state_stack
64+
.push(TermIterState::subterm_to_state(lvl, term));
65+
}
66+
67+
fn from(term: &'a Term) -> Result<Self, ArithmeticError> {
68+
let state = match term {
69+
Term::AnonVar => return Err(ArithmeticError::UninstantiatedVar),
70+
Term::Clause(cell, name, terms) => {
71+
TermIterState::Clause(Level::Shallow, 0, cell, *name, terms)
72+
}
73+
Term::Literal(cell, cons) => TermIterState::Literal(Level::Shallow, cell, cons),
74+
Term::Cons(..) | Term::PartialString(..) | Term::CompleteString(..) => {
75+
return Err(ArithmeticError::NonEvaluableFunctor(
76+
Literal::Atom(atom!(".")),
77+
2,
78+
))
79+
}
80+
Term::Var(cell, var_ptr) => TermIterState::Var(Level::Shallow, cell, var_ptr.clone()),
81+
};
82+
83+
Ok(ArithInstructionIterator {
84+
state_stack: vec![state],
85+
})
86+
}
87+
}
88+
89+
#[derive(Debug)]
90+
pub(crate) enum ArithTermRef<'a> {
91+
Literal(Literal),
92+
Op(Atom, usize), // name, arity.
93+
Var(Level, &'a Cell<VarReg>, VarPtr),
94+
}
95+
96+
impl<'a> Iterator for ArithInstructionIterator<'a> {
97+
type Item = Result<ArithTermRef<'a>, ArithmeticError>;
98+
99+
fn next(&mut self) -> Option<Self::Item> {
100+
while let Some(iter_state) = self.state_stack.pop() {
101+
match iter_state {
102+
TermIterState::AnonVar(_) => return Some(Err(ArithmeticError::UninstantiatedVar)),
103+
TermIterState::Clause(lvl, child_num, cell, name, subterms) => {
104+
let arity = subterms.len();
105+
106+
if child_num == arity {
107+
return Some(Ok(ArithTermRef::Op(name, arity)));
108+
} else {
109+
self.state_stack.push(TermIterState::Clause(
110+
lvl,
111+
child_num + 1,
112+
cell,
113+
name,
114+
subterms,
115+
));
116+
117+
self.push_subterm(lvl.child_level(), &subterms[child_num]);
118+
}
119+
}
120+
TermIterState::Literal(_, _, c) => return Some(Ok(ArithTermRef::Literal(*c))),
121+
TermIterState::Var(lvl, cell, var_ptr) => {
122+
return Some(Ok(ArithTermRef::Var(lvl, cell, var_ptr)));
123+
}
124+
_ => {
125+
return Some(Err(ArithmeticError::NonEvaluableFunctor(
126+
Literal::Atom(atom!(".")),
127+
2,
128+
)));
129+
}
130+
};
131+
}
132+
133+
None
134+
}
135+
}
136+
57137
#[derive(Debug)]
58138
pub(crate) struct ArithmeticEvaluator<'a> {
59139
marker: &'a mut DebrayAllocator,
60140
interm: Vec<ArithmeticTerm>,
61141
interm_c: usize,
62142
}
63143

64-
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: HeapCellValue) -> Result<(), ArithmeticError> {
65-
let c = unmark_cell_bits!(c);
144+
pub(crate) trait ArithmeticTermIter<'a> {
145+
type Iter: Iterator<Item = Result<ArithTermRef<'a>, ArithmeticError>>;
66146

67-
read_heap_cell!(c,
68-
(HeapCellValueTag::Fixnum, n) => {
69-
interm.push(ArithmeticTerm::Number(Number::Fixnum(n)))
70-
}
71-
(HeapCellValueTag::Cons, cons_ptr) => {
72-
match_untyped_arena_ptr!(cons_ptr,
73-
(ArenaHeaderTag::Integer, n) => {
74-
interm.push(ArithmeticTerm::Number(Number::Integer(n)));
75-
}
76-
(ArenaHeaderTag::Rational, n) => {
77-
interm.push(ArithmeticTerm::Number(Number::Rational(n)));
78-
}
79-
_ => return Err(ArithmeticError::NonEvaluableFunctor(c, 0)),
80-
);
81-
}
82-
(HeapCellValueTag::Atom, (name, arity)) => {
83-
debug_assert_eq!(arity, 0);
84-
85-
match name {
86-
atom!("pi") => interm.push(ArithmeticTerm::Number(
87-
Number::Float(OrderedFloat(std::f64::consts::PI)),
88-
)),
89-
atom!("epsilon") => interm.push(ArithmeticTerm::Number(
90-
Number::Float(OrderedFloat(std::f64::EPSILON)),
91-
)),
92-
atom!("e") => interm.push(ArithmeticTerm::Number(
93-
Number::Float(OrderedFloat(std::f64::consts::E)),
94-
)),
95-
_ => unreachable!(),
96-
}
97-
}
98-
(HeapCellValueTag::F64, n) => {
99-
interm.push(ArithmeticTerm::Number(Number::Float(*n)));
100-
}
101-
_ => {
102-
return Err(ArithmeticError::NonEvaluableFunctor(c, 0));
103-
}
104-
);
147+
fn iter(self) -> Result<Self::Iter, ArithmeticError>;
148+
}
149+
150+
impl<'a> ArithmeticTermIter<'a> for &'a Term {
151+
type Iter = ArithInstructionIterator<'a>;
152+
153+
fn iter(self) -> Result<Self::Iter, ArithmeticError> {
154+
ArithInstructionIterator::from(self)
155+
}
156+
}
157+
158+
fn push_literal(interm: &mut Vec<ArithmeticTerm>, c: &Literal) -> Result<(), ArithmeticError> {
159+
match c {
160+
Literal::Fixnum(n) => interm.push(ArithmeticTerm::Number(Number::Fixnum(*n))),
161+
Literal::Integer(n) => interm.push(ArithmeticTerm::Number(Number::Integer(*n))),
162+
Literal::Float(n) => interm.push(ArithmeticTerm::Number(Number::Float(*n.as_ptr()))),
163+
Literal::Rational(n) => interm.push(ArithmeticTerm::Number(Number::Rational(*n))),
164+
Literal::Atom(name) if name == &atom!("e") => interm.push(ArithmeticTerm::Number(
165+
Number::Float(OrderedFloat(std::f64::consts::E)),
166+
)),
167+
Literal::Atom(name) if name == &atom!("pi") => interm.push(ArithmeticTerm::Number(
168+
Number::Float(OrderedFloat(std::f64::consts::PI)),
169+
)),
170+
Literal::Atom(name) if name == &atom!("epsilon") => interm.push(ArithmeticTerm::Number(
171+
Number::Float(OrderedFloat(f64::EPSILON)),
172+
)),
173+
_ => return Err(ArithmeticError::NonEvaluableFunctor(*c, 0)),
174+
}
105175

106176
Ok(())
107177
}
@@ -143,7 +213,7 @@ impl<'a> ArithmeticEvaluator<'a> {
143213
atom!("float_fractional_part") => Ok(Instruction::FloatFractionalPart(a1, t)),
144214
atom!("sign") => Ok(Instruction::Sign(a1, t)),
145215
atom!("\\") => Ok(Instruction::BitwiseComplement(a1, t)),
146-
_ => Err(ArithmeticError::NonEvaluableFunctor(atom_as_cell!(name), 1)),
216+
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 1)),
147217
}
148218
}
149219

@@ -175,7 +245,7 @@ impl<'a> ArithmeticEvaluator<'a> {
175245
atom!("rem") => Ok(Instruction::Rem(a1, a2, t)),
176246
atom!("gcd") => Ok(Instruction::Gcd(a1, a2, t)),
177247
atom!("atan2") => Ok(Instruction::ATan2(a1, a2, t)),
178-
_ => Err(ArithmeticError::NonEvaluableFunctor(atom_as_cell!(name), 2)),
248+
_ => Err(ArithmeticError::NonEvaluableFunctor(Literal::Atom(name), 2)),
179249
}
180250
}
181251

@@ -231,70 +301,52 @@ impl<'a> ArithmeticEvaluator<'a> {
231301
self.get_binary_instr(name, a1, a2, ninterm)
232302
}
233303
_ => Err(ArithmeticError::NonEvaluableFunctor(
234-
atom_as_cell!(name),
304+
Literal::Atom(name),
235305
arity,
236306
)),
237307
}
238308
}
239309

240310
pub(crate) fn compile_is(
241311
&mut self,
242-
src: &mut FocusedHeapRefMut,
243-
term_loc: usize,
244-
context: GenContext,
312+
src: &'a Term,
313+
term_loc: GenContext,
245314
arg: usize,
246315
) -> Result<ArithCont, ArithmeticError> {
247316
let mut code = CodeDeque::new();
248-
let mut stack = Stack::uninitialized();
249-
let mut iter = query_iterator::<false>(&mut src.heap, &mut stack, term_loc);
250-
251-
let chunk_num = context.chunk_num();
252-
253-
while let Some(term) = iter.next() {
254-
read_heap_cell!(term,
255-
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, term_loc) => {
256-
let lvl = iter.level();
257-
258-
let r = match self.marker.var_data.var_locs_to_nums.get(VarPtrIndex { chunk_num, term_loc }) {
259-
VarPtr::Numbered(var_num) => {
260-
let old_r = self.marker.get_var_binding(var_num);
261-
262-
if lvl == Level::Root {
263-
self.marker.mark_non_callable(var_num, arg, context, &mut code)
264-
} else if context.is_last() || old_r.reg_num() == 0 {
265-
let r = old_r;
266-
267-
if r.reg_num() == 0 {
268-
self.marker.mark_var::<QueryInstruction>(
269-
var_num, lvl, context, &mut code,
270-
)
271-
} else {
272-
self.marker.increment_running_count(var_num);
273-
r
274-
}
275-
} else {
276-
self.marker.increment_running_count(var_num);
277-
old_r
278-
}
279-
}
280-
VarPtr::Anon => {
281-
self.marker.mark_anon_var::<QueryInstruction>(lvl, context, &mut code)
317+
318+
for term_ref in src.iter()? {
319+
match term_ref? {
320+
ArithTermRef::Literal(c) => push_literal(&mut self.interm, &c)?,
321+
ArithTermRef::Var(lvl, cell, name) => {
322+
let var_num = name.to_var_num().unwrap();
323+
324+
let r = if lvl == Level::Shallow {
325+
self.marker
326+
.mark_non_callable(var_num, arg, term_loc, cell, &mut code)
327+
} else if term_loc.is_last() || cell.get().norm().reg_num() == 0 {
328+
let r = self.marker.get_binding(var_num);
329+
330+
if r.reg_num() == 0 {
331+
self.marker.mark_var::<QueryInstruction>(
332+
var_num, lvl, cell, term_loc, &mut code,
333+
);
334+
cell.get().norm()
335+
} else {
336+
self.marker.increment_running_count(var_num);
337+
r
282338
}
339+
} else {
340+
self.marker.increment_running_count(var_num);
341+
cell.get().norm()
283342
};
284343

285344
self.interm.push(ArithmeticTerm::Reg(r));
286345
}
287-
(HeapCellValueTag::Atom, (name, arity)) => {
288-
if arity == 0 {
289-
push_literal(&mut self.interm, atom_as_cell!(name))?;
290-
} else {
291-
code.push_back(self.instr_from_clause(name, arity)?);
292-
}
293-
}
294-
_ => {
295-
push_literal(&mut self.interm, term)?;
346+
ArithTermRef::Op(name, arity) => {
347+
code.push_back(self.instr_from_clause(name, arity)?);
296348
}
297-
);
349+
}
298350
}
299351

300352
Ok((code, self.interm.pop()))

0 commit comments

Comments
 (0)