Merge branch 'master' into library-use-case

# Conflicts:
#	Cargo.toml
#	src/atom_table.rs
#	src/bin/scryer-prolog.rs
#	src/http.rs
#	src/machine/mock_wam.rs
#	src/machine/mod.rs
#	src/machine/system_calls.rs
This commit is contained in:
Nicolas Luck
2023-09-13 18:13:14 +02:00
68 changed files with 12920 additions and 10310 deletions

View File

@@ -1,7 +1,9 @@
use dashu::base::Abs;
use dashu::base::DivRem;
use dashu::base::Gcd;
use dashu::integer::IBig;
use divrem::*;
use num_order::NumOrd;
use crate::arena::*;
use crate::arithmetic::*;
@@ -50,9 +52,7 @@ macro_rules! drop_iter_on_err {
};
}
fn zero_divisor_eval_error(
stub_gen: impl Fn() -> FunctorStub + 'static,
) -> MachineStubGen {
fn zero_divisor_eval_error(stub_gen: impl Fn() -> FunctorStub + 'static) -> MachineStubGen {
Box::new(move |machine_st| {
let eval_error = machine_st.evaluation_error(EvalError::ZeroDivisor);
let stub = stub_gen();
@@ -61,9 +61,7 @@ fn zero_divisor_eval_error(
})
}
fn undefined_eval_error(
stub_gen: impl Fn() -> FunctorStub + 'static,
) -> MachineStubGen {
fn undefined_eval_error(stub_gen: impl Fn() -> FunctorStub + 'static) -> MachineStubGen {
Box::new(move |machine_st| {
let eval_error = machine_st.evaluation_error(EvalError::Undefined);
let stub = stub_gen();
@@ -169,9 +167,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
Ok(Number::Float(add_f(float_i_to_f(&n1)?, n2)?))
}
(Number::Integer(n1), Number::Rational(n2))
| (Number::Rational(n2), Number::Integer(n1)) => {
Ok(Number::arena_from(&*n1 + &*n2, arena))
}
| (Number::Rational(n2), Number::Integer(n1)) => Ok(Number::arena_from(&*n1 + &*n2, arena)),
(Number::Rational(n1), Number::Float(OrderedFloat(n2)))
| (Number::Float(OrderedFloat(n2)), Number::Rational(n1)) => {
Ok(Number::Float(add_f(float_r_to_f(&n1)?, n2)?))
@@ -179,9 +175,7 @@ pub(crate) fn add(lhs: Number, rhs: Number, arena: &mut Arena) -> Result<Number,
(Number::Float(OrderedFloat(f1)), Number::Float(OrderedFloat(f2))) => {
Ok(Number::Float(add_f(f1, f2)?))
}
(Number::Rational(r1), Number::Rational(r2)) => {
Ok(Number::arena_from(&*r1 + &*r2, arena))
}
(Number::Rational(r1), Number::Rational(r2)) => Ok(Number::arena_from(&*r1 + &*r2, arena)),
}
}
@@ -197,12 +191,12 @@ pub(crate) fn neg(n: Number, arena: &mut Arena) -> Number {
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Number::arena_from(-Integer::from(n_clone), arena)
},
}
Number::Float(OrderedFloat(f)) => Number::Float(OrderedFloat(-f)),
Number::Rational(r) => {
let r_clone: Rational = (*r).clone();
Number::arena_from(-Rational::from(r_clone), arena)
},
}
}
}
@@ -219,12 +213,12 @@ pub(crate) fn abs(n: Number, arena: &mut Arena) -> Number {
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Number::arena_from(Integer::from(n_clone.abs()), arena)
},
}
Number::Float(f) => Number::Float(f.abs()),
Number::Rational(r) => {
let r_clone: Rational = (*r).clone();
Number::arena_from(Rational::from(r_clone.abs()), arena)
},
}
}
}
@@ -368,7 +362,11 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe
(Number::Integer(n1), Number::Fixnum(n2)) => {
let n2_i = n2.get_num();
if !(&*n1 == &Integer::from(1) || &*n1 == &Integer::from(0) || &*n1 == &Integer::from(-1)) && n2_i < 0 {
if !(&*n1 == &Integer::from(1)
|| &*n1 == &Integer::from(0)
|| &*n1 == &Integer::from(-1))
&& n2_i < 0
{
let n = Number::Integer(n1);
Err(numerical_type_error(ValidType::Float, n, stub_gen))
} else {
@@ -377,7 +375,11 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe
}
}
(Number::Integer(n1), Number::Integer(n2)) => {
if !(&*n1 == &Integer::from(1) || &*n1 == &Integer::from(0) || &*n1 == &Integer::from(-1)) && &*n2 < &Integer::from(0) {
if !(&*n1 == &Integer::from(1)
|| &*n1 == &Integer::from(0)
|| &*n1 == &Integer::from(-1))
&& &*n2 < &Integer::from(0)
{
let n = Number::Integer(n1);
Err(numerical_type_error(ValidType::Float, n, stub_gen))
} else {
@@ -454,14 +456,14 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 > &n1.get_num() {
if (&*n2).num_gt(&n1.get_num()) {
Ok(Number::Integer(n2))
} else {
Ok(Number::Fixnum(n1))
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
if &*n1 > &n2.get_num() {
if (&*n1).num_gt(&n2.get_num()) {
Ok(Number::Integer(n1))
} else {
Ok(Number::Fixnum(n2))
@@ -498,14 +500,14 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 < &n1.get_num() {
if (&*n2).num_lt(&n1.get_num()) {
Ok(Number::Integer(n2))
} else {
Ok(Number::Fixnum(n1))
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => {
if &*n1 < &n2.get_num() {
if (&*n1).num_lt(&n2.get_num()) {
Ok(Number::Integer(n1))
} else {
Ok(Number::Fixnum(n2))
@@ -552,7 +554,7 @@ pub fn rational_from_number(
Number::Integer(n) => {
let n_clone: Integer = (*n).clone();
Ok(arena_alloc!(Rational::from(n_clone), arena))
},
}
}
}
@@ -560,7 +562,7 @@ pub(crate) fn rdiv(
r1: TypedArenaPtr<Rational>,
r2: TypedArenaPtr<Rational>,
) -> Result<Rational, MachineStubGen> {
if &*r2 == &0 {
if &*r2 == &Rational::from(0) {
let stub_gen = || {
let rdiv_atom = atom!("rdiv");
functor_stub(rdiv_atom, 2)
@@ -594,7 +596,7 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 {
if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(Integer::from(n1) / &*n2, arena))
@@ -608,11 +610,11 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
}
}
(Number::Integer(n1), Number::Integer(n2)) => {
if &*n2 == &0 {
if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).0,
<(Integer, Integer)>::from((&*n1).div_rem(&*n2)).0,
arena,
))
}
@@ -659,31 +661,42 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
if let Ok(n2) = usize::try_from(n2_i) {
return Ok(Number::arena_from(n1 >> n2, arena));
} else {
} else {
return Ok(Number::arena_from(n1 >> usize::max_value(), arena));
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1.get_num());
match n2.to_usize() {
Some(n2) => Ok(Number::arena_from(n1 >> n2, arena)),
_ => {
Ok(Number::arena_from(n1 >> usize::max_value(), arena))
},
let result: Result<usize, _> = (&*n2).try_into();
match result {
Ok(n2) => {
Ok(Number::arena_from(n1 >> n2, arena))
}
Err(_) => {
Ok(Number::arena_from(n1 >> usize::max_value(), arena))
}
}
}
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
Ok(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
_ => {
Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()),arena))
},
_ => Ok(Number::arena_from(
Integer::from(&*n1 >> usize::max_value()),
arena,
)),
},
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_usize() {
Some(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
_ => {
Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
},
(Number::Integer(n1), Number::Integer(n2)) => {
let result: Result<usize, _> = (&*n2).try_into();
match result {
Ok(n2) => {
Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena))
}
Err(_) => {
Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
}
}
},
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
@@ -710,15 +723,18 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
if let Ok(n2) = usize::try_from(n2_i) {
return Ok(Number::arena_from(n1 << n2, arena));
} else {
} else {
return Ok(Number::arena_from(n1 << usize::max_value(), arena));
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
let n1 = Integer::from(n1.get_num());
match n2.to_u32() {
Some(n2) => Ok(Number::arena_from(n1.to_u64().unwrap() << n2, arena)),
match (&*n2).try_into() as Result<u32, _> {
Ok(n2) => {
let n1: u64 = n1.try_into().unwrap();
Ok(Number::arena_from(n1 << n2, arena))
},
_ => {
Ok(Number::arena_from(n1 << usize::max_value(), arena))
}
@@ -726,12 +742,16 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
}
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
Ok(n2) => Ok(Number::arena_from(Integer::from(&*n1 << n2), arena)),
_ => {
Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
}
_ => Ok(Number::arena_from(
Integer::from(&*n1 << usize::max_value()),
arena,
)),
},
(Number::Integer(n1), Number::Integer(n2)) => match n2.to_u32() {
Some(n2) => Ok(Number::arena_from(Integer::from(n1.to_u64().unwrap() << n2), arena)),
(Number::Integer(n1), Number::Integer(n2)) => match (&*n2).try_into() as Result<u32, _> {
Ok(n2) => {
let n1: u64 = (&*n1).try_into().unwrap();
Ok(Number::arena_from(Integer::from(n1 << n2), arena))
},
_ => {
Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
}
@@ -845,12 +865,12 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 {
if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
let n1 = Integer::from(n1.get_num());
Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&*n2)).1,
<(Integer, Integer)>::from(n1.div_rem(&*n2)).1,
arena,
))
}
@@ -863,17 +883,17 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
} else {
let n2 = Integer::from(n2_i);
Ok(Number::arena_from(
<(Integer, Integer)>::from(n1.div_rem_floor_ref(&n2)).1,
<(Integer, Integer)>::from((&*n1).div_rem(&n2)).1,
arena,
))
}
}
(Number::Integer(x), Number::Integer(y)) => {
if &*y == &0 {
if (&*y).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(
<(Integer, Integer)>::from(x.div_rem_floor_ref(&*y)).1,
<(Integer, Integer)>::from((&*x).div_rem(&*y)).1,
arena,
))
}
@@ -903,7 +923,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
}
}
(Number::Fixnum(n1), Number::Integer(n2)) => {
if &*n2 == &0 {
if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
let n1 = Integer::from(n1.get_num());
@@ -921,7 +941,7 @@ pub(crate) fn remainder(x: Number, y: Number, arena: &mut Arena) -> Result<Numbe
}
}
(Number::Integer(n1), Number::Integer(n2)) => {
if &*n2 == &0 {
if (&*n2).num_eq(&0) {
Err(zero_divisor_eval_error(stub_gen))
} else {
Ok(Number::arena_from(Integer::from(&*n1 % &*n2), arena))
@@ -949,10 +969,7 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
Ok(Number::arena_from(result, arena))
} else {
let value: IBig = Integer::from(n1_i).gcd(&Integer::from(n2_i)).into();
Ok(Number::arena_from(
value,
arena,
))
Ok(Number::arena_from(value, arena))
}
}
(Number::Fixnum(n1), Number::Integer(n2)) | (Number::Integer(n2), Number::Fixnum(n1)) => {
@@ -962,7 +979,8 @@ pub(crate) fn gcd(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
}
(Number::Integer(n1), Number::Integer(n2)) => {
let n1_clone: Integer = (*n1).clone();
Ok(Number::arena_from(Integer::from(n1_clone.gcd(&Integer::from(n2.to_isize().unwrap()))) as IBig, arena))
let n2: isize = (&*n2).try_into().unwrap();
Ok(Number::arena_from(Integer::from(n1_clone.gcd(&Integer::from(n2))) as IBig, arena))
}
(Number::Float(f), _) | (_, Number::Float(f)) => {
let n = Number::Float(f);
@@ -1050,12 +1068,14 @@ pub(crate) fn atanh(n1: Number) -> Result<f64, MachineStubGen> {
let f1 = try_numeric_result!(result_f(&n1), stub_gen)?;
try_numeric_result!(if f1 == 1.0 || f1 == -1.0 {
Err(EvalError::Undefined)
} else {
result_f(&Number::Float(OrderedFloat(f1.atanh())))
},
stub_gen)
try_numeric_result!(
if f1 == 1.0 || f1 == -1.0 {
Err(EvalError::Undefined)
} else {
result_f(&Number::Float(OrderedFloat(f1.atanh())))
},
stub_gen
)
}
#[inline]
@@ -1107,7 +1127,6 @@ pub(crate) fn floor(n1: Number, arena: &mut Arena) -> Number {
rnd_i(&n1, arena)
}
#[inline]
pub(crate) fn ceiling(n1: Number, arena: &mut Arena) -> Number {
let n1 = neg(n1, arena);
@@ -1160,16 +1179,17 @@ impl MachineState {
pub fn get_number(&mut self, at: &ArithmeticTerm) -> Result<Number, MachineStub> {
match at {
&ArithmeticTerm::Reg(r) => {
let value = self.store(self.deref(self[r]));
let value = self.store(self.deref(self[r]));
match Number::try_from(value) {
Ok(n) => Ok(n),
Err(_) => self.arith_eval_by_metacall(value),
}
}
&ArithmeticTerm::Interm(i) => {
Ok(mem::replace(&mut self.interms[i - 1], Number::Fixnum(Fixnum::build_with(0))))
}
&ArithmeticTerm::Interm(i) => Ok(mem::replace(
&mut self.interms[i - 1],
Number::Fixnum(Fixnum::build_with(0)),
)),
&ArithmeticTerm::Number(n) => Ok(n),
}
}
@@ -1183,11 +1203,14 @@ impl MachineState {
match rational_from_number(n, caller, &mut self.arena) {
Ok(r) => Ok(r),
Err(e_gen) => Err(e_gen(self))
Err(e_gen) => Err(e_gen(self)),
}
}
pub(crate) fn arith_eval_by_metacall(&mut self, value: HeapCellValue) -> Result<Number, MachineStub> {
pub(crate) fn arith_eval_by_metacall(
&mut self,
value: HeapCellValue,
) -> Result<Number, MachineStub> {
let stub_gen = || functor_stub(atom!("is"), 2);
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, value);
@@ -1493,26 +1516,11 @@ mod tests {
let mut wam = MachineState::new();
let mut op_dir = default_op_dir();
op_dir.insert(
(atom!("+"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("-"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("-"), Fixity::Pre),
OpDesc::build_with(200, FY as u8),
);
op_dir.insert(
(atom!("*"), Fixity::In),
OpDesc::build_with(400, YFX as u8),
);
op_dir.insert(
(atom!("/"), Fixity::In),
OpDesc::build_with(400, YFX as u8),
);
op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("-"), Fixity::Pre), OpDesc::build_with(200, FY as u8));
op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8));
op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8));
let term_write_result =
parse_and_write_parsed_term_to_heap(&mut wam, "3 + 4 - 1 + 2.", &op_dir).unwrap();

View File

@@ -118,12 +118,9 @@ impl MachineState {
and_frame[i] = self.registers[i];
}
and_frame[arity + 1] =
fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
and_frame[arity + 2] =
fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
and_frame[arity + 3] =
fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
and_frame[arity + 1] = fixnum_as_cell!(Fixnum::build_with(self.b0 as i64));
and_frame[arity + 2] = fixnum_as_cell!(Fixnum::build_with(self.num_of_args as i64));
and_frame[arity + 3] = fixnum_as_cell!(Fixnum::build_with(self.attr_var_init.cp as i64));
self.verify_attributes();

View File

@@ -8,7 +8,9 @@ fn capture_offset(line: &Instruction, index: usize, stack: &mut Vec<usize>) -> b
&Instruction::TryMeElse(offset) if offset > 0 => {
stack.push(index + offset);
}
&Instruction::DefaultRetryMeElse(offset) | &Instruction::RetryMeElse(offset) if offset > 0 => {
&Instruction::DefaultRetryMeElse(offset) | &Instruction::RetryMeElse(offset)
if offset > 0 =>
{
stack.push(index + offset);
}
&Instruction::DynamicElse(_, _, NextOrFail::Next(offset)) if offset > 0 => {

View File

@@ -28,17 +28,15 @@ pub(super) fn bootstrapping_compile(
) -> Result<(), SessionError> {
let (wam_prelude, machine_st) = wam.prelude_view_and_machine_st();
let term_stream = BootstrappingTermStream::from_char_reader(
stream,
machine_st,
listing_src,
);
let term_stream = BootstrappingTermStream::from_char_reader(stream, machine_st, listing_src);
let payload = BootstrappingLoadState(
LoadStatePayload::new(wam_prelude.code.len(), term_stream)
);
let payload =
BootstrappingLoadState(LoadStatePayload::new(wam_prelude.code.len(), term_stream));
let loader: Loader<'_, BootstrappingLoadState> = Loader { payload, wam_prelude };
let loader: Loader<'_, BootstrappingLoadState> = Loader {
payload,
wam_prelude,
};
loader.load()?;
Ok(())
@@ -98,8 +96,8 @@ fn derelictize_try_me_else(
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(index, *o));
Some(mem::replace(o, 0))
}
Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => None,
Instruction::DynamicElse(_, _, NextOrFail::Fail(_))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => None,
Instruction::TryMeElse(0) => None,
Instruction::TryMeElse(ref mut o) => {
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(index, *o));
@@ -154,8 +152,8 @@ fn merge_indices(
fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
loop {
match &code[index] {
Instruction::DynamicElse(_, _, NextOrFail::Next(i)) |
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
Instruction::DynamicElse(_, _, NextOrFail::Next(i))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Next(i))
if *i > 0 =>
{
index += i;
@@ -170,42 +168,37 @@ fn find_outer_choice_instr(code: &Code, mut index: usize) -> usize {
fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> usize {
loop {
match &code[index] {
Instruction::TryMeElse(o) |
Instruction::RetryMeElse(o) => {
Instruction::TryMeElse(o) | Instruction::RetryMeElse(o) => {
if *o > 0 {
return index;
} else {
index = index_loc;
}
}
&Instruction::DynamicElse(_, _, next_or_fail) => {
match next_or_fail {
NextOrFail::Next(i) => {
if i == 0 {
index = index_loc;
} else {
return index;
}
}
NextOrFail::Fail(_) => {
&Instruction::DynamicElse(_, _, next_or_fail) => match next_or_fail {
NextOrFail::Next(i) => {
if i == 0 {
index = index_loc;
}
}
}
&Instruction::DynamicInternalElse(_, _, next_or_fail) => {
match next_or_fail {
NextOrFail::Next(i) => {
if i == 0 {
index = index_loc;
} else {
return index;
}
}
NextOrFail::Fail(_) => {
} else {
return index;
}
}
}
NextOrFail::Fail(_) => {
index = index_loc;
}
},
&Instruction::DynamicInternalElse(_, _, next_or_fail) => match next_or_fail {
NextOrFail::Next(i) => {
if i == 0 {
index = index_loc;
} else {
return index;
}
}
NextOrFail::Fail(_) => {
return index;
}
},
Instruction::TrustMe(_) => {
return index;
}
@@ -215,11 +208,7 @@ fn find_inner_choice_instr(code: &Code, mut index: usize, index_loc: usize) -> u
index += v;
}
IndexingCodePtr::DynamicExternal(v) => match &code[index + v] {
&Instruction::DynamicInternalElse(
_,
_,
NextOrFail::Next(0),
) => {
&Instruction::DynamicInternalElse(_, _, NextOrFail::Next(0)) => {
return index + v;
}
_ => {
@@ -309,8 +298,7 @@ fn merge_indexed_subsequences(
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
}
_ => {
code[inner_try_me_else_loc] =
Instruction::RetryMeElse(o);
code[inner_try_me_else_loc] = Instruction::RetryMeElse(o);
}
},
}
@@ -376,7 +364,9 @@ fn delete_from_skeleton(
}
if skeleton.core.is_dynamic {
skeleton.core.add_retracted_dynamic_clause_info(clause_index_info);
skeleton
.core
.add_retracted_dynamic_clause_info(clause_index_info);
retraction_info.push_record(RetractionRecord::RemovedDynamicSkeletonClause(
compilation_target,
@@ -409,8 +399,8 @@ fn blunt_leading_choice_instr(
code[instr_loc] = Instruction::TryMeElse(*o);
return instr_loc;
}
Instruction::DynamicElse(_, _, NextOrFail::Next(_)) |
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
Instruction::DynamicElse(_, _, NextOrFail::Next(_))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Next(_)) => {
return instr_loc;
}
&mut Instruction::DynamicElse(b, d, NextOrFail::Fail(o)) => {
@@ -422,26 +412,19 @@ fn blunt_leading_choice_instr(
code[instr_loc] = Instruction::DynamicElse(b, d, NextOrFail::Next(0));
return instr_loc;
}
&mut Instruction::DynamicInternalElse(
b,
d,
NextOrFail::Fail(o),
) => {
&mut Instruction::DynamicInternalElse(b, d, NextOrFail::Fail(o)) => {
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(
instr_loc,
NextOrFail::Fail(o),
));
code[instr_loc] = Instruction::DynamicInternalElse(
b,
d,
NextOrFail::Next(0),
);
code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Next(0));
return instr_loc;
}
Instruction::TrustMe(o) => {
retraction_info.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
retraction_info
.push_record(RetractionRecord::AppendedTrustMe(instr_loc, *o, false));
code[instr_loc] = Instruction::TryMeElse(0);
return instr_loc + 1;
@@ -481,9 +464,9 @@ fn set_switch_var_offset_to_choice_instr(
};
match &code[index_loc + v] {
Instruction::TryMeElse(_) |
Instruction::DynamicElse(..) |
Instruction::DynamicInternalElse(..) => {}
Instruction::TryMeElse(_)
| Instruction::DynamicElse(..)
| Instruction::DynamicInternalElse(..) => {}
_ => {
set_switch_var_offset(code, index_loc, offset, retraction_info);
}
@@ -523,9 +506,8 @@ fn internalize_choice_instr_at(
retraction_info: &mut RetractionInfo,
) {
match &mut code[instr_loc] {
Instruction::DynamicElse(_, _, NextOrFail::Fail(_)) |
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => {
}
Instruction::DynamicElse(_, _, NextOrFail::Fail(_))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(_)) => {}
Instruction::DynamicElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
retraction_info.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, 0));
*o = NextOrFail::Fail(0);
@@ -554,18 +536,10 @@ fn internalize_choice_instr_at(
match &mut code[instr_loc + o] {
Instruction::RevJmpBy(p) if *p == 0 => {
code[instr_loc] = Instruction::DynamicInternalElse(
b,
d,
NextOrFail::Fail(o),
);
code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Fail(o));
}
_ => {
code[instr_loc] = Instruction::DynamicInternalElse(
b,
d,
NextOrFail::Next(o),
);
code[instr_loc] = Instruction::DynamicInternalElse(b, d, NextOrFail::Next(o));
}
}
}
@@ -609,23 +583,20 @@ fn thread_choice_instr_at_to(
*o = target_loc - instr_loc;
return;
}
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o)) |
Instruction::DynamicInternalElse(
_,
_,
NextOrFail::Next(ref mut o),
) if target_loc >= instr_loc => {
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o))
if target_loc >= instr_loc =>
{
retraction_info
.push_record(RetractionRecord::ReplacedDynamicElseOffset(instr_loc, *o));
*o = target_loc - instr_loc;
return;
}
Instruction::DynamicElse(_, _, NextOrFail::Next(o)) |
Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
Instruction::DynamicElse(_, _, NextOrFail::Next(o))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Next(o)) => {
instr_loc += *o;
}
Instruction::TryMeElse(o)
| Instruction::RetryMeElse(o) => {
Instruction::TryMeElse(o) | Instruction::RetryMeElse(o) => {
instr_loc += *o;
}
Instruction::RevJmpBy(ref mut o) if instr_loc >= target_loc => {
@@ -642,7 +613,8 @@ fn thread_choice_instr_at_to(
{
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
code[instr_loc] = instr!("dynamic_else",
code[instr_loc] = instr!(
"dynamic_else",
birth,
death,
NextOrFail::Next(target_loc - instr_loc)
@@ -653,14 +625,13 @@ fn thread_choice_instr_at_to(
Instruction::DynamicElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
instr_loc += *o;
}
&mut Instruction::DynamicInternalElse(
birth,
death,
ref mut fail,
) if target_loc >= instr_loc => {
&mut Instruction::DynamicInternalElse(birth, death, ref mut fail)
if target_loc >= instr_loc =>
{
retraction_info.push_record(RetractionRecord::AppendedNextOrFail(instr_loc, *fail));
code[instr_loc] = instr!("dynamic_internal_else",
code[instr_loc] = instr!(
"dynamic_internal_else",
birth,
death,
NextOrFail::Next(target_loc - instr_loc)
@@ -668,9 +639,7 @@ fn thread_choice_instr_at_to(
return;
}
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o))
if *o > 0 =>
{
Instruction::DynamicInternalElse(_, _, NextOrFail::Fail(o)) if *o > 0 => {
instr_loc += *o;
}
Instruction::TrustMe(ref mut o) if target_loc >= instr_loc => {
@@ -711,33 +680,31 @@ fn remove_non_leading_clause(
None
}
Instruction::TrustMe(_) => {
match &mut code[preceding_choice_instr_loc] {
Instruction::RetryMeElse(o) => {
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
preceding_choice_instr_loc,
*o,
));
Instruction::TrustMe(_) => match &mut code[preceding_choice_instr_loc] {
Instruction::RetryMeElse(o) => {
retraction_info.push_record(RetractionRecord::ModifiedRetryMeElse(
preceding_choice_instr_loc,
*o,
));
code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
code[preceding_choice_instr_loc] = Instruction::TrustMe(0);
None
}
Instruction::TryMeElse(ref mut o) => {
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
preceding_choice_instr_loc,
*o,
));
*o = 0;
Some(IndexPtr::index(preceding_choice_instr_loc + 1))
}
_ => {
unreachable!();
}
None
}
}
Instruction::TryMeElse(ref mut o) => {
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
preceding_choice_instr_loc,
*o,
));
*o = 0;
Some(IndexPtr::index(preceding_choice_instr_loc + 1))
}
_ => {
unreachable!();
}
},
_ => {
unreachable!();
}
@@ -988,11 +955,7 @@ fn prepend_compiled_clause(
Instruction::TryMeElse(ref mut o) if *o == 0 => {
*o = prepend_queue_len - 2;
}
Instruction::DynamicInternalElse(
_,
_,
ref mut o @ NextOrFail::Next(0),
) => {
Instruction::DynamicInternalElse(_, _, ref mut o @ NextOrFail::Next(0)) => {
*o = NextOrFail::Fail(prepend_queue_len - 2);
}
_ => {
@@ -1258,7 +1221,11 @@ fn print_overwrite_warning(
_ => {}
}
println!("Warning: overwriting {}/{} because the clauses are discontiguous", key.0.as_str(), key.1);
println!(
"Warning: overwriting {}/{} because the clauses are discontiguous",
key.0.as_str(),
key.1
);
}
impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
@@ -1270,8 +1237,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
if let Some(path_str) = load_context.path.to_str() {
if !path_str.is_empty() {
return Some(LS::machine_st(&mut self.payload).atom_tbl.build_with(
path_str
return Some(AtomTable::build_with(
&LS::machine_st(&mut self.payload).atom_tbl,
path_str,
));
}
}
@@ -1290,10 +1258,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let clause = self.try_term_to_tl(term, &mut preprocessor)?;
// let queue = preprocessor.parse_queue(self)?;
let mut cg = CodeGenerator::new(
&mut LS::machine_st(&mut self.payload).atom_tbl,
settings,
);
let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
let clause_code = cg.compile_predicate(vec![clause])?;
@@ -1323,10 +1288,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clauses.push(self.try_term_to_tl(term, &mut preprocessor)?);
}
let mut cg = CodeGenerator::new(
&mut LS::machine_st(&mut self.payload).atom_tbl,
settings,
);
let mut cg = CodeGenerator::new(&LS::machine_st(&mut self.payload).atom_tbl, settings);
let mut code = cg.compile_predicate(clauses)?;
@@ -1361,26 +1323,23 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.clause_clause_locs
.extend(&clause_clause_locs.make_contiguous()[0..]);
self.payload.retraction_info
.push_record(RetractionRecord::SkeletonClauseTruncateBack(
self.payload.retraction_info.push_record(
RetractionRecord::SkeletonClauseTruncateBack(
predicates.compilation_target,
key,
skeleton_clause_len,
));
),
);
}
None => {
cg.skeleton
.core
.clause_clause_locs
.extend(&clause_clause_locs.make_contiguous()[0..]);
.core
.clause_clause_locs
.extend(&clause_clause_locs.make_contiguous()[0..]);
let skeleton = cg.skeleton;
self.add_extensible_predicate(
key,
skeleton,
predicates.compilation_target,
);
self.add_extensible_predicate(key, skeleton, predicates.compilation_target);
}
};
@@ -1450,11 +1409,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs = clause_clause_locs;
self.add_local_extensible_predicate(
*compilation_target,
*key,
skeleton,
);
self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1490,11 +1445,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs.push_front(code_len);
self.add_local_extensible_predicate(
*compilation_target,
*key,
skeleton,
);
self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1530,11 +1481,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
skeleton.clause_clause_locs.push_back(code_len);
self.add_local_extensible_predicate(
*compilation_target,
*key,
skeleton,
);
self.add_local_extensible_predicate(*compilation_target, *key, skeleton);
}
}
}
@@ -1606,7 +1553,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.core.clause_clause_locs.push_back(code_len);
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::SkeletonClausePopBack(
compilation_target,
key,
@@ -1624,8 +1572,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_back_to_local_predicate_skeleton(&compilation_target, &key, code_len);
let code_index =
self.get_or_insert_code_index(key, compilation_target);
let code_index = self.get_or_insert_code_index(key, compilation_target);
if let Some(new_code_ptr) = result {
set_code_index(
@@ -1646,7 +1593,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.core.clause_clause_locs.push_front(code_len);
skeleton.core.clause_assert_margin += 1;
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::SkeletonClausePopFront(
compilation_target,
key,
@@ -1666,8 +1614,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.push_front_to_local_predicate_skeleton(&compilation_target, &key, code_len);
let code_index =
self.get_or_insert_code_index(key, compilation_target);
let code_index = self.get_or_insert_code_index(key, compilation_target);
set_code_index(
&mut self.payload.retraction_info,
@@ -1698,19 +1645,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.opt_arg_index_key
.switch_on_term_loc()
{
Some(index_loc) => {
find_inner_choice_instr(
&self.wam_prelude.code,
skeleton.clauses[target_pos].clause_start,
index_loc,
)
}
Some(index_loc) => find_inner_choice_instr(
&self.wam_prelude.code,
skeleton.clauses[target_pos].clause_start,
index_loc,
),
None => skeleton.clauses[target_pos].clause_start,
};
match &mut self.wam_prelude.code[clause_loc] {
Instruction::DynamicElse(_, ref mut d, _) |
Instruction::DynamicInternalElse(_, ref mut d, _) => {
Instruction::DynamicElse(_, ref mut d, _)
| Instruction::DynamicInternalElse(_, ref mut d, _) => {
*d = Death::Finite(LS::machine_st(&mut self.payload).global_clock);
}
_ => unreachable!(),
@@ -1797,11 +1742,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
skeleton.clauses[target_pos + 1].clause_start =
skeleton.clauses[target_pos].clause_start;
let update_code_index = target_pos == 0 &&
skeleton.clauses[target_pos + 1]
.opt_arg_index_key
.switch_on_term_loc()
.is_none();
let update_code_index = target_pos == 0
&& skeleton.clauses[target_pos + 1]
.opt_arg_index_key
.switch_on_term_loc()
.is_none();
let index_ptr_opt = if update_code_index {
Some(IndexPtr::index(clause_loc))
@@ -1964,7 +1909,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
index_loc,
);
let lower_bound_clause_start = skeleton.clauses[lower_bound].clause_start;
let lower_bound_clause_start =
skeleton.clauses[lower_bound].clause_start;
let preceding_choice_instr_loc;
match &mut code[clause_start] {
@@ -2093,13 +2039,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
clause_clauses: ClauseIter,
append_or_prepend: AppendOrPrepend,
) -> Result<(), SessionError> {
let clause_predicates = clause_clauses.map(|(head, body)| {
Term::Clause(
Cell::default(),
atom!("$clause"),
vec![head, body],
)
});
let clause_predicates = clause_clauses
.map(|(head, body)| Term::Clause(Cell::default(), atom!("$clause"), vec![head, body]));
let clause_clause_compilation_target = match compilation_target {
CompilationTarget::User => CompilationTarget::Module(atom!("builtins")),
@@ -2132,21 +2073,21 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.cloned()
.collect()
}
Some(skeleton) => {
skeleton.core.clause_clause_locs.make_contiguous()[0..num_clause_predicates]
.iter()
.cloned()
.collect()
}
Some(skeleton) => skeleton.core.clause_clause_locs.make_contiguous()
[0..num_clause_predicates]
.iter()
.cloned()
.collect(),
None => {
unreachable!()
}
};
match self.wam_prelude.indices.get_predicate_skeleton_mut(
&clause_clause_compilation_target,
&(atom!("$clause"), 2),
) {
match self
.wam_prelude
.indices
.get_predicate_skeleton_mut(&clause_clause_compilation_target, &(atom!("$clause"), 2))
{
Some(skeleton) if append_or_prepend.is_append() => {
for _ in 0..num_clause_predicates {
skeleton.core.clause_clause_locs.pop_back();
@@ -2270,25 +2211,25 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
println!(
"Warning: overwriting multifile predicate {}:{}/{} because \
it was not locally declared multifile.",
self.payload.predicates.compilation_target, key.0.as_str(), key.1
self.payload.predicates.compilation_target,
key.0.as_str(),
key.1
);
}
if let Some(skeleton) = self
.wam_prelude
.indices
.remove_predicate_skeleton(&self.payload.predicates.compilation_target, &key)
{
if let Some(skeleton) = self.wam_prelude.indices.remove_predicate_skeleton(
&self.payload.predicates.compilation_target,
&key,
) {
let compilation_target = self.payload.predicates.compilation_target;
if predicate_info.is_dynamic {
let clause_clause_compilation_target =
match compilation_target {
CompilationTarget::User => {
CompilationTarget::Module(atom!("builtins"))
}
module => module,
};
let clause_clause_compilation_target = match compilation_target {
CompilationTarget::User => {
CompilationTarget::Module(atom!("builtins"))
}
module => module,
};
self.retract_local_clauses_by_locs(
clause_clause_compilation_target,
@@ -2301,11 +2242,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
self.payload.retraction_info.push_record(
RetractionRecord::RemovedSkeleton(
compilation_target,
key,
skeleton,
),
RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton),
);
}
}
@@ -2328,9 +2265,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
match self.wam_prelude.indices.modules.get_mut(&filename) {
Some(ref mut module) => {
let index_ptr = code_index.get();
let code_index = module.code_dir.entry(key)
.or_insert(code_index)
.clone();
let code_index = module.code_dir.entry(key).or_insert(code_index).clone();
set_code_index(
&mut self.payload.retraction_info,
@@ -2349,8 +2284,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
LS::machine_st(&mut self.payload).global_clock += 1;
let clause_clauses_len = self.payload.clause_clauses.len();
let clauses_vec: Vec<_> = self.payload
.clause_clauses.drain(0..std::cmp::min(predicates_len, clause_clauses_len))
let clauses_vec: Vec<_> = self
.payload
.clause_clauses
.drain(0..std::cmp::min(predicates_len, clause_clauses_len))
.collect();
let compilation_target = self.payload.predicates.compilation_target;
@@ -2374,10 +2311,7 @@ impl Machine {
module_name: HeapCellValue,
key: PredicateKey,
) -> CodeIndex {
let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
self,
InlineTermStream {},
);
let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(self, InlineTermStream {});
let module_name = if module_name.get_tag() == HeapCellValueTag::Atom {
cell_as_atom!(module_name)
@@ -2394,10 +2328,8 @@ impl Machine {
vars: &[Term],
) -> Result<(), SessionError> {
let mut compile = || {
let mut loader: Loader<'_, InlineLoadState<'_>> = Loader::new(
self,
InlineTermStream {},
);
let mut loader: Loader<'_, InlineLoadState<'_>> =
Loader::new(self, InlineTermStream {});
let term = loader.read_term_from_heap(term_loc)?;
let clause = build_rule_body(vars, term);

View File

@@ -91,12 +91,16 @@ impl<T: CopierTarget> CopyTermState<T> {
self.target.push(hcv);
}
let cdr = self.target.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
let cdr = self
.target
.store(self.target.deref(heap_loc_as_cell!(addr + 1)));
if !cdr.is_var() {
self.trail_list_cell(addr + 1, threshold);
} else {
let car = self.target.store(self.target.deref(heap_loc_as_cell!(addr)));
let car = self
.target
.store(self.target.deref(heap_loc_as_cell!(addr)));
if !car.is_var() {
self.trail_list_cell(addr, threshold);
@@ -188,10 +192,10 @@ impl<T: CopierTarget> CopyTermState<T> {
while let HeapCellValueTag::Lis = list_addr.get_tag() {
let threshold = self.target.threshold();
let heap_loc = list_addr.get_value() as usize;
let str_loc = self.target[heap_loc].get_value() as usize;
let str_loc = self.target[heap_loc].get_value() as usize;
self.target.push(heap_loc_as_cell!(threshold+2));
self.target.push(heap_loc_as_cell!(threshold+1));
self.target.push(heap_loc_as_cell!(threshold + 2));
self.target.push(heap_loc_as_cell!(threshold + 1));
read_heap_cell!(self.target[str_loc],
(HeapCellValueTag::Atom) => {
@@ -377,8 +381,9 @@ mod tests {
let a_atom = atom!("a");
let b_atom = atom!("b");
wam.machine_st.heap
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
wam.machine_st
.heap
.extend(functor!(f_atom, [atom(a_atom), atom(b_atom)]));
assert_eq!(wam.machine_st.heap[0], atom_as_cell!(f_atom, 2));
assert_eq!(wam.machine_st.heap[1], atom_as_cell!(a_atom));
@@ -401,20 +406,26 @@ mod tests {
wam.machine_st.heap.clear();
let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &mut wam.machine_st.atom_tbl);
let pstr_var_cell =
put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
let pstr_second_var_cell = put_partial_string(&mut wam.machine_st.heap, "def", &mut wam.machine_st.atom_tbl);
let pstr_second_var_cell =
put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st
.heap
.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
wam.machine_st
.heap
.push(fixnum_as_cell!(Fixnum::build_with(0i64)));
{
let wam = TermCopyingMockWAM { wam: &mut wam };
@@ -428,14 +439,20 @@ mod tests {
assert_eq!(wam.machine_st.heap[2], pstr_second_cell);
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(4));
assert_eq!(wam.machine_st.heap[4], pstr_offset_as_cell!(0));
assert_eq!(wam.machine_st.heap[5], fixnum_as_cell!(Fixnum::build_with(0i64)));
assert_eq!(
wam.machine_st.heap[5],
fixnum_as_cell!(Fixnum::build_with(0i64))
);
assert_eq!(wam.machine_st.heap[7], pstr_cell);
assert_eq!(wam.machine_st.heap[8], pstr_loc_as_cell!(9));
assert_eq!(wam.machine_st.heap[9], pstr_second_cell);
assert_eq!(wam.machine_st.heap[10], pstr_loc_as_cell!(11));
assert_eq!(wam.machine_st.heap[11], pstr_offset_as_cell!(7));
assert_eq!(wam.machine_st.heap[12], fixnum_as_cell!(Fixnum::build_with(0i64)));
assert_eq!(
wam.machine_st.heap[12],
fixnum_as_cell!(Fixnum::build_with(0i64))
);
wam.machine_st.heap.clear();

View File

@@ -74,7 +74,7 @@ impl BranchNumber {
fn halve_delta(&self) -> BranchNumber {
BranchNumber {
branch_num: self.branch_num.clone(),
delta : &self.delta / Rational::from(2),
delta: &self.delta / Rational::from(2),
}
}
}
@@ -108,7 +108,10 @@ pub struct BranchInfo {
impl BranchInfo {
fn new(branch_num: BranchNumber) -> Self {
Self { branch_num, chunks: vec![] }
Self {
branch_num,
chunks: vec![],
}
}
}
@@ -149,11 +152,11 @@ enum TraversalState {
// where it leaves off.
BuildFinalDisjunct(usize),
Fail,
GetCutPoint{ var_num: usize, prev_b: bool },
GetCutPoint { var_num: usize, prev_b: bool },
Cut { var_num: usize, is_global: bool },
ResetCallPolicy(CallPolicy),
Term(Term),
RemoveBranchNum, // pop the current_branch_num and from the root set.
RemoveBranchNum, // pop the current_branch_num and from the root set.
AddBranchNum(BranchNumber), // set current_branch_num, add it to the root set
RepBranchNum(BranchNumber), // replace current_branch_num and the latest in the root set
}
@@ -179,22 +182,22 @@ pub struct VarData {
impl VarData {
fn emit_initial_get_level(&mut self, build_stack: &mut ChunkedTermVec) {
let global_cut_var_num =
if let &Some(global_cut_var_num) = &self.global_cut_var_num {
match &self.records[global_cut_var_num].allocation {
VarAlloc::Perm(..) => Some(global_cut_var_num),
VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => {
Some(global_cut_var_num)
}
_ => None
let global_cut_var_num = if let &Some(global_cut_var_num) = &self.global_cut_var_num {
match &self.records[global_cut_var_num].allocation {
VarAlloc::Perm(..) => Some(global_cut_var_num),
VarAlloc::Temp { term_loc, .. } if term_loc.chunk_num() > 0 => {
Some(global_cut_var_num)
}
} else {
None
};
_ => None,
}
} else {
None
};
if let Some(global_cut_var_num) = global_cut_var_num {
let term = QueryTerm::GetLevel(global_cut_var_num);
self.records[global_cut_var_num].allocation = VarAlloc::Perm(0, PermVarAllocation::Pending);
self.records[global_cut_var_num].allocation =
VarAlloc::Perm(0, PermVarAllocation::Pending);
match build_stack.front_mut() {
Some(ChunkedTerms::Branch(_)) => {
@@ -229,7 +232,7 @@ fn merge_branch_seq(branches: impl Iterator<Item = BranchInfo>) -> BranchInfo {
}
fn flatten_into_disjunct(build_stack: &mut ChunkedTermVec, preceding_len: usize) {
let branch_vec = build_stack.drain(preceding_len + 1 ..).collect();
let branch_vec = build_stack.drain(preceding_len + 1..).collect();
if let ChunkedTerms::Branch(ref mut disjuncts) = &mut build_stack[preceding_len] {
disjuncts.push(branch_vec);
@@ -254,11 +257,14 @@ impl VariableClassifier {
pub fn classify_fact(mut self, term: Term) -> Result<ClassifyFactResult, CompilationError> {
self.classify_head_variables(&term)?;
Ok((term, self.branch_map.separate_and_classify_variables(
self.var_num,
self.global_cut_var_num,
self.current_chunk_num,
)))
Ok((
term,
self.branch_map.separate_and_classify_variables(
self.var_num,
self.global_cut_var_num,
self.current_chunk_num,
),
))
}
pub fn classify_rule<'a, LS: LoadState<'a>>(
@@ -298,7 +304,7 @@ impl VariableClassifier {
}
}
let iter = old_branches.drain(old_branches_len - 1 ..);
let iter = old_branches.drain(old_branches_len - 1..);
branches.push(merge_branch_seq(iter));
}
@@ -346,9 +352,13 @@ impl VariableClassifier {
}
fn probe_body_var(&mut self, var_info: VarInfo) {
let term_loc = self.current_chunk_type.to_gen_context(self.current_chunk_num);
let term_loc = self
.current_chunk_type
.to_gen_context(self.current_chunk_num);
let branch_info_v = self.branch_map.entry(var_info.var_ptr.clone())
let branch_info_v = self
.branch_map
.entry(var_info.var_ptr.clone())
.or_insert_with(|| vec![]);
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
@@ -396,12 +406,14 @@ impl VariableClassifier {
fn classify_head_variables(&mut self, term: &Term) -> Result<(), CompilationError> {
match term {
Term::Clause(..) | Term::Literal(_, Literal::Atom(_)) => {
}
Term::Clause(..) | Term::Literal(_, Literal::Atom(_)) => {}
_ => return Err(CompilationError::InvalidRuleHead),
}
let mut classify_info = ClassifyInfo { arg_c: 1, arity: term.arity() };
let mut classify_info = ClassifyInfo {
arg_c: 1,
arity: term.arity(),
};
match term {
Term::Clause(_, _, terms) => {
@@ -414,13 +426,16 @@ impl VariableClassifier {
// the body of the if let here is an inlined
// "probe_head_var". note the difference between it
// and "probe_body_var".
let branch_info_v = self.branch_map.entry(var_ptr.clone())
let branch_info_v = self
.branch_map
.entry(var_ptr.clone())
.or_insert_with(|| vec![]);
let needs_new_branch = branch_info_v.is_empty();
if needs_new_branch {
branch_info_v.push(BranchInfo::new(self.current_branch_num.clone()));
branch_info_v
.push(BranchInfo::new(self.current_branch_num.clone()));
}
let branch_info = branch_info_v.last_mut().unwrap();
@@ -509,13 +524,11 @@ impl VariableClassifier {
self.probe_in_situ_var(var_num);
build_stack.push_chunk_term(
if is_global {
QueryTerm::GlobalCut(var_num)
} else {
QueryTerm::LocalCut(var_num)
}
);
build_stack.push_chunk_term(if is_global {
QueryTerm::GlobalCut(var_num)
} else {
QueryTerm::LocalCut(var_num)
});
}
TraversalState::Fail => {
build_stack.push_chunk_term(QueryTerm::Fail);
@@ -539,22 +552,28 @@ impl VariableClassifier {
classifier.probe_body_term(arg_c + 1, terms.len(), term);
}
build_stack.push_chunk_term(
clause_to_query_term(
loader,
name,
terms,
classifier.call_policy,
),
);
build_stack.push_chunk_term(clause_to_query_term(
loader,
name,
terms,
classifier.call_policy,
));
};
match term {
Term::Clause(_, name @ (atom!("->") | atom!(";") | atom!(",")), mut terms) if terms.len() == 3 => {
Term::Clause(
_,
name @ (atom!("->") | atom!(";") | atom!(",")),
mut terms,
) if terms.len() == 3 => {
if let Some(last_arg) = terms.last() {
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
terms.pop();
state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), name, terms)));
state_stack.push(TraversalState::Term(Term::Clause(
Cell::default(),
name,
terms,
)));
} else {
add_chunk(self, name, terms);
}
@@ -583,7 +602,7 @@ impl VariableClassifier {
let mut branch_numbers = vec![first_branch_num];
for idx in 1 .. branches.len() {
for idx in 1..branches.len() {
let succ_branch_number = branch_numbers[idx - 1].incr_by_delta();
branch_numbers.push(if idx + 1 < branches.len() {
@@ -610,8 +629,11 @@ impl VariableClassifier {
state_stack.push(TraversalState::AddBranchNum(branch_num));
}
if let TraversalState::BuildDisjunct(build_stack_len) = state_stack[final_disjunct_loc] {
state_stack[final_disjunct_loc] = TraversalState::BuildFinalDisjunct(build_stack_len);
if let TraversalState::BuildDisjunct(build_stack_len) =
state_stack[final_disjunct_loc]
{
state_stack[final_disjunct_loc] =
TraversalState::BuildFinalDisjunct(build_stack_len);
}
self.current_chunk_type = ChunkType::Mid;
@@ -621,18 +643,30 @@ impl VariableClassifier {
let then_term = terms.pop().unwrap();
let if_term = terms.pop().unwrap();
let prev_b = if matches!(state_stack.last(), Some(TraversalState::RemoveBranchNum)) {
let prev_b = if matches!(
state_stack.last(),
Some(TraversalState::RemoveBranchNum)
) {
// check if the second-to-last element is a regular BuildDisjunct, as we don't
// want to add GetPrevLevel in case of a TrustMe.
matches!(state_stack.iter().rev().nth(1), Some(TraversalState::BuildDisjunct(..)))
matches!(
state_stack.iter().rev().nth(1),
Some(TraversalState::BuildDisjunct(..))
)
} else {
false
};
state_stack.push(TraversalState::Term(then_term));
state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false });
state_stack.push(TraversalState::Cut {
var_num: self.var_num,
is_global: false,
});
state_stack.push(TraversalState::Term(if_term));
state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b });
state_stack.push(TraversalState::GetCutPoint {
var_num: self.var_num,
prev_b,
});
self.var_num += 1;
}
@@ -643,12 +677,22 @@ impl VariableClassifier {
build_stack.reserve_branch(2);
state_stack.push(TraversalState::BuildFinalDisjunct(build_stack_len));
state_stack.push(TraversalState::Term(Term::Clause(Cell::default(), atom!("$succeed"), vec![])));
state_stack.push(TraversalState::Term(Term::Clause(
Cell::default(),
atom!("$succeed"),
vec![],
)));
state_stack.push(TraversalState::BuildDisjunct(build_stack_len));
state_stack.push(TraversalState::Fail);
state_stack.push(TraversalState::Cut { var_num: self.var_num, is_global: false });
state_stack.push(TraversalState::Cut {
var_num: self.var_num,
is_global: false,
});
state_stack.push(TraversalState::Term(not_term));
state_stack.push(TraversalState::GetCutPoint { var_num: self.var_num, prev_b: true });
state_stack.push(TraversalState::GetCutPoint {
var_num: self.var_num,
prev_b: true,
});
self.current_chunk_type = ChunkType::Mid;
self.current_chunk_num += 1;
@@ -668,15 +712,13 @@ impl VariableClassifier {
build_stack.add_chunk();
}
build_stack.push_chunk_term(
qualified_clause_to_query_term(
loader,
module_name,
predicate_name,
vec![],
self.call_policy,
),
);
build_stack.push_chunk_term(qualified_clause_to_query_term(
loader,
module_name,
predicate_name,
vec![],
self.call_policy,
));
}
(
Term::Literal(_, Literal::Atom(module_name)),
@@ -690,15 +732,13 @@ impl VariableClassifier {
self.probe_body_term(arg_c + 1, terms.len(), term);
}
build_stack.push_chunk_term(
qualified_clause_to_query_term(
loader,
module_name,
name,
terms,
self.call_policy,
),
);
build_stack.push_chunk_term(qualified_clause_to_query_term(
loader,
module_name,
name,
terms,
self.call_policy,
));
}
(module_name, predicate_name) => {
if update_chunk_data(self, atom!("call"), 2) {
@@ -711,18 +751,18 @@ impl VariableClassifier {
terms.push(module_name);
terms.push(predicate_name);
build_stack.push_chunk_term(
clause_to_query_term(
loader,
atom!("call"),
vec![Term::Clause(Cell::default(), atom!(":"), terms)],
self.call_policy,
),
);
build_stack.push_chunk_term(clause_to_query_term(
loader,
atom!("call"),
vec![Term::Clause(Cell::default(), atom!(":"), terms)],
self.call_policy,
));
}
}
}
Term::Clause(_, atom!("$call_with_inference_counting"), mut terms) if terms.len() == 1 => {
Term::Clause(_, atom!("$call_with_inference_counting"), mut terms)
if terms.len() == 1 =>
{
state_stack.push(TraversalState::ResetCallPolicy(self.call_policy));
state_stack.push(TraversalState::Term(terms.pop().unwrap()));
@@ -738,14 +778,12 @@ impl VariableClassifier {
self.probe_body_term(1, 1, &var);
build_stack.push_chunk_term(
clause_to_query_term(
loader,
atom!("call"),
vec![var],
self.call_policy,
),
);
build_stack.push_chunk_term(clause_to_query_term(
loader,
atom!("call"),
vec![var],
self.call_policy,
));
}
Term::Literal(_, Literal::Atom(atom!("!")) | Literal::Char('!')) => {
if self.global_cut_var_num.is_none() {
@@ -765,14 +803,12 @@ impl VariableClassifier {
build_stack.add_chunk();
}
build_stack.push_chunk_term(
clause_to_query_term(
loader,
name,
vec![],
self.call_policy,
),
);
build_stack.push_chunk_term(clause_to_query_term(
loader,
name,
vec![],
self.call_policy,
));
}
_ => {
return Err(CompilationError::InadmissibleQueryTerm);
@@ -800,12 +836,11 @@ impl BranchMap {
};
for (var, branches) in self.iter_mut() {
let (mut var_num, var_num_incr) =
if let Var::InSitu(var_num) = *var.borrow() {
(var_num, false)
} else {
(var_data.records.len(), true)
};
let (mut var_num, var_num_incr) = if let Var::InSitu(var_num) = *var.borrow() {
(var_num, false)
} else {
(var_data.records.len(), true)
};
for branch in branches.iter_mut() {
if var_num_incr {
@@ -813,7 +848,8 @@ impl BranchMap {
var_data.records.push(VariableRecord::default());
}
if branch.chunks.len() <= 1 { // true iff var is a temporary variable.
if branch.chunks.len() <= 1 {
// true iff var is a temporary variable.
debug_assert_eq!(branch.chunks.len(), 1);
let chunk = &mut branch.chunks[0];
@@ -822,7 +858,9 @@ impl BranchMap {
for var_info in chunk.vars.iter_mut() {
if var_info.lvl == Level::Shallow {
let term_loc = var_info.chunk_type.to_gen_context(chunk.chunk_num);
temp_var_data.use_set.insert((term_loc, var_info.classify_info.arg_c));
temp_var_data
.use_set
.insert((term_loc, var_info.classify_info.arg_c));
}
}

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -130,11 +130,7 @@ pub fn print_heap_terms<'a, I: Iterator<Item = &'a HeapCellValue>>(heap: I, h: u
}
#[inline]
pub(crate) fn put_complete_string(
heap: &mut Heap,
s: &str,
atom_tbl: &mut AtomTable,
) -> HeapCellValue {
pub(crate) fn put_complete_string(heap: &mut Heap, s: &str, atom_tbl: &AtomTable) -> HeapCellValue {
match allocate_pstr(heap, s, atom_tbl) {
Some(h) => {
heap.pop(); // pop the trailing variable cell from the heap planted by allocate_pstr.
@@ -157,11 +153,7 @@ pub(crate) fn put_complete_string(
}
#[inline]
pub(crate) fn put_partial_string(
heap: &mut Heap,
s: &str,
atom_tbl: &mut AtomTable,
) -> HeapCellValue {
pub(crate) fn put_partial_string(heap: &mut Heap, s: &str, atom_tbl: &AtomTable) -> HeapCellValue {
match allocate_pstr(heap, s, atom_tbl) {
Some(h) => {
pstr_loc_as_cell!(h)
@@ -173,11 +165,7 @@ pub(crate) fn put_partial_string(
}
#[inline]
pub(crate) fn allocate_pstr(
heap: &mut Heap,
mut src: &str,
atom_tbl: &mut AtomTable,
) -> Option<usize> {
pub(crate) fn allocate_pstr(heap: &mut Heap, mut src: &str, atom_tbl: &AtomTable) -> Option<usize> {
let orig_h = heap.len();
loop {
@@ -258,7 +246,10 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usiz
let extract_integer = |s: usize| -> Option<usize> {
match Number::try_from(heap[s]) {
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
Ok(Number::Integer(n)) => n.to_usize(),
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
},
_ => None,
}
};

View File

@@ -1,5 +1,6 @@
use std::collections::BTreeSet;
use crate::atom_table;
use crate::machine::BREAK_FROM_DISPATCH_LOOP_LOC;
use crate::machine::mock_wam::{CompositeOpDir, Term};
use crate::parser::parser::{Parser, Tokens};
@@ -58,7 +59,7 @@ impl Machine {
pub fn consult_module_string(&mut self, module_name: &str, program: String) {
let stream = Stream::from_owned_string(program, &mut self.machine_st.arena);
self.machine_st.registers[1] = stream_as_cell!(stream);
self.machine_st.registers[2] = atom_as_cell!(self.machine_st.atom_tbl.build_with(module_name));
self.machine_st.registers[2] = atom_as_cell!(&atom_table::AtomTable::build_with(&self.machine_st.atom_tbl, module_name));
self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2));
}

View File

@@ -63,21 +63,27 @@ fn add_op_decl_as_module_export<'a, LS: LoadState<'a>>(
match op_decl.insert_into_op_dir(wam_op_dir) {
Some(op_desc) => {
payload.retraction_info.push_record(RetractionRecord::ReplacedUserOp(
*op_decl,
op_desc,
));
payload
.retraction_info
.push_record(RetractionRecord::ReplacedUserOp(*op_decl, op_desc));
payload.module_op_exports.push((*op_decl, Some(op_desc)));
}
None => {
payload.retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl));
payload
.retraction_info
.push_record(RetractionRecord::AddedUserOp(*op_decl));
payload.module_op_exports.push((*op_decl, None));
}
}
let compilation_target = payload.compilation_target;
add_op_decl(&mut payload.retraction_info, &compilation_target, module_op_dir, op_decl);
add_op_decl(
&mut payload.retraction_info,
&compilation_target,
module_op_dir,
op_decl,
);
}
pub(super) fn add_op_decl(
@@ -89,10 +95,7 @@ pub(super) fn add_op_decl(
match op_decl.insert_into_op_dir(op_dir) {
Some(op_desc) => match &compilation_target {
CompilationTarget::User => {
retraction_info.push_record(RetractionRecord::ReplacedUserOp(
*op_decl,
op_desc,
));
retraction_info.push_record(RetractionRecord::ReplacedUserOp(*op_decl, op_desc));
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(RetractionRecord::ReplacedModuleOp(
@@ -107,10 +110,8 @@ pub(super) fn add_op_decl(
retraction_info.push_record(RetractionRecord::AddedUserOp(*op_decl));
}
CompilationTarget::Module(ref module_name) => {
retraction_info.push_record(RetractionRecord::AddedModuleOp(
*module_name,
*op_decl,
));
retraction_info
.push_record(RetractionRecord::AddedModuleOp(*module_name, *op_decl));
}
},
}
@@ -160,7 +161,12 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
}
}
ModuleExport::OpDecl(ref op_decl) => {
add_op_decl(&mut payload.retraction_info, compilation_target, op_dir, op_decl);
add_op_decl(
&mut payload.retraction_info,
compilation_target,
op_dir,
op_decl,
);
}
}
}
@@ -209,12 +215,7 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
}
}
ModuleExport::OpDecl(ref op_decl) => {
add_op_decl_as_module_export::<LS>(
payload,
op_dir,
wam_op_dir,
op_decl,
);
add_op_decl_as_module_export::<LS>(payload, op_dir, wam_op_dir, op_decl);
}
}
}
@@ -239,13 +240,18 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
let key = (*name, *arity);
if let Some(meta_specs) = imported_module.meta_predicates.get(&key) {
wam_prelude.indices.meta_predicates.insert(key.clone(), meta_specs.clone());
wam_prelude
.indices
.meta_predicates
.insert(key.clone(), meta_specs.clone());
}
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
let arena = &mut LS::machine_st(payload).arena;
let target_code_index = wam_prelude.indices.code_dir
let target_code_index = wam_prelude
.indices
.code_dir
.entry(key.clone())
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
.clone();
@@ -325,12 +331,7 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
}
}
ModuleExport::OpDecl(ref op_decl) => {
add_op_decl_as_module_export::<LS>(
payload,
op_dir,
wam_op_dir,
op_decl,
);
add_op_decl_as_module_export::<LS>(payload, op_dir, wam_op_dir, op_decl);
}
}
}
@@ -378,10 +379,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
mut clause_target_poses: Vec<Option<usize>>,
is_dynamic: bool,
) {
let old_compilation_target = mem::replace(
&mut self.payload.compilation_target,
compilation_target,
);
let old_compilation_target =
mem::replace(&mut self.payload.compilation_target, compilation_target);
while let Some(target_pos_opt) = clause_target_poses.pop() {
match target_pos_opt {
@@ -482,7 +481,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let old_index_ptr = code_index.replace(IndexPtr::undefined());
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::ReplacedModulePredicate(
module_name,
*key,
@@ -491,7 +491,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
for (key, skeleton) in removed_module.extensible_predicates.drain(..) {
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::RemovedSkeleton(
CompilationTarget::Module(module_name),
key,
@@ -499,7 +500,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
));
}
self.wam_prelude.indices.modules.insert(module_name, removed_module);
self.wam_prelude
.indices
.modules
.insert(module_name, removed_module);
}
pub(super) fn remove_module_exports(&mut self, module_name: Atom) {
@@ -523,15 +527,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
(Some(module_code_index), Some(target_code_index))
if module_code_index.get() == target_code_index.get() =>
{
let old_index_ptr = target_code_index.replace(IndexPtr::undefined());
retraction_info.push_record(predicate_retractor(*key, old_index_ptr));
let old_index_ptr =
target_code_index.replace(IndexPtr::undefined());
retraction_info
.push_record(predicate_retractor(*key, old_index_ptr));
}
_ => {}
}
}
ModuleExport::OpDecl(op_decl) => {
let op_dir_value_opt =
op_dir.remove(&(op_decl.name, fixity(op_decl.op_desc.get_spec() as u32)));
let op_dir_value_opt = op_dir
.remove(&(op_decl.name, fixity(op_decl.op_desc.get_spec() as u32)));
if let Some(op_desc) = op_dir_value_opt {
retraction_info.push_record(op_retractor(*op_decl, op_desc));
@@ -552,9 +558,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
RetractionRecord::ReplacedUserOp,
);
}
CompilationTarget::Module(target_module_name)
if target_module_name != module_name =>
{
CompilationTarget::Module(target_module_name) if target_module_name != module_name => {
let predicate_retractor = |key, index_ptr| {
RetractionRecord::ReplacedModulePredicate(module_name, key, index_ptr)
};
@@ -563,7 +567,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
RetractionRecord::ReplacedModuleOp(module_name, op_decl, op_desc)
};
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&target_module_name) {
if let Some(module) = self
.wam_prelude
.indices
.modules
.get_mut(&target_module_name)
{
remove_module_exports(
&removed_module,
&mut module.code_dir,
@@ -579,7 +588,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
CompilationTarget::Module(_) => {}
};
self.wam_prelude.indices.modules.insert(module_name, removed_module);
self.wam_prelude
.indices
.modules
.insert(module_name, removed_module);
}
fn get_or_insert_local_code_index(
@@ -591,10 +603,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
Some(ref mut module) => module
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
))
.or_insert_with(|| {
CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
)
})
.clone(),
None => {
self.add_dynamically_generated_module(module_name);
@@ -603,10 +617,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
Some(ref mut module) => module
.code_dir
.entry(key)
.or_insert_with(|| CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
))
.or_insert_with(|| {
CodeIndex::new(
IndexPtr::undefined(),
&mut LS::machine_st(&mut self.payload).arena,
)
})
.clone(),
None => {
unreachable!()
@@ -771,10 +787,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
ClauseType::Named(arity, name, _) => {
let payload_compilation_target = self.payload.compilation_target;
let idx = self.get_or_insert_code_index(
(name, arity),
payload_compilation_target,
);
let idx = self.get_or_insert_code_index((name, arity), payload_compilation_target);
ClauseType::Named(arity, name, idx)
}
@@ -802,13 +815,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
pub(super) fn get_meta_specs(&self, name: Atom, arity: usize) -> Option<&Vec<MetaSpec>> {
self.wam_prelude
.indices
.get_meta_predicate_spec(
name,
arity,
&self.payload.compilation_target,
)
self.wam_prelude.indices.get_meta_predicate_spec(
name,
arity,
&self.payload.compilation_target,
)
}
pub(super) fn add_meta_predicate_record(
@@ -829,19 +840,18 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.insert(key, meta_specs)
{
Some(old_meta_specs) => {
self.payload.retraction_info
.push_record(RetractionRecord::ReplacedMetaPredicate(
self.payload.retraction_info.push_record(
RetractionRecord::ReplacedMetaPredicate(
module_name,
key.0,
old_meta_specs,
));
),
);
}
None => {
self.payload.retraction_info
.push_record(RetractionRecord::AddedMetaPredicate(
module_name,
key,
));
self.payload
.retraction_info
.push_record(RetractionRecord::AddedMetaPredicate(module_name, key));
}
}
}
@@ -868,17 +878,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
None => {
self.add_dynamically_generated_module(module_name);
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&module_name) {
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&module_name)
{
module.meta_predicates.insert(key.clone(), meta_specs);
} else {
unreachable!()
}
self.payload.retraction_info
.push_record(RetractionRecord::AddedMetaPredicate(
module_name.clone(),
key,
));
self.payload.retraction_info.push_record(
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
);
}
}
}
@@ -901,10 +910,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
&mut module.meta_predicates,
);
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::AddedModule(module_name.clone()));
self.wam_prelude.indices.modules.insert(module_name.clone(), module);
self.wam_prelude
.indices
.modules
.insert(module_name.clone(), module);
}
fn import_builtins_in_module(
@@ -968,9 +981,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
if is_dynamic {
let clause_clause_compilation_target = match compilation_target {
CompilationTarget::User => {
CompilationTarget::Module(atom!("builtins"))
}
CompilationTarget::User => CompilationTarget::Module(atom!("builtins")),
module => module.clone(),
};
@@ -981,7 +992,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
}
self.payload.retraction_info
self.payload
.retraction_info
.push_record(RetractionRecord::ReplacedModule(
old_module_decl,
listing_src.clone(),
@@ -1051,7 +1063,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
)?;
}
CompilationTarget::Module(ref defining_module_name) => {
match self.wam_prelude.indices.modules.get_mut(defining_module_name) {
match self
.wam_prelude
.indices
.modules
.get_mut(defining_module_name)
{
Some(ref mut target_module) => {
import_module_exports_into_module::<LS>(
&mut self.payload,
@@ -1091,17 +1108,20 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let payload_compilation_target = self.payload.compilation_target;
let result = match &payload_compilation_target {
CompilationTarget::User => {
import_qualified_module_exports::<LS>(
&mut self.payload,
&payload_compilation_target,
&module,
&exports,
&mut self.wam_prelude,
)
}
CompilationTarget::User => import_qualified_module_exports::<LS>(
&mut self.payload,
&payload_compilation_target,
&module,
&exports,
&mut self.wam_prelude,
),
CompilationTarget::Module(ref defining_module_name) => {
match self.wam_prelude.indices.modules.get_mut(defining_module_name) {
match self
.wam_prelude
.indices
.modules
.get_mut(defining_module_name)
{
Some(ref mut target_module) => {
import_qualified_module_exports_into_module::<LS>(
&mut self.payload,
@@ -1113,9 +1133,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
&mut self.wam_prelude.indices.op_dir,
)
}
None => {
Err(SessionError::ModuleCannotImportSelf(module_name))
}
None => Err(SessionError::ModuleCannotImportSelf(module_name)),
}
}
};
@@ -1123,29 +1141,38 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
self.wam_prelude.indices.modules.insert(module_name, module);
result
} else {
Err(SessionError::ExistenceError(ExistenceError::Module(module_name)))
Err(SessionError::ExistenceError(ExistenceError::Module(
module_name,
)))
}
}
pub(crate) fn use_module(&mut self, module_src: ModuleSource) -> Result<(), SessionError> {
let (stream, listing_src) = match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
let mut path_buf = PathBuf::from(&*filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
(
Stream::from_file_as_input(filename, file, &mut LS::machine_st(&mut self.payload).arena),
Stream::from_file_as_input(
filename,
file,
&mut LS::machine_st(&mut self.payload).arena,
),
ListingSource::File(filename, path_buf),
)
}
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
Some(code) => {
if let Some(ref module) = self.wam_prelude.indices.modules.get(&library) {
if let ListingSource::DynamicallyGenerated = &module.listing_src {
(
Stream::from_static_string(*code, &mut LS::machine_st(&mut self.payload).arena),
Stream::from_static_string(
*code,
&mut LS::machine_st(&mut self.payload).arena,
),
ListingSource::User,
)
} else {
@@ -1153,7 +1180,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
} else {
(
Stream::from_static_string(*code, &mut LS::machine_st(&mut self.payload).arena),
Stream::from_static_string(
*code,
&mut LS::machine_st(&mut self.payload).arena,
),
ListingSource::User,
)
}
@@ -1172,9 +1202,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
);
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
payload: BootstrappingLoadState(
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream)
),
payload: BootstrappingLoadState(LoadStatePayload::new(
self.wam_prelude.code.len(),
term_stream,
)),
wam_prelude: MachinePreludeView {
indices: self.wam_prelude.indices,
code: self.wam_prelude.code,
@@ -1201,22 +1232,29 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
) -> Result<(), SessionError> {
let (stream, listing_src) = match module_src {
ModuleSource::File(filename) => {
let mut path_buf = PathBuf::from(filename.as_str());
let mut path_buf = PathBuf::from(&*filename.as_str());
path_buf.set_extension("pl");
let file = File::open(&path_buf)?;
(
Stream::from_file_as_input(filename, file, &mut LS::machine_st(&mut self.payload).arena),
Stream::from_file_as_input(
filename,
file,
&mut LS::machine_st(&mut self.payload).arena,
),
ListingSource::File(filename, path_buf),
)
}
ModuleSource::Library(library) => match LIBRARIES.borrow().get(library.as_str()) {
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
Some(code) => {
if self.wam_prelude.indices.modules.contains_key(&library) {
return self.import_qualified_module(library, exports);
} else {
(
Stream::from_static_string(*code, &mut LS::machine_st(&mut self.payload).arena),
Stream::from_static_string(
*code,
&mut LS::machine_st(&mut self.payload).arena,
),
ListingSource::User,
)
}
@@ -1235,9 +1273,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
);
let subloader: Loader<'_, BootstrappingLoadState> = Loader {
payload: BootstrappingLoadState(
LoadStatePayload::new(self.wam_prelude.code.len(), term_stream),
),
payload: BootstrappingLoadState(LoadStatePayload::new(
self.wam_prelude.code.len(),
term_stream,
)),
wam_prelude: MachinePreludeView {
indices: self.wam_prelude.indices,
code: self.wam_prelude.code,

View File

@@ -230,9 +230,7 @@ macro_rules! predicate_queue {
pub type LiveLoadState = LoadStatePayload<LiveTermStream>;
pub struct BootstrappingLoadState<'a>(
pub LoadStatePayload<BootstrappingTermStream<'a>>
);
pub struct BootstrappingLoadState<'a>(pub LoadStatePayload<BootstrappingTermStream<'a>>);
impl<'a> Deref for BootstrappingLoadState<'a> {
type Target = LoadStatePayload<BootstrappingTermStream<'a>>;
@@ -253,9 +251,12 @@ impl<'a> DerefMut for BootstrappingLoadState<'a> {
pub trait LoadState<'a>: Sized {
type Evacuable;
type TS: TermStream;
type LoaderFieldType: DerefMut<Target=LoadStatePayload<Self::TS>>;
type LoaderFieldType: DerefMut<Target = LoadStatePayload<Self::TS>>;
fn new(machine_st: &'a mut MachineState, payload: LoadStatePayload<Self::TS>) -> Self::LoaderFieldType;
fn new(
machine_st: &'a mut MachineState,
payload: LoadStatePayload<Self::TS>,
) -> Self::LoaderFieldType;
fn evacuate(loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError>;
fn should_drop_load_state(loader: &Loader<'a, Self>) -> bool;
fn reset_machine(loader: &mut Loader<'a, Self>);
@@ -293,14 +294,23 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> {
type Evacuable = TypedArenaPtr<LiveLoadState>;
#[inline(always)]
fn new(machine_st: &'a mut MachineState, payload: LoadStatePayload<Self::TS>) -> Self::LoaderFieldType {
fn new(
machine_st: &'a mut MachineState,
payload: LoadStatePayload<Self::TS>,
) -> Self::LoaderFieldType {
let load_state = arena_alloc!(payload, &mut machine_st.arena);
LiveLoadAndMachineState { load_state, machine_st }
LiveLoadAndMachineState {
load_state,
machine_st,
}
}
#[inline(always)]
fn evacuate(mut loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError> {
loader.payload.load_state.set_tag(ArenaHeaderTag::InactiveLoadState);
loader
.payload
.load_state
.set_tag(ArenaHeaderTag::InactiveLoadState);
Ok(loader.payload.load_state)
}
@@ -332,7 +342,11 @@ impl<'a> LoadState<'a> for LiveLoadAndMachineState<'a> {
}
if let Some(builtins) = loader.wam_prelude.indices.modules.get(&atom!("builtins")) {
if builtins.module_decl.exports.contains(&ModuleExport::PredicateKey(key)) {
if builtins
.module_decl
.exports
.contains(&ModuleExport::PredicateKey(key))
{
return Err(SessionError::CannotOverwriteBuiltIn(key));
}
}
@@ -358,10 +372,7 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
let repo_len = loader.wam_prelude.code.len();
loader
.payload
.retraction_info
.reset(repo_len);
loader.payload.retraction_info.reset(repo_len);
loader.remove_module_op_exports();
@@ -419,22 +430,27 @@ impl<'a> LoadState<'a> for InlineLoadState<'a> {
type Evacuable = ();
#[inline(always)]
fn new(machine_st: &'a mut MachineState, payload: LoadStatePayload<Self::TS>) -> Self::LoaderFieldType {
InlineLoadState { machine_st, payload }
fn new(
machine_st: &'a mut MachineState,
payload: LoadStatePayload<Self::TS>,
) -> Self::LoaderFieldType {
InlineLoadState {
machine_st,
payload,
}
}
fn evacuate(_loader: Loader<'a, Self>) -> Result<Self::Evacuable, SessionError> {
Ok(())
Ok(())
}
#[inline(always)]
fn should_drop_load_state(_loader: &Loader<'a, Self>) -> bool {
false
false
}
#[inline(always)]
fn reset_machine(_loader: &mut Loader<'a, Self>) {
}
fn reset_machine(_loader: &mut Loader<'a, Self>) {}
#[inline(always)]
fn machine_st(load_state: &mut Self::LoaderFieldType) -> &mut MachineState {
@@ -548,7 +564,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
atom!("user") => {
self.wam_prelude.indices.meta_predicates.remove(&key);
}
_ => match self.wam_prelude.indices.modules.get_mut(&target_module_name) {
_ => match self
.wam_prelude
.indices
.modules
.get_mut(&target_module_name)
{
Some(ref mut module) => {
module.meta_predicates.remove(&key);
}
@@ -566,7 +587,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.meta_predicates
.insert((name, meta_specs.len()), meta_specs);
}
_ => match self.wam_prelude.indices.modules.get_mut(&target_module_name) {
_ => match self
.wam_prelude
.indices
.modules
.get_mut(&target_module_name)
{
Some(ref mut module) => {
module
.meta_predicates
@@ -773,9 +799,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
RetractionRecord::ReplacedChoiceOffset(instr_loc, offset) => {
match self.wam_prelude.code[instr_loc] {
Instruction::TryMeElse(ref mut o) |
Instruction::RetryMeElse(ref mut o) |
Instruction::DefaultRetryMeElse(ref mut o) => {
Instruction::TryMeElse(ref mut o)
| Instruction::RetryMeElse(ref mut o)
| Instruction::DefaultRetryMeElse(ref mut o) => {
*o = offset;
}
_ => {
@@ -792,16 +818,18 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
RetractionRecord::ReplacedSwitchOnTermVarIndex(index_loc, old_v) => {
match self.wam_prelude.code[index_loc] {
Instruction::IndexingCode(ref mut indexing_code) => match &mut indexing_code[0] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
_,
ref mut v,
..,
)) => {
*v = old_v;
Instruction::IndexingCode(ref mut indexing_code) => {
match &mut indexing_code[0] {
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
_,
ref mut v,
..,
)) => {
*v = old_v;
}
_ => {}
}
_ => {}
},
}
_ => {}
}
}
@@ -941,7 +969,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
.get_predicate_skeleton_mut(&compilation_target, &key)
{
Some(skeleton) => {
if let Some(removed_clauses) = &mut skeleton.core.retracted_dynamic_clauses {
if let Some(removed_clauses) =
&mut skeleton.core.retracted_dynamic_clauses
{
let clause_index_info = removed_clauses.pop().unwrap();
skeleton
@@ -1001,10 +1031,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton) => {
match compilation_target {
CompilationTarget::User => {
self.wam_prelude.indices.extensible_predicates.insert(key, skeleton);
self.wam_prelude
.indices
.extensible_predicates
.insert(key, skeleton);
}
CompilationTarget::Module(module_name) => {
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&module_name) {
if let Some(module) =
self.wam_prelude.indices.modules.get_mut(&module_name)
{
module.extensible_predicates.insert(key, skeleton);
}
}
@@ -1012,16 +1047,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
RetractionRecord::ReplacedDynamicElseOffset(instr_loc, next) => {
match self.wam_prelude.code[instr_loc] {
Instruction::DynamicElse(
_,
_,
NextOrFail::Next(ref mut o),
)
| Instruction::DynamicInternalElse(
_,
_,
NextOrFail::Next(ref mut o),
) => {
Instruction::DynamicElse(_, _, NextOrFail::Next(ref mut o))
| Instruction::DynamicInternalElse(_, _, NextOrFail::Next(ref mut o)) => {
*o = next;
}
_ => {}
@@ -1029,16 +1056,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
}
RetractionRecord::AppendedNextOrFail(instr_loc, fail) => {
match self.wam_prelude.code[instr_loc] {
Instruction::DynamicElse(
_,
_,
ref mut next_or_fail,
)
| Instruction::DynamicInternalElse(
_,
_,
ref mut next_or_fail,
) => {
Instruction::DynamicElse(_, _, ref mut next_or_fail)
| Instruction::DynamicInternalElse(_, _, ref mut next_or_fail) => {
*next_or_fail = fail;
}
_ => {}
@@ -1057,15 +1076,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let export_list = machine_st.read_term_from_heap(cell)?;
let atom_tbl = &mut LS::machine_st(&mut self.payload).atom_tbl;
let export_list = setup_module_export_list(export_list, atom_tbl)?;
let export_list = setup_module_export_list(export_list, &atom_tbl)?;
Ok(export_list.into_iter().collect())
}
fn add_clause_clause(&mut self, term: Term) -> Result<(), CompilationError> {
match term {
Term::Clause(_, atom!(":-"), mut terms) if terms.len() == 2 =>
{
Term::Clause(_, atom!(":-"), mut terms) if terms.len() == 2 => {
let body = terms.pop().unwrap();
let head = terms.pop().unwrap();
@@ -1096,20 +1114,14 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
match &compilation_target {
CompilationTarget::User => {
match self
.wam_prelude
.indices
.extensible_predicates
.get_mut(&key)
{
match self.wam_prelude.indices.extensible_predicates.get_mut(&key) {
Some(skeleton) => {
if !*flag_accessor(&mut skeleton.core) {
*flag_accessor(&mut skeleton.core) = true;
self.payload.retraction_info.push_record(retraction_fn(
compilation_target,
key,
));
self.payload
.retraction_info
.push_record(retraction_fn(compilation_target, key));
}
}
None => {
@@ -1117,11 +1129,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton.core) = true;
self.add_extensible_predicate(
key,
skeleton,
CompilationTarget::User,
);
self.add_extensible_predicate(key, skeleton, CompilationTarget::User);
} else {
throw_permission_error = true;
}
@@ -1135,10 +1143,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
if !*flag_accessor(&mut skeleton.core) {
*flag_accessor(&mut skeleton.core) = true;
self.payload.retraction_info.push_record(retraction_fn(
compilation_target,
key,
));
self.payload
.retraction_info
.push_record(retraction_fn(compilation_target, key));
}
}
None => {
@@ -1146,11 +1153,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton.core) = true;
self.add_extensible_predicate(
key,
skeleton,
compilation_target,
);
self.add_extensible_predicate(key, skeleton, compilation_target);
} else {
throw_permission_error = true;
}
@@ -1162,11 +1165,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = PredicateSkeleton::new();
*flag_accessor(&mut skeleton.core) = true;
self.add_extensible_predicate(
key,
skeleton,
compilation_target,
);
self.add_extensible_predicate(key, skeleton, compilation_target);
}
}
}
@@ -1178,15 +1177,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
match payload_compilation_target {
CompilationTarget::User => {
match self
.wam_prelude
.indices
.get_local_predicate_skeleton_mut(
payload_compilation_target,
compilation_target,
listing_src_file_name,
key,
) {
match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
payload_compilation_target,
compilation_target,
listing_src_file_name,
key,
) {
Some(skeleton) => {
if !*flag_accessor(skeleton) {
*flag_accessor(skeleton) = true;
@@ -1196,11 +1192,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true;
self.add_local_extensible_predicate(
compilation_target,
key,
skeleton,
);
self.add_local_extensible_predicate(compilation_target, key, skeleton);
}
}
}
@@ -1232,11 +1224,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let mut skeleton = LocalPredicateSkeleton::new();
*flag_accessor(&mut skeleton) = true;
self.add_local_extensible_predicate(
compilation_target,
key,
skeleton,
);
self.add_local_extensible_predicate(compilation_target, key, skeleton);
}
}
}
@@ -1336,10 +1324,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let is_dynamic = self
.wam_prelude
.indices
.get_predicate_skeleton(
&predicates_compilation_target,
&(predicate_name, arity),
)
.get_predicate_skeleton(&predicates_compilation_target, &(predicate_name, arity))
.map(|skeleton| skeleton.core.is_dynamic)
.unwrap_or(false);
@@ -1356,15 +1341,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
let predicates_compilation_target = self.payload.predicates.compilation_target;
let listing_src_file_name = self.listing_src_file_name();
let clause_locs = match self
.wam_prelude
.indices
.get_local_predicate_skeleton_mut(
payload_compilation_target,
predicates_compilation_target,
listing_src_file_name,
*key,
) {
let clause_locs = match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
payload_compilation_target,
predicates_compilation_target,
listing_src_file_name,
*key,
) {
Some(skeleton) if !skeleton.clause_clause_locs.is_empty() => {
mem::replace(&mut skeleton.clause_clause_locs, VecDeque::new())
}
@@ -1380,11 +1362,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
),
);
self.retract_local_clauses_impl(
predicates_compilation_target,
*key,
&clause_locs,
);
self.retract_local_clauses_impl(predicates_compilation_target, *key, &clause_locs);
if is_dynamic {
let clause_clause_compilation_target = match predicates_compilation_target {
@@ -1399,7 +1377,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
impl<'a> MachinePreludeView<'a> {
#[inline]
pub(super) fn composite_op_dir(&self, compilation_target: &CompilationTarget) -> CompositeOpDir {
pub(super) fn composite_op_dir(
&self,
compilation_target: &CompilationTarget,
) -> CompositeOpDir {
match compilation_target {
CompilationTarget::User => CompositeOpDir::new(&self.indices.op_dir, None),
CompilationTarget::Module(ref module_name) => {
@@ -1417,7 +1398,10 @@ impl<'a> MachinePreludeView<'a> {
}
impl MachineState {
pub(super) fn read_term_from_heap(&mut self, term_addr: HeapCellValue) -> Result<Term, SessionError> {
pub(super) fn read_term_from_heap(
&mut self,
term_addr: HeapCellValue,
) -> Result<Term, SessionError> {
let mut term_stack = vec![];
let mut iter = stackful_post_order_iter(&mut self.heap, &mut self.stack, term_addr);
@@ -1436,7 +1420,7 @@ impl MachineState {
term_stack.push(Term::PartialString(Cell::default(), string, tail));
}
Ok((string, None)) => {
let atom = self.atom_tbl.build_with(&string);
let atom = AtomTable::build_with(&self.atom_tbl, &string);
term_stack.push(Term::CompleteString(Cell::default(), atom));
}
Err(cons_term) => term_stack.push(cons_term),
@@ -1550,9 +1534,9 @@ impl Machine {
}
pub(crate) fn load_compiled_library(&mut self) -> CallResult {
let library = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let library = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
if let Some(module) = self.indices.modules.get(&library) {
if let ListingSource::DynamicallyGenerated = module.listing_src {
@@ -1583,9 +1567,9 @@ impl Machine {
}
pub(crate) fn declare_module(&mut self) -> CallResult {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
@@ -1652,7 +1636,10 @@ impl Machine {
let arity = self.deref_register(3);
let arity = match Number::try_from(arity) {
Ok(Number::Integer(n)) if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => Ok(n.to_usize().unwrap()),
Ok(Number::Integer(n)) if &*n >= &Integer::from(0) && &*n <= &Integer::from(MAX_ARITY) => {
let value: usize = (&*n).try_into().unwrap();
Ok(value)
},
Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => {
Ok(usize::try_from(n.get_num()).unwrap())
}
@@ -1692,9 +1679,9 @@ impl Machine {
}
pub(crate) fn add_goal_expansion_clause(&mut self) -> CallResult {
let target_module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let target_module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let mut loader = self.loader_from_heap_evacuable(temp_v!(3));
@@ -1714,7 +1701,8 @@ impl Machine {
if let Some(indexing_term) = indexing_arg {
if let Some(indexing_name) = indexing_term.name() {
loader.wam_prelude
loader
.wam_prelude
.indices
.goal_expansion_indices
.insert((indexing_name, indexing_term.arity()));
@@ -1789,16 +1777,19 @@ impl Machine {
&'a mut self,
r: RegType,
) -> Loader<'a, LiveLoadAndMachineState<'a>> {
let mut load_state = cell_as_load_state_payload!(
self.machine_st.store(self.machine_st.deref(self.machine_st[r]))
);
let mut load_state = cell_as_load_state_payload!(self
.machine_st
.store(self.machine_st.deref(self.machine_st[r])));
load_state.set_tag(ArenaHeaderTag::LiveLoadState);
let (wam_prelude, machine_st) = self.prelude_view_and_machine_st();
Loader {
payload: LiveLoadAndMachineState { load_state, machine_st },
payload: LiveLoadAndMachineState {
load_state,
machine_st,
},
wam_prelude,
}
}
@@ -1806,26 +1797,21 @@ impl Machine {
#[inline]
pub(crate) fn push_load_state_payload(&mut self) {
let payload = arena_alloc!(
LoadStatePayload::new(
self.code.len(),
LiveTermStream::new(ListingSource::User),
),
LoadStatePayload::new(self.code.len(), LiveTermStream::new(ListingSource::User),),
&mut self.machine_st.arena
);
let var = self.machine_st.deref(self.machine_st.registers[1]);
self.machine_st.bind(
var.as_var().unwrap(),
typed_arena_ptr_as_cell!(payload),
);
self.machine_st
.bind(var.as_var().unwrap(), typed_arena_ptr_as_cell!(payload));
}
#[inline]
pub(crate) fn pop_load_state_payload(&mut self) {
let load_state_payload = self.machine_st.store(
self.machine_st.deref(self.machine_st.registers[1])
);
let load_state_payload = self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1]));
// unlike in loader_from_heap_evacuable,
// pop_load_state_payload is allowed to fail to find a
@@ -1863,11 +1849,12 @@ impl Machine {
2,
)?;
let path = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[2]))
);
let path = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[2])));
self.load_contexts.push(LoadContext::new(path.as_str(), stream));
self.load_contexts
.push(LoadContext::new(&*path.as_str(), stream));
Ok(())
}
@@ -1876,9 +1863,7 @@ impl Machine {
result: Result<TypedArenaPtr<LiveLoadState>, SessionError>,
) -> CallResult {
match result {
Ok(_payload) => {
Ok(())
}
Ok(_payload) => Ok(()),
Err(e) => {
let err = self.machine_st.session_error(e);
let stub = functor_stub(atom!("load"), 1);
@@ -1889,9 +1874,9 @@ impl Machine {
}
pub(crate) fn scoped_clause_to_evacuable(&mut self) -> CallResult {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let loader = self.loader_from_heap_evacuable(temp_v!(3));
@@ -1931,9 +1916,10 @@ impl Machine {
pub(crate) fn load_context_source(&mut self) {
if let Some(load_context) = self.load_contexts.last() {
let path_str = load_context.path.to_str().unwrap();
let path_atom = self.machine_st.atom_tbl.build_with(path_str);
let path_atom = AtomTable::build_with(&self.machine_st.atom_tbl, path_str);
self.machine_st.unify_atom(path_atom, self.machine_st.registers[1]);
self.machine_st
.unify_atom(path_atom, self.machine_st.registers[1]);
} else {
self.machine_st.fail = true;
}
@@ -1944,9 +1930,11 @@ impl Machine {
match load_context.path.file_name() {
Some(file_name) if load_context.path.is_file() => {
let file_name_str = file_name.to_str().unwrap();
let file_name_atom = self.machine_st.atom_tbl.build_with(file_name_str);
let file_name_atom =
AtomTable::build_with(&self.machine_st.atom_tbl, file_name_str);
self.machine_st.unify_atom(file_name_atom, self.machine_st.registers[1]);
self.machine_st
.unify_atom(file_name_atom, self.machine_st.registers[1]);
return;
}
_ => {
@@ -1962,9 +1950,11 @@ impl Machine {
if let Some(load_context) = self.load_contexts.last() {
if let Some(directory) = load_context.path.parent() {
let directory_str = directory.to_str().unwrap();
let directory_atom = self.machine_st.atom_tbl.build_with(directory_str);
let directory_atom =
AtomTable::build_with(&self.machine_st.atom_tbl, directory_str);
self.machine_st.unify_atom(directory_atom, self.machine_st.registers[1]);
self.machine_st
.unify_atom(directory_atom, self.machine_st.registers[1]);
return;
}
}
@@ -1999,11 +1989,9 @@ impl Machine {
_ => CompilationTarget::Module(module_name),
};
let stub_gen = || {
match append_or_prepend {
AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1),
AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1),
}
let stub_gen = || match append_or_prepend {
AppendOrPrepend::Append => functor_stub(atom!("assertz"), 1),
AppendOrPrepend::Prepend => functor_stub(atom!("asserta"), 1),
};
let head = self.deref_register(2);
@@ -2019,7 +2007,8 @@ impl Machine {
loader.payload.compilation_target = compilation_target;
let head = LiveLoadAndMachineState::machine_st(&mut loader.payload).read_term_from_heap(head)?;
let head = LiveLoadAndMachineState::machine_st(&mut loader.payload)
.read_term_from_heap(head)?;
let name = if let Some(name) = head.name() {
name
@@ -2031,32 +2020,24 @@ impl Machine {
let is_builtin = loader.wam_prelude.indices.builtin_property((name, arity));
let is_dynamic_predicate = loader
.wam_prelude
.indices
.is_dynamic_predicate(
module_name,
(name, arity),
);
.wam_prelude
.indices
.is_dynamic_predicate(module_name, (name, arity));
let no_such_predicate =
if !is_dynamic_predicate && !is_builtin {
let idx_tag = loader
.wam_prelude
.indices
.get_predicate_code_index(
name,
arity,
module_name,
)
.map(|code_idx| code_idx.get_tag())
.unwrap_or(IndexPtrTag::DynamicUndefined);
let no_such_predicate = if !is_dynamic_predicate && !is_builtin {
let idx_tag = loader
.wam_prelude
.indices
.get_predicate_code_index(name, arity, module_name)
.map(|code_idx| code_idx.get_tag())
.unwrap_or(IndexPtrTag::DynamicUndefined);
idx_tag == IndexPtrTag::DynamicUndefined || idx_tag == IndexPtrTag::Undefined
} else if is_builtin {
return Err(SessionError::CannotOverwriteBuiltIn((name, arity)));
} else {
is_dynamic_predicate
};
idx_tag == IndexPtrTag::DynamicUndefined || idx_tag == IndexPtrTag::Undefined
} else if is_builtin {
return Err(SessionError::CannotOverwriteBuiltIn((name, arity)));
} else {
is_dynamic_predicate
};
if !no_such_predicate {
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail = true;
@@ -2098,23 +2079,18 @@ impl Machine {
match compile_assert() {
Ok(_) => Ok(()),
Err(SessionError::CompilationError(
CompilationError::InvalidRuleHead |
CompilationError::InadmissibleFact
CompilationError::InvalidRuleHead | CompilationError::InadmissibleFact,
)) => {
let err = self.machine_st.type_error(
ValidType::Callable,
self.machine_st.registers[2],
);
let err = self
.machine_st
.type_error(ValidType::Callable, self.machine_st.registers[2]);
Err(self.machine_st.error_form(err, stub_gen()))
}
Err(SessionError::CompilationError(
CompilationError::InadmissibleQueryTerm
)) => {
let err = self.machine_st.type_error(
ValidType::Callable,
self.machine_st.registers[3],
);
Err(SessionError::CompilationError(CompilationError::InadmissibleQueryTerm)) => {
let err = self
.machine_st
.type_error(ValidType::Callable, self.machine_st.registers[3]);
Err(self.machine_st.error_form(err, stub_gen()))
}
@@ -2126,9 +2102,9 @@ impl Machine {
}
pub(crate) fn abolish_clause(&mut self) -> CallResult {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let key = self
.machine_st
@@ -2140,8 +2116,8 @@ impl Machine {
};
let mut abolish_clause = || {
let mut loader: Loader<'_, LiveLoadAndMachineState<'_>>
= Loader::new(self, LiveTermStream::new(ListingSource::User));
let mut loader: Loader<'_, LiveLoadAndMachineState<'_>> =
Loader::new(self, LiveTermStream::new(ListingSource::User));
loader.payload.compilation_target = compilation_target;
@@ -2161,9 +2137,11 @@ impl Machine {
.remove_predicate_skeleton(
&clause_clause_compilation_target,
&(atom!("$clause"), 2),
).unwrap();
)
.unwrap();
let result = skeleton.core
let result = skeleton
.core
.clause_clause_locs
.iter()
.map(|clause_clause_loc| {
@@ -2173,11 +2151,7 @@ impl Machine {
})
.collect();
loader.add_extensible_predicate(
key,
skeleton,
compilation_target,
);
loader.add_extensible_predicate(key, skeleton, compilation_target);
loader.add_extensible_predicate(
(atom!("$clause"), 2),
@@ -2186,14 +2160,15 @@ impl Machine {
);
result
}).unwrap();
})
.unwrap();
loader.wam_prelude
loader
.wam_prelude
.indices
.remove_predicate_skeleton(&compilation_target, &key);
let mut code_index = loader
.get_or_insert_code_index(key, compilation_target);
let mut code_index = loader.get_or_insert_code_index(key, compilation_target);
code_index.set(IndexPtr::undefined());
@@ -2226,14 +2201,17 @@ impl Machine {
.store(self.machine_st.deref(self.machine_st[temp_v!(3)]));
let target_pos = match Number::try_from(target_pos) {
Ok(Number::Integer(n)) => n.to_usize().unwrap(),
Ok(Number::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
value
},
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
_ => unreachable!(),
};
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[4]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[4])));
let compilation_target = match module_name {
atom!("user") => CompilationTarget::User,
@@ -2286,9 +2264,9 @@ impl Machine {
}
pub(crate) fn is_consistent_with_term_queue(&mut self) -> CallResult {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let key = self
.machine_st
@@ -2303,8 +2281,8 @@ impl Machine {
LiveLoadAndMachineState::machine_st(&mut loader.payload).fail =
(!loader.payload.predicates.is_empty()
&& loader.payload.predicates.compilation_target != compilation_target)
|| !key.is_consistent(&loader.payload.predicates);
&& loader.payload.predicates.compilation_target != compilation_target)
|| !key.is_consistent(&loader.payload.predicates);
let result = LiveLoadAndMachineState::evacuate(loader);
self.restore_load_state_payload(result)
@@ -2326,9 +2304,9 @@ impl Machine {
}
pub(crate) fn remove_module_exports(&mut self) -> CallResult {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let mut loader = self.loader_from_heap_evacuable(temp_v!(2));
@@ -2354,9 +2332,9 @@ impl Machine {
}
pub(crate) fn meta_predicate_property(&mut self) {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let (predicate_name, arity) = self
.machine_st
@@ -2374,9 +2352,12 @@ impl Machine {
Some(meta_specs) => {
let term_loc = self.machine_st.heap.len();
self.machine_st.heap.push(atom_as_cell!(predicate_name, arity));
self.machine_st.heap.extend(
meta_specs.iter().map(|meta_spec| match meta_spec {
self.machine_st
.heap
.push(atom_as_cell!(predicate_name, arity));
self.machine_st
.heap
.extend(meta_specs.iter().map(|meta_spec| match meta_spec {
MetaSpec::Minus => atom_as_cell!(atom!("+")),
MetaSpec::Plus => atom_as_cell!(atom!("-")),
MetaSpec::Either => atom_as_cell!(atom!("?")),
@@ -2384,15 +2365,20 @@ impl Machine {
MetaSpec::RequiresExpansionWithArgument(ref arg_num) => {
fixnum_as_cell!(Fixnum::build_with(*arg_num as i64))
}
})
);
}));
let heap_loc = self.machine_st.heap.len();
self.machine_st.heap.push(atom_as_cell!(atom!("meta_predicate"), 1));
self.machine_st
.heap
.push(atom_as_cell!(atom!("meta_predicate"), 1));
self.machine_st.heap.push(str_loc_as_cell!(term_loc));
unify!(self.machine_st, str_loc_as_cell!(heap_loc), self.machine_st.registers[4]);
unify!(
self.machine_st,
str_loc_as_cell!(heap_loc),
self.machine_st.registers[4]
);
}
None => {
self.machine_st.fail = true;
@@ -2401,9 +2387,9 @@ impl Machine {
}
pub(crate) fn dynamic_property(&mut self) {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let key = self
.machine_st
@@ -2428,9 +2414,9 @@ impl Machine {
}
pub(crate) fn multifile_property(&mut self) {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let key = self
.machine_st
@@ -2455,9 +2441,9 @@ impl Machine {
}
pub(crate) fn discontiguous_property(&mut self) {
let module_name = cell_as_atom!(
self.machine_st.store(self.machine_st.deref(self.machine_st.registers[1]))
);
let module_name = cell_as_atom!(self
.machine_st
.store(self.machine_st.deref(self.machine_st.registers[1])));
let key = self
.machine_st

View File

@@ -44,7 +44,8 @@ pub(crate) enum ValidType {
InCharacter,
Integer,
List,
#[allow(unused)] Number,
#[allow(unused)]
Number,
Pair,
// PredicateIndicator,
// Variable
@@ -254,9 +255,11 @@ pub(super) type FunctorStub = [HeapCellValue; 3];
#[inline(always)]
pub(super) fn functor_stub(name: Atom, arity: usize) -> FunctorStub {
[atom_as_cell!(atom!("/"), 2),
atom_as_cell!(name),
fixnum_as_cell!(Fixnum::build_with(arity as i64))]
[
atom_as_cell!(atom!("/"), 2),
atom_as_cell!(name),
fixnum_as_cell!(Fixnum::build_with(arity as i64)),
]
}
impl MachineState {
@@ -440,11 +443,13 @@ impl MachineState {
pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
match err {
SessionError::CannotOverwriteBuiltIn(key) => {
// SessionError::CannotOverwriteImport(pred_atom) => {
// SessionError::CannotOverwriteImport(pred_atom) => {
self.permission_error(
Permission::Modify,
atom!("static_procedure"),
functor_stub(key.0, key.1).into_iter().collect::<MachineStub>(),
functor_stub(key.0, key.1)
.into_iter()
.collect::<MachineStub>(),
)
}
SessionError::ExistenceError(err) => self.existence_error(err),
@@ -471,7 +476,11 @@ impl MachineState {
}
SessionError::NamelessEntry => {
let error_atom = atom!("nameless_procedure");
self.permission_error(Permission::Create, atom!("static_procedure"), functor!(error_atom))
self.permission_error(
Permission::Create,
atom!("static_procedure"),
functor!(error_atom),
)
}
SessionError::OpIsInfixAndPostFix(op) => {
self.permission_error(Permission::Create, atom!("operator"), functor!(op))
@@ -541,21 +550,21 @@ impl MachineState {
#[cfg(feature = "ffi")]
pub(super) fn ffi_error(&mut self, err: FFIError) -> MachineError {
let error_atom = match err {
FFIError::ValueCast => atom!("value_cast"),
FFIError::ValueDontFit => atom!("value_dont_fit"),
FFIError::InvalidFFIType => atom!("invalid_ffi_type"),
FFIError::InvalidStructName => atom!("invalid_struct_name"),
FFIError::FunctionNotFound => atom!("function_not_found"),
FFIError::StructNotFound => atom!("struct_not_found"),
};
let stub = functor!(atom!("ffi_error"),[atom(error_atom)]);
let error_atom = match err {
FFIError::ValueCast => atom!("value_cast"),
FFIError::ValueDontFit => atom!("value_dont_fit"),
FFIError::InvalidFFIType => atom!("invalid_ffi_type"),
FFIError::InvalidStructName => atom!("invalid_struct_name"),
FFIError::FunctionNotFound => atom!("function_not_found"),
FFIError::StructNotFound => atom!("struct_not_found"),
};
let stub = functor!(atom!("ffi_error"), [atom(error_atom)]);
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
MachineError {
stub,
location: None,
from: ErrorProvenance::Constructed,
}
}
pub(super) fn error_form(&mut self, err: MachineError, src: FunctorStub) -> MachineStub {
@@ -682,10 +691,12 @@ impl CompilationError {
&CompilationError::ExpectedRel => {
functor!(atom!("expected_relation"))
}
&CompilationError::InadmissibleFact => { // TODO: type_error(callable, _).
&CompilationError::InadmissibleFact => {
// TODO: type_error(callable, _).
functor!(atom!("inadmissible_fact"))
}
&CompilationError::InadmissibleQueryTerm => { // TODO: type_error(callable, _).
&CompilationError::InadmissibleQueryTerm => {
// TODO: type_error(callable, _).
functor!(atom!("inadmissible_query_term"))
}
&CompilationError::InconsistentEntry => {
@@ -820,10 +831,10 @@ pub enum CycleSearchResult {
Cyclic(usize),
EmptyList,
NotList(usize, HeapCellValue), // the list length until the second argument in the heap
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
PartialList(usize, Ref), // the list length (up to max), and an offset into the heap.
ProperList(usize), // the list length.
PStrLocation(usize, usize, usize), // list length (up to max), the heap address of the PStr, the offset
UntouchedList(usize, usize), // list length (up to max), the address of an uniterated Addr::Lis(address).
UntouchedList(usize, usize), // list length (up to max), the address of an uniterated Addr::Lis(address).
UntouchedCStr(Atom, usize),
}
@@ -838,7 +849,7 @@ impl MachineState {
match BrentAlgState::detect_cycles(&self.heap, list) {
CycleSearchResult::PartialList(..) => {
let err = self.instantiation_error();
return Err(self.error_form(err, stub_gen()))
return Err(self.error_form(err, stub_gen()));
}
CycleSearchResult::NotList(..) | CycleSearchResult::Cyclic(_) => {
let err = self.type_error(ValidType::List, list);

View File

@@ -3,15 +3,15 @@ use crate::parser::ast::*;
use crate::arena::*;
use crate::atom_table::*;
use crate::forms::*;
use crate::machine::ClauseType;
use crate::machine::loader::*;
use crate::machine::machine_state::*;
use crate::machine::streams::Stream;
use crate::machine::ClauseType;
use fxhash::FxBuildHasher;
use indexmap::{IndexMap, IndexSet};
use modular_bitfield::{BitfieldSpecifier, bitfield};
use modular_bitfield::specifiers::*;
use modular_bitfield::{bitfield, BitfieldSpecifier};
use std::cmp::Ordering;
use std::collections::BTreeSet;
@@ -21,14 +21,6 @@ use crate::types::*;
#[derive(Debug, Clone, PartialEq, Eq, PartialOrd, Ord, Hash)]
pub(crate) struct OrderedOpDirKey(pub(crate) Atom, pub(crate) Fixity);
pub(crate) type OssifiedOpDir = IndexMap<(Atom, Fixity), (usize, Specifier)>;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum DBRef {
NamedPred(Atom, usize),
Op(Atom, Fixity, TypedArenaPtr<OssifiedOpDir>),
}
// 7.2
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
pub enum TermOrderCategory {
@@ -86,7 +78,8 @@ pub enum IndexPtrTag {
#[derive(Debug, Clone, Copy, Eq, Hash, Ord, PartialEq, PartialOrd)]
pub struct IndexPtr {
pub p: B56,
#[allow(unused)] m: bool,
#[allow(unused)]
m: bool,
pub tag: IndexPtrTag,
}
@@ -143,10 +136,10 @@ impl IndexPtr {
#[derive(Debug, Clone, Copy, Ord, Hash, PartialOrd, Eq, PartialEq)]
pub struct CodeIndex(TypedArenaPtr<IndexPtr>);
#[cfg(target_pointer_width="32")]
#[cfg(target_pointer_width = "32")]
const_assert!(std::mem::align_of::<CodeIndex>() == 4);
#[cfg(target_pointer_width="64")]
#[cfg(target_pointer_width = "64")]
const_assert!(std::mem::align_of::<CodeIndex>() == 8);
impl Deref for CodeIndex {
@@ -293,7 +286,8 @@ impl IndexStore {
let (name, arity) = key;
if !ClauseType::is_inbuilt(name, arity) {
self.modules.get(&(atom!("builtins")))
self.modules
.get(&(atom!("builtins")))
.map(|module| module.code_dir.contains_key(&(name, arity)))
.unwrap_or(false)
} else {
@@ -444,11 +438,7 @@ impl IndexStore {
}
}
pub(crate) fn is_dynamic_predicate(
&self,
module_name: Atom,
key: PredicateKey,
) -> bool {
pub(crate) fn is_dynamic_predicate(&self, module_name: Atom, key: PredicateKey) -> bool {
match module_name {
atom!("user") => self
.extensible_predicates

View File

@@ -3,7 +3,6 @@ use crate::atom_table::*;
use crate::forms::*;
use crate::heap_iter::*;
use crate::heap_print::*;
use crate::machine::Machine;
use crate::machine::attributed_variables::*;
use crate::machine::copier::*;
use crate::machine::heap::*;
@@ -11,6 +10,7 @@ use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::machine::stack::*;
use crate::machine::streams::*;
use crate::machine::Machine;
use crate::parser::ast::*;
use crate::read::TermWriteResult;
use crate::types::*;
@@ -22,6 +22,7 @@ use indexmap::IndexMap;
use std::convert::TryFrom;
use std::fmt;
use std::ops::{Index, IndexMut};
use std::sync::Arc;
pub(crate) type Registers = [HeapCellValue; MAX_ARITY + 1];
@@ -57,14 +58,14 @@ pub enum OnEOF {
}
pub struct MachineState {
pub atom_tbl: AtomTable,
pub atom_tbl: Arc<AtomTable>,
pub arena: Arena,
pub(super) pdl: Vec<HeapCellValue>,
pub(super) s: HeapPtr,
pub(super) s_offset: usize,
pub(super) p: usize,
pub(super) oip: u32, // first internal code ptr
pub(super) iip : u32, // second internal code ptr
pub(super) iip: u32, // second internal code ptr
pub(super) b: usize,
pub(super) b0: usize,
pub(super) e: usize,
@@ -79,7 +80,7 @@ pub struct MachineState {
pub(super) trail: Vec<TrailEntry>,
pub(super) tr: usize,
pub(super) hb: usize,
pub(super) block: usize, // an offset into the OR stack.
pub(super) block: usize, // an offset into the OR stack.
pub(super) scc_block: usize, // an offset into the OR stack for setup_call_cleanup/3.
pub(super) ball: Ball,
pub(super) ball_stack: Vec<Ball>, // save current ball before jumping via, e.g., verify_attr interrupt.
@@ -203,12 +204,12 @@ pub fn pstr_loc_and_offset(heap: &[HeapCellValue], index: usize) -> (usize, Fixn
fn push_var_eq_functors<'a>(
heap: &mut Heap,
iter: impl Iterator<Item = (&'a VarKey, &'a HeapCellValue)>,
atom_tbl: &mut AtomTable,
atom_tbl: &AtomTable,
) -> Vec<HeapCellValue> {
let mut list_of_var_eqs = vec![];
for (var, binding) in iter {
let var_atom = atom_tbl.build_with(&var.to_string());
let var_atom = AtomTable::build_with(atom_tbl, &var.to_string());
let h = heap.len();
heap.push(atom_as_cell!(atom!("="), 2));
@@ -243,9 +244,11 @@ impl Ball {
pub(super) fn copy_and_align(&self, h: usize) -> Heap {
let diff = self.boundary as i64 - h as i64;
self.stub.iter().cloned().map(|heap_value| {
heap_value - diff
}).collect()
self.stub
.iter()
.cloned()
.map(|heap_value| heap_value - diff)
.collect()
}
}
@@ -418,9 +421,7 @@ impl MachineState {
if self.cwil.count == *limit {
self.cwil.inference_limit_exceeded = true;
return Err(
functor!(atom!("inference_limit_exceeded"), [fixnum(bp)])
);
return Err(functor!(atom!("inference_limit_exceeded"), [fixnum(bp)]));
} else {
self.cwil.count += 1;
}
@@ -430,7 +431,10 @@ impl MachineState {
}
#[allow(dead_code)]
pub(super) fn try_char_list(&mut self, addrs: Vec<HeapCellValue>) -> Result<String, MachineError> {
pub(super) fn try_char_list(
&mut self,
addrs: Vec<HeapCellValue>,
) -> Result<String, MachineError> {
let mut chars = String::new();
for addr in addrs {
@@ -515,18 +519,25 @@ impl MachineState {
mut var_list: Vec<(VarKey, HeapCellValue, usize)>,
singleton_var_list: Vec<HeapCellValue>,
) -> CallResult {
var_list.sort_by(|(_,_,idx_1),(_,_,idx_2)| idx_1.cmp(idx_2));
var_list.sort_by(|(_, _, idx_1), (_, _, idx_2)| idx_1.cmp(idx_2));
let list_of_var_eqs = push_var_eq_functors(
&mut self.heap,
var_list.iter().filter_map(|(var_name, var,_)| if var_name.is_anon() { None } else { Some((var_name,var)) }),
&mut self.atom_tbl,
var_list.iter().filter_map(|(var_name, var, _)| {
if var_name.is_anon() {
None
} else {
Some((var_name, var))
}
}),
&self.atom_tbl,
);
let singleton_addr = self.registers[3];
let singletons_offset = heap_loc_as_cell!(
iter_to_heap_list(&mut self.heap, singleton_var_list.into_iter())
);
let singletons_offset = heap_loc_as_cell!(iter_to_heap_list(
&mut self.heap,
singleton_var_list.into_iter()
));
unify_fn!(*self, singletons_offset, singleton_addr);
@@ -535,9 +546,10 @@ impl MachineState {
}
let vars_addr = self.registers[4];
let vars_offset = heap_loc_as_cell!(
iter_to_heap_list(&mut self.heap, var_list.into_iter().map(|(_,cell,_)| cell))
);
let vars_offset = heap_loc_as_cell!(iter_to_heap_list(
&mut self.heap,
var_list.into_iter().map(|(_, cell, _)| cell)
));
unify_fn!(*self, vars_offset, vars_addr);
@@ -546,9 +558,10 @@ impl MachineState {
}
let var_names_addr = self.registers[5];
let var_names_offset = heap_loc_as_cell!(
iter_to_heap_list(&mut self.heap, list_of_var_eqs.into_iter())
);
let var_names_offset = heap_loc_as_cell!(iter_to_heap_list(
&mut self.heap,
list_of_var_eqs.into_iter()
));
Ok(unify_fn!(*self, var_names_offset, var_names_addr))
}
@@ -589,18 +602,21 @@ impl MachineState {
let singleton_var_list = push_var_eq_functors(
&mut self.heap,
term_write_result.var_dict.iter().filter(|(var_name, binding)| {
if var_name.is_anon() {
return false;
}
term_write_result
.var_dict
.iter()
.filter(|(var_name, binding)| {
if var_name.is_anon() {
return false;
}
if let Some(r) = binding.as_var() {
*singleton_var_set.get(&r).unwrap_or(&false)
} else {
false
}
}),
&mut self.atom_tbl,
if let Some(r) = binding.as_var() {
*singleton_var_set.get(&r).unwrap_or(&false)
} else {
false
}
}),
&self.atom_tbl,
);
for var in term_write_result.var_dict.values_mut() {
@@ -620,13 +636,11 @@ impl MachineState {
self.write_read_term_options(var_list, singleton_var_list)
}
pub fn read_term_from_user_input_eof_handler(&mut self, stream: Stream) -> Result<OnEOF, MachineStub> {
self.eof_action(
self.registers[2],
stream,
atom!("read_term"),
3,
)?;
pub fn read_term_from_user_input_eof_handler(
&mut self,
stream: Stream,
) -> Result<OnEOF, MachineStub> {
self.eof_action(self.registers[2], stream, atom!("read_term"), 3)?;
if stream.options().eof_action() == EOFAction::Reset {
if self.fail == false {
@@ -639,13 +653,15 @@ impl MachineState {
// Safety: the atom_tbl lives for the lifetime of the machine, as does the helper, so the ptr
// will always be valid.
pub fn read_term_from_user_input(&mut self, stream: Stream, indices: &mut IndexStore) -> CallResult {
let atoms_ptr = (&self.atom_tbl.table) as *const indexmap::IndexSet<Atom>;
pub fn read_term_from_user_input(
&mut self,
stream: Stream,
indices: &mut IndexStore,
) -> CallResult {
if let Stream::Readline(ptr) = stream {
unsafe {
let readline = ptr.as_ptr().as_mut().unwrap();
readline.set_atoms_for_completion(atoms_ptr);
readline.set_atoms_for_completion(&self.atom_tbl);
return self.read_term(
stream,
indices,
@@ -671,12 +687,7 @@ impl MachineState {
stream.set_past_end_of_stream(true);
return Ok(OnEOF::Return);
} else if stream.past_end_of_stream() {
self.eof_action(
self.registers[2],
stream,
atom!("read_term"),
3,
)?;
self.eof_action(self.registers[2], stream, atom!("read_term"), 3)?;
if stream.options().eof_action() == EOFAction::Reset {
if self.fail == false {
@@ -717,7 +728,9 @@ impl MachineState {
match &err {
CompilationError::ParserError(e) if e.is_unexpected_eof() => {
match eof_handler(self, stream)? {
OnEOF::Return => return self.write_read_term_options(vec![], vec![]),
OnEOF::Return => {
return self.write_read_term_options(vec![], vec![])
}
OnEOF::Continue => continue,
}
}
@@ -771,14 +784,14 @@ impl MachineState {
}
(HeapCellValueTag::Atom, (name, _arity)) => {
debug_assert_eq!(_arity, 0);
var_names.insert(var, VarPtr::from(name.as_str()));
var_names.insert(var, VarPtr::from(&*name.as_str()));
}
(HeapCellValueTag::Str, s) => {
let (name, arity) = cell_as_atom_cell!(self.heap[s])
.get_name_and_arity();
debug_assert_eq!(arity, 0);
var_names.insert(var, VarPtr::from(name.as_str()));
var_names.insert(var, VarPtr::from(&*name.as_str()));
}
_ => {
unreachable!();
@@ -859,7 +872,7 @@ impl MachineState {
let mut printer = HCPrinter::new(
&mut self.heap,
&mut self.atom_tbl,
Arc::clone(&self.atom_tbl),
&mut self.stack,
op_dir,
PrinterOutputter::new(),
@@ -881,8 +894,10 @@ impl MachineState {
}
}
Ok(Number::Integer(n)) => {
if let Some(n) = n.to_usize() {
printer.max_depth = n;
let result = (&*n).try_into();
if let Ok(value) = result {
printer.max_depth = value;
} else {
self.fail = true;
return Ok(None);
@@ -905,7 +920,11 @@ impl MachineState {
Ok(Some(printer))
}
pub(super) fn read_predicate_key(&self, name: HeapCellValue, arity: HeapCellValue) -> (Atom, usize) {
pub(super) fn read_predicate_key(
&self,
name: HeapCellValue,
arity: HeapCellValue,
) -> (Atom, usize) {
let name = cell_as_atom!(self.store(self.deref(name)));
let arity = cell_as_fixnum!(self.store(self.deref(arity)));

View File

@@ -1,6 +1,5 @@
use crate::arena::*;
use crate::atom_table::*;
use crate::types::*;
use crate::forms::*;
use crate::heap_iter::*;
use crate::machine::attributed_variables::*;
@@ -14,8 +13,10 @@ use crate::machine::stack::*;
use crate::machine::unify::*;
use crate::parser::ast::*;
use crate::parser::dashu::{Integer, Rational};
use crate::types::*;
use indexmap::IndexSet;
use num_order::NumOrd;
use std::cmp::Ordering;
use std::convert::TryFrom;
@@ -50,7 +51,7 @@ impl MachineState {
ball: Ball::new(),
ball_stack: vec![],
lifted_heap: Heap::new(),
interms: vec![Number::default();256],
interms: vec![Number::default(); 256],
cont_pts: Vec::with_capacity(256),
cwil: CWIL::new(),
flags: MachineFlags::default(),
@@ -59,8 +60,8 @@ impl MachineState {
dynamic_mode: FirstOrNext::First,
unify_fn: MachineState::unify,
bind_fn: MachineState::bind,
run_cleaners_fn: |_| { false },
increment_call_count_fn: |_| { Ok(()) },
run_cleaners_fn: |_| false,
increment_call_count_fn: |_| Ok(()),
}
}
@@ -160,9 +161,8 @@ impl MachineState {
key_atom.index as u64,
));
self.trail.push(TrailEntry::from_bytes(
value_cell.into_bytes(),
));
self.trail
.push(TrailEntry::from_bytes(value_cell.into_bytes()));
self.tr += 2;
}
@@ -248,9 +248,7 @@ impl MachineState {
r: Ref,
value: HeapCellValue,
) {
let mut unifier = CompositeUnifierForOccursCheckWithError::from(
DefaultUnifier::from(self),
);
let mut unifier = CompositeUnifierForOccursCheckWithError::from(DefaultUnifier::from(self));
unifier.bind(r, value);
}
@@ -297,12 +295,12 @@ impl MachineState {
pub fn unify_big_int(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
let mut unifier = DefaultUnifier::from(self);
unifier.unify_big_num(n1, value);
unifier.unify_big_integer(n1, value);
}
pub fn unify_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
let mut unifier = DefaultUnifier::from(self);
unifier.unify_big_num(n1, value);
unifier.unify_big_rational(n1, value);
}
pub fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
@@ -316,9 +314,7 @@ impl MachineState {
}
pub(super) fn unify_with_occurs_check_with_error(&mut self) {
let mut unifier = CompositeUnifierForOccursCheckWithError::from(
DefaultUnifier::from(self),
);
let mut unifier = CompositeUnifierForOccursCheckWithError::from(DefaultUnifier::from(self));
unifier.unify_internal();
}
@@ -380,8 +376,7 @@ impl MachineState {
}
)
}
&mut HeapPtr::PStrChar(h, ref mut n) |
&mut HeapPtr::PStrLocation(h, ref mut n) => {
&mut HeapPtr::PStrChar(h, ref mut n) | &mut HeapPtr::PStrLocation(h, ref mut n) => {
read_heap_cell!(self.heap[h],
(HeapCellValueTag::PStr, pstr_atom) => {
let pstr = PartialString::from(pstr_atom);
@@ -509,7 +504,7 @@ impl MachineState {
} else {
self.pdl.clear();
return Some(
n1.chars().next().cmp(&Some(c2))
n1.as_str().chars().next().cmp(&Some(c2))
.then(Ordering::Greater)
);
}
@@ -539,7 +534,7 @@ impl MachineState {
} else {
self.pdl.clear();
return Some(
Some(c1).cmp(&n2.chars().next())
Some(c1).cmp(&n2.as_str().chars().next())
.then(Ordering::Less)
);
}
@@ -562,7 +557,7 @@ impl MachineState {
} else {
self.pdl.clear();
return Some(
Some(c1).cmp(&n2.chars().next())
Some(c1).cmp(&n2.as_str().chars().next())
.then(Ordering::Less)
);
}
@@ -592,7 +587,7 @@ impl MachineState {
} else {
self.pdl.clear();
return Some(
n1.chars().next().cmp(&Some(c2))
n1.as_str().chars().next().cmp(&Some(c2))
.then(Ordering::Greater)
);
}
@@ -639,7 +634,7 @@ impl MachineState {
// iter2 is continuable, so it
// has a tail in the heap at
// focus+1.
pdl.push(iter2.heap[focus+1]);
pdl.push(iter2.heap[focus + 1]);
return None;
}
@@ -902,8 +897,12 @@ impl MachineState {
let s = string.as_str();
match heap_pstr_iter.compare_pstr_to_string(s) {
Some(PStrPrefixCmpResult { focus, offset, prefix_len }) if prefix_len == s.len() => {
match heap_pstr_iter.compare_pstr_to_string(&*s) {
Some(PStrPrefixCmpResult {
focus,
offset,
prefix_len,
}) if prefix_len == s.len() => {
let focus_addr = self.heap[focus];
read_heap_cell!(focus_addr,
@@ -950,7 +949,10 @@ impl MachineState {
return;
}
Some(PStrPrefixCmpResult { prefix_len: inner_prefix_len, .. }) => {
Some(PStrPrefixCmpResult {
prefix_len: inner_prefix_len,
..
}) => {
prefix_len = inner_prefix_len;
}
None => {
@@ -1002,9 +1004,9 @@ impl MachineState {
self.s_offset = 0;
self.mode = MachineMode::Read;
put_partial_string(&mut self.heap, pstr, &mut self.atom_tbl)
put_partial_string(&mut self.heap, pstr, &self.atom_tbl)
} else {
put_complete_string(&mut self.heap, pstr, &mut self.atom_tbl)
put_complete_string(&mut self.heap, pstr, &self.atom_tbl)
}
}
@@ -1096,7 +1098,7 @@ impl MachineState {
(name, 0, 0)
}
(HeapCellValueTag::Char, c) => {
(self.atom_tbl.build_with(&c.to_string()), 0, 0)
(AtomTable::build_with(&self.atom_tbl, &c.to_string()), 0, 0)
}
(HeapCellValueTag::Var | HeapCellValueTag::AttrVar | HeapCellValueTag::StackVar) => {
let stub = functor_stub(atom!("call"), arity + 1);
@@ -1181,7 +1183,10 @@ impl MachineState {
let n = match n {
Number::Fixnum(n) => n.get_num() as usize,
Number::Integer(n) if *n >= 0 && *n <= std::usize::MAX => n.to_usize().unwrap(),
Number::Integer(n) if (*n).num_ge(&0) && (*n).num_le(&std::usize::MAX) => {
let value: usize = (&*n).try_into().unwrap();
value
},
_ => {
self.fail = true;
return Ok(());
@@ -1324,7 +1329,7 @@ impl MachineState {
let f_a = if name == atom!(".") && arity == 2 {
self.heap.push(heap_loc_as_cell!(h));
self.heap.push(heap_loc_as_cell!(h+1));
self.heap.push(heap_loc_as_cell!(h + 1));
list_loc_as_cell!(h)
} else {
@@ -1398,9 +1403,15 @@ impl MachineState {
let err = self.domain_error(DomainErrorType::NotLessThanZero, n);
return Err(self.error_form(err, stub_gen()));
}
Ok(Number::Rational(n)) => n.numerator().to_i64().unwrap(),
Ok(Number::Rational(n)) => {
let value: i64 = n.numerator().try_into().unwrap();
value
},
Ok(Number::Fixnum(n)) => n.get_num(),
Ok(Number::Integer(n)) => n.to_i64().unwrap(),
Ok(Number::Integer(n)) => {
let value: i64 = (&*n).try_into().unwrap();
value
},
Err(_) => {
return type_error(arity);
}
@@ -1435,7 +1446,7 @@ impl MachineState {
}
}
(HeapCellValueTag::Char, c) => {
let c = self.atom_tbl.build_with(&c.to_string());
let c = AtomTable::build_with(&self.atom_tbl, &c.to_string());
self.try_functor_fabricate_struct(
c,
@@ -1571,8 +1582,7 @@ impl MachineState {
while let Some(iteratee) = heap_pstr_iter.next() {
match iteratee {
PStrIteratee::Char(_, c) =>
chars.push(char_as_cell!(c)),
PStrIteratee::Char(_, c) => chars.push(char_as_cell!(c)),
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
let pstr = PartialString::from(pstr_atom);
chars.extend(pstr.as_str_from(n).chars().map(|c| char_as_cell!(c)));
@@ -1634,10 +1644,7 @@ impl MachineState {
let mut value = unmark_cell_bits!(value);
if value.is_var() {
value = heap_bound_store(
iter.heap,
heap_bound_deref(iter.heap, value),
);
value = heap_bound_store(iter.heap, heap_bound_deref(iter.heap, value));
if value.is_var() {
return true;
@@ -1646,7 +1653,7 @@ impl MachineState {
if value.is_compound(iter.heap) {
if visited.contains(&value) {
for _ in stack_len .. iter.stack_len() {
for _ in stack_len..iter.stack_len() {
iter.pop_stack();
}
} else {
@@ -1681,9 +1688,9 @@ impl MachineState {
Err(_) => {}
},
Ok(Number::Integer(n)) => {
if let Some(b) = n.to_u8() {
bytes.push(b);
}
let b: u8 = (&*n).try_into().unwrap();
bytes.push(b);
}
_ => {}
}

View File

@@ -2,15 +2,17 @@ pub use crate::arena::*;
pub use crate::atom_table::*;
use crate::heap_print::*;
pub use crate::machine::heap::*;
pub use crate::machine::*;
pub use crate::machine::machine_state::*;
pub use crate::machine::stack::*;
pub use crate::machine::streams::*;
pub use crate::machine::*;
pub use crate::macros::*;
pub use crate::parser::ast::*;
use crate::read::*;
pub use crate::types::*;
use std::sync::Arc;
#[cfg(test)]
use crate::machine::copier::CopierTarget;
@@ -61,7 +63,7 @@ impl MockWAM {
let mut printer = HCPrinter::new(
&mut self.machine_st.heap,
&mut self.machine_st.atom_tbl,
Arc::clone(&self.machine_st.atom_tbl),
&mut self.machine_st.stack,
&self.op_dir,
PrinterOutputter::new(),
@@ -71,11 +73,9 @@ impl MockWAM {
printer.var_names = term_write_result
.var_dict
.into_iter()
.map(|(var, cell)| {
match var {
VarKey::VarPtr(var) => (cell, var.clone()),
VarKey::AnonVar(_) => (cell, VarPtr::from(var.to_string()))
}
.map(|(var, cell)| match var {
VarKey::VarPtr(var) => (cell, var.clone()),
VarKey::AnonVar(_) => (cell, VarPtr::from(var.to_string())),
})
.collect();
@@ -234,6 +234,17 @@ impl Machine {
self.load_file(file.into(), stream);
self.user_output.bytes().map(|b| b.unwrap()).collect()
}
pub fn test_load_string(&mut self, code: &str) -> Vec<u8> {
let stream = Stream::from_owned_string(
code.to_owned(),
&mut self.machine_st.arena,
);
self.load_file("<stdin>".into(), stream);
self.user_output.bytes().map(|b| b.unwrap()).collect()
}
}
#[cfg(test)]
@@ -245,26 +256,11 @@ mod tests {
let mut wam = MachineState::new();
let mut op_dir = default_op_dir();
op_dir.insert(
(atom!("+"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("-"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("*"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("/"), Fixity::In),
OpDesc::build_with(400, YFX as u8),
);
op_dir.insert(
(atom!("="), Fixity::In),
OpDesc::build_with(700, XFX as u8),
);
op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8));
op_dir.insert((atom!("="), Fixity::In), OpDesc::build_with(700, XFX as u8));
{
parse_and_write_parsed_term_to_heap(&mut wam, "f(X,X).", &op_dir).unwrap();
@@ -481,22 +477,10 @@ mod tests {
let mut wam = MachineState::new();
let mut op_dir = default_op_dir();
op_dir.insert(
(atom!("+"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("-"), Fixity::In),
OpDesc::build_with(500, YFX as u8),
);
op_dir.insert(
(atom!("*"), Fixity::In),
OpDesc::build_with(400, YFX as u8),
);
op_dir.insert(
(atom!("/"), Fixity::In),
OpDesc::build_with(400, YFX as u8),
);
op_dir.insert((atom!("+"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("-"), Fixity::In), OpDesc::build_with(500, YFX as u8));
op_dir.insert((atom!("*"), Fixity::In), OpDesc::build_with(400, YFX as u8));
op_dir.insert((atom!("/"), Fixity::In), OpDesc::build_with(400, YFX as u8));
{
parse_and_write_parsed_term_to_heap(&mut wam, "f(X,X).", &op_dir).unwrap();
@@ -587,20 +571,12 @@ mod tests {
wam.heap.push(heap_loc_as_cell!(1));
assert_eq!(
compare_term_test!(
wam,
heap_loc_as_cell!(0),
heap_loc_as_cell!(0)
),
compare_term_test!(wam, heap_loc_as_cell!(0), heap_loc_as_cell!(0)),
Some(Ordering::Equal)
);
assert_eq!(
compare_term_test!(
wam,
heap_loc_as_cell!(0),
atom_as_cell!(atom!("a"))
),
compare_term_test!(wam, heap_loc_as_cell!(0), atom_as_cell!(atom!("a"))),
Some(Ordering::Greater)
);
@@ -623,29 +599,17 @@ mod tests {
wam.heap.push(empty_list_as_cell!());
assert_eq!(
compare_term_test!(
wam,
heap_loc_as_cell!(7),
heap_loc_as_cell!(7)
),
compare_term_test!(wam, heap_loc_as_cell!(7), heap_loc_as_cell!(7)),
Some(Ordering::Equal)
);
assert_eq!(
compare_term_test!(
wam,
heap_loc_as_cell!(0),
heap_loc_as_cell!(7)
),
compare_term_test!(wam, heap_loc_as_cell!(0), heap_loc_as_cell!(7)),
Some(Ordering::Greater)
);
assert_eq!(
compare_term_test!(
wam,
empty_list_as_cell!(),
heap_loc_as_cell!(7)
),
compare_term_test!(wam, empty_list_as_cell!(), heap_loc_as_cell!(7)),
Some(Ordering::Less)
);
@@ -668,40 +632,24 @@ mod tests {
);
assert_eq!(
compare_term_test!(
wam,
empty_list_as_cell!(),
atom_as_cell!(atom!("atom"))
),
compare_term_test!(wam, empty_list_as_cell!(), atom_as_cell!(atom!("atom"))),
Some(Ordering::Less)
);
assert_eq!(
compare_term_test!(
wam,
atom_as_cell!(atom!("atom")),
empty_list_as_cell!()
),
compare_term_test!(wam, atom_as_cell!(atom!("atom")), empty_list_as_cell!()),
Some(Ordering::Greater)
);
let one_p_one = HeapCellValue::from(float_alloc!(1.1, &mut wam.arena));
assert_eq!(
compare_term_test!(
wam,
one_p_one,
fixnum_as_cell!(Fixnum::build_with(1))
),
compare_term_test!(wam, one_p_one, fixnum_as_cell!(Fixnum::build_with(1))),
Some(Ordering::Less)
);
assert_eq!(
compare_term_test!(
wam,
fixnum_as_cell!(Fixnum::build_with(1)),
one_p_one
),
compare_term_test!(wam, fixnum_as_cell!(Fixnum::build_with(1)), one_p_one),
Some(Ordering::Greater)
);
}
@@ -720,7 +668,8 @@ mod tests {
all_cells_unmarked(&wam.heap);
wam.heap.clear();
wam.heap.extend(functor!(atom!("f"), [atom(atom!("a")), atom(atom!("b"))]));
wam.heap
.extend(functor!(atom!("f"), [atom(atom!("a")), atom(atom!("b"))]));
assert!(!wam.is_cyclic_term(str_loc_as_cell!(0)));

View File

@@ -7,6 +7,7 @@ pub mod loader;
pub mod compile;
pub mod config;
pub mod copier;
pub mod disjuncts;
pub mod dispatch;
pub mod gc;
pub mod heap;
@@ -19,7 +20,6 @@ pub mod machine_state_impl;
pub mod mock_wam;
pub mod parsed_results;
pub mod partial_string;
pub mod disjuncts;
pub mod preprocessor;
pub mod stack;
pub mod streams;
@@ -30,9 +30,9 @@ pub mod unify;
use crate::arena::*;
use crate::arithmetic::*;
use crate::atom_table::*;
use crate::forms::*;
#[cfg(feature = "ffi")]
use crate::ffi::ForeignFunctionTable;
use crate::forms::*;
use crate::instructions::*;
use crate::machine::args::*;
use crate::machine::compile::*;
@@ -168,7 +168,10 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) {
for key in keys {
let idx = code_dir.get(&key).unwrap();
builtins.code_dir.insert(key, idx.clone());
builtins.module_decl.exports.push(ModuleExport::PredicateKey(key));
builtins
.module_decl
.exports
.push(ModuleExport::PredicateKey(key));
}
}
@@ -199,7 +202,7 @@ impl Machine {
code: &mut self.code,
load_contexts: &mut self.load_contexts,
},
&mut self.machine_st
&mut self.machine_st,
)
}
@@ -211,7 +214,11 @@ impl Machine {
self.machine_st.throw_exception(err);
}
fn run_module_predicate(&mut self, module_name: Atom, key: PredicateKey) -> std::process::ExitCode {
fn run_module_predicate(
&mut self,
module_name: Atom,
key: PredicateKey,
) -> std::process::ExitCode {
if let Some(module) = self.indices.modules.get(&module_name) {
if let Some(ref code_index) = module.code_dir.get(&key) {
let p = code_index.local().unwrap();
@@ -228,7 +235,8 @@ impl Machine {
pub fn load_file(&mut self, path: &str, stream: Stream) {
self.machine_st.registers[1] = stream_as_cell!(stream);
self.machine_st.registers[2] = atom_as_cell!(self.machine_st.atom_tbl.build_with(path));
self.machine_st.registers[2] =
atom_as_cell!(AtomTable::build_with(&self.machine_st.atom_tbl, path));
self.run_module_predicate(atom!("loader"), (atom!("file_load"), 2));
}
@@ -239,7 +247,9 @@ impl Machine {
path_buf.push("src/toplevel.pl");
let path = path_buf.to_str().unwrap();
let toplevel_stream = Stream::from_static_string(program, &mut self.machine_st.arena);
let toplevel_stream =
Stream::from_static_string(program, &mut self.machine_st.arena);
self.load_file(path, toplevel_stream);
@@ -292,7 +302,7 @@ impl Machine {
arg_pstrs.push(put_complete_string(
&mut self.machine_st.heap,
&arg,
&mut self.machine_st.atom_tbl,
&self.machine_st.atom_tbl,
));
}
@@ -314,7 +324,11 @@ impl Machine {
}
pub(crate) fn configure_modules(&mut self) {
fn update_call_n_indices(loader: &Module, target_code_dir: &mut CodeDir, arena: &mut Arena) {
fn update_call_n_indices(
loader: &Module,
target_code_dir: &mut CodeDir,
arena: &mut Arena,
) {
for arity in 1..66 {
let key = (atom!("call"), arity);
@@ -359,10 +373,18 @@ impl Machine {
}
for (_, target_module) in self.indices.modules.iter_mut() {
update_call_n_indices(&loader, &mut target_module.code_dir, &mut self.machine_st.arena);
update_call_n_indices(
&loader,
&mut target_module.code_dir,
&mut self.machine_st.arena,
);
}
update_call_n_indices(&loader, &mut self.indices.code_dir, &mut self.machine_st.arena);
update_call_n_indices(
&loader,
&mut self.indices.code_dir,
&mut self.machine_st.arena,
);
self.indices.modules.insert(atom!("loader"), loader);
} else {
@@ -373,56 +395,65 @@ impl Machine {
pub(crate) fn add_impls_to_indices(&mut self) {
let impls_offset = self.code.len() + 3;
self.code.extend(vec![
Instruction::BreakFromDispatchLoop,
Instruction::InstallVerifyAttr,
Instruction::VerifyAttrInterrupt,
Instruction::ExecuteTermGreaterThan,
Instruction::ExecuteTermLessThan,
Instruction::ExecuteTermGreaterThanOrEqual,
Instruction::ExecuteTermLessThanOrEqual,
Instruction::ExecuteTermEqual,
Instruction::ExecuteTermNotEqual,
Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2))),
Instruction::ExecuteAcyclicTerm,
Instruction::ExecuteArg,
Instruction::ExecuteCompare,
Instruction::ExecuteCopyTerm,
Instruction::ExecuteFunctor,
Instruction::ExecuteGround,
Instruction::ExecuteKeySort,
Instruction::ExecuteSort,
Instruction::ExecuteN(1),
Instruction::ExecuteN(2),
Instruction::ExecuteN(3),
Instruction::ExecuteN(4),
Instruction::ExecuteN(5),
Instruction::ExecuteN(6),
Instruction::ExecuteN(7),
Instruction::ExecuteN(8),
Instruction::ExecuteN(9),
Instruction::ExecuteIsAtom(temp_v!(1)),
Instruction::ExecuteIsAtomic(temp_v!(1)),
Instruction::ExecuteIsCompound(temp_v!(1)),
Instruction::ExecuteIsInteger(temp_v!(1)),
Instruction::ExecuteIsNumber(temp_v!(1)),
Instruction::ExecuteIsRational(temp_v!(1)),
Instruction::ExecuteIsFloat(temp_v!(1)),
Instruction::ExecuteIsNonVar(temp_v!(1)),
Instruction::ExecuteIsVar(temp_v!(1))
].into_iter());
self.code.extend(
vec![
Instruction::BreakFromDispatchLoop,
Instruction::InstallVerifyAttr,
Instruction::VerifyAttrInterrupt,
Instruction::ExecuteTermGreaterThan,
Instruction::ExecuteTermLessThan,
Instruction::ExecuteTermGreaterThanOrEqual,
Instruction::ExecuteTermLessThanOrEqual,
Instruction::ExecuteTermEqual,
Instruction::ExecuteTermNotEqual,
Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberGreaterThanOrEqual(
ar_reg!(temp_v!(1)),
ar_reg!(temp_v!(2)),
),
Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2))),
Instruction::ExecuteAcyclicTerm,
Instruction::ExecuteArg,
Instruction::ExecuteCompare,
Instruction::ExecuteCopyTerm,
Instruction::ExecuteFunctor,
Instruction::ExecuteGround,
Instruction::ExecuteKeySort,
Instruction::ExecuteSort,
Instruction::ExecuteN(1),
Instruction::ExecuteN(2),
Instruction::ExecuteN(3),
Instruction::ExecuteN(4),
Instruction::ExecuteN(5),
Instruction::ExecuteN(6),
Instruction::ExecuteN(7),
Instruction::ExecuteN(8),
Instruction::ExecuteN(9),
Instruction::ExecuteIsAtom(temp_v!(1)),
Instruction::ExecuteIsAtomic(temp_v!(1)),
Instruction::ExecuteIsCompound(temp_v!(1)),
Instruction::ExecuteIsInteger(temp_v!(1)),
Instruction::ExecuteIsNumber(temp_v!(1)),
Instruction::ExecuteIsRational(temp_v!(1)),
Instruction::ExecuteIsFloat(temp_v!(1)),
Instruction::ExecuteIsNonVar(temp_v!(1)),
Instruction::ExecuteIsVar(temp_v!(1)),
]
.into_iter(),
);
for (p, instr) in self.code[impls_offset ..].iter().enumerate() {
for (p, instr) in self.code[impls_offset..].iter().enumerate() {
let key = instr.to_name_and_arity();
self.indices.code_dir.insert(
key,
CodeIndex::new(IndexPtr::index(p + impls_offset), &mut self.machine_st.arena),
CodeIndex::new(
IndexPtr::index(p + impls_offset),
&mut self.machine_st.arena,
),
);
}
}
@@ -455,7 +486,7 @@ impl Machine {
user_error,
load_contexts: vec![],
#[cfg(feature = "ffi")]
foreign_function_table: Default::default(),
foreign_function_table: Default::default(),
};
let mut lib_path = current_dir();
@@ -479,10 +510,7 @@ impl Machine {
.unwrap();
bootstrapping_compile(
Stream::from_static_string(
LIBRARIES.borrow()["builtins"],
&mut wam.machine_st.arena,
),
Stream::from_static_string(LIBRARIES.borrow()["builtins"], &mut wam.machine_st.arena),
&mut wam,
ListingSource::from_file_and_path(atom!("builtins.pl"), lib_path.clone()),
)
@@ -535,7 +563,9 @@ impl Machine {
}
pub(crate) fn configure_streams(&mut self) {
self.user_input.options_mut().set_alias_to_atom_opt(Some(atom!("user_input")));
self.user_input
.options_mut()
.set_alias_to_atom_opt(Some(atom!("user_input")));
self.indices
.stream_aliases
@@ -543,7 +573,9 @@ impl Machine {
self.indices.streams.insert(self.user_input);
self.user_output.options_mut().set_alias_to_atom_opt(Some(atom!("user_output")));
self.user_output
.options_mut()
.set_alias_to_atom_opt(Some(atom!("user_output")));
self.indices
.stream_aliases
@@ -573,9 +605,16 @@ impl Machine {
loop {
let indexing_code_ptr = match &indexing_lines[oip] {
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(arg, v, c, l, s)) => {
&IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
arg,
v,
c,
l,
s,
)) => {
cell = self.deref_register(arg);
self.machine_st.select_switch_on_term_index(cell, v, c, l, s)
self.machine_st
.select_switch_on_term_index(cell, v, c, l, s)
}
IndexingLine::Indexing(IndexingInstruction::SwitchOnConstant(hm)) => {
let lit = self.machine_st.constant_to_literal(cell);
@@ -685,7 +724,12 @@ impl Machine {
}
);
}
&Instruction::GetPartialString(Level::Shallow, string, RegType::Temp(t), has_tail) => {
&Instruction::GetPartialString(
Level::Shallow,
string,
RegType::Temp(t),
has_tail,
) => {
let cell = self.deref_register(t);
read_heap_cell!(cell,
@@ -716,17 +760,17 @@ impl Machine {
}
);
}
Instruction::GetConstant(..) |
Instruction::GetList(..) |
Instruction::GetStructure(..) |
Instruction::GetPartialString(..) |
&Instruction::UnifyVoid(..) |
&Instruction::UnifyConstant(..) |
&Instruction::GetVariable(..) |
&Instruction::GetValue(..) |
&Instruction::UnifyVariable(..) |
&Instruction::UnifyValue(..) |
&Instruction::UnifyLocalValue(..) => {
Instruction::GetConstant(..)
| Instruction::GetList(..)
| Instruction::GetStructure(..)
| Instruction::GetPartialString(..)
| &Instruction::UnifyVoid(..)
| &Instruction::UnifyConstant(..)
| &Instruction::GetVariable(..)
| &Instruction::GetValue(..)
| &Instruction::UnifyVariable(..)
| &Instruction::UnifyValue(..)
| &Instruction::UnifyLocalValue(..) => {
offset += 1;
}
_ => {
@@ -741,9 +785,10 @@ impl Machine {
fn next_applicable_clause(&mut self, mut offset: usize) -> Option<usize> {
while !self.next_clause_applicable(self.machine_st.p + offset + 1) {
match &self.code[self.machine_st.p + offset] {
&Instruction::DefaultRetryMeElse(o) | &Instruction::RetryMeElse(o) |
&Instruction::DynamicElse(.., NextOrFail::Next(o)) |
&Instruction::DynamicInternalElse(.., NextOrFail::Next(o)) => offset += o,
&Instruction::DefaultRetryMeElse(o)
| &Instruction::RetryMeElse(o)
| &Instruction::DynamicElse(.., NextOrFail::Next(o))
| &Instruction::DynamicInternalElse(.., NextOrFail::Next(o)) => offset += o,
_ => {
return None;
}
@@ -762,14 +807,16 @@ impl Machine {
match &indexing_lines[self.machine_st.oip as usize] {
IndexingLine::IndexedChoice(indexed_choice) => {
match &indexed_choice[(self.machine_st.iip + inner_offset) as usize] {
&IndexedChoiceInstruction::Retry(o) => {
&IndexedChoiceInstruction::Retry(o)
| &IndexedChoiceInstruction::DefaultRetry(o) => {
if self.next_clause_applicable(self.machine_st.p + o) {
return Some(inner_offset);
}
inner_offset += 1;
}
&IndexedChoiceInstruction::Trust(o) => {
&IndexedChoiceInstruction::Trust(o)
| &IndexedChoiceInstruction::DefaultTrust(o) => {
return if self.next_clause_applicable(self.machine_st.p + o) {
Some(inner_offset)
} else {
@@ -822,12 +869,13 @@ impl Machine {
or_frame.prelude.tr = self.machine_st.tr;
or_frame.prelude.h = self.machine_st.heap.len();
or_frame.prelude.b0 = self.machine_st.b0;
or_frame.prelude.attr_var_queue_len = self.machine_st.attr_var_init.attr_var_queue.len();
or_frame.prelude.attr_var_queue_len =
self.machine_st.attr_var_init.attr_var_queue.len();
self.machine_st.b = b;
for i in 0..n {
or_frame[i] = self.machine_st.registers[i+1];
or_frame[i] = self.machine_st.registers[i + 1];
}
self.machine_st.hb = self.machine_st.heap.len();
@@ -853,12 +901,13 @@ impl Machine {
or_frame.prelude.tr = self.machine_st.tr;
or_frame.prelude.h = self.machine_st.heap.len();
or_frame.prelude.b0 = self.machine_st.b0;
or_frame.prelude.attr_var_queue_len = self.machine_st.attr_var_init.attr_var_queue.len();
or_frame.prelude.attr_var_queue_len =
self.machine_st.attr_var_init.attr_var_queue.len();
self.machine_st.b = b;
for i in 0..n {
or_frame[i] = self.machine_st.registers[i+1];
or_frame[i] = self.machine_st.registers[i + 1];
}
self.machine_st.hb = self.machine_st.heap.len();
@@ -921,7 +970,7 @@ impl Machine {
let curr_tr = self.machine_st.tr;
for i in 0..n {
self.machine_st.registers[i+1] = or_frame[i];
self.machine_st.registers[i + 1] = or_frame[i];
}
self.unwind_trail(old_tr, curr_tr);
@@ -965,7 +1014,7 @@ impl Machine {
let curr_tr = self.machine_st.tr;
for i in 0..n {
self.machine_st.registers[i+1] = or_frame[i];
self.machine_st.registers[i + 1] = or_frame[i];
}
self.unwind_trail(old_tr, curr_tr);
@@ -1008,7 +1057,7 @@ impl Machine {
let n = or_frame.prelude.num_cells;
for i in 0..n {
self.machine_st.registers[i+1] = or_frame[i];
self.machine_st.registers[i + 1] = or_frame[i];
}
let old_tr = or_frame.prelude.tr;
@@ -1047,15 +1096,17 @@ impl Machine {
#[inline(always)]
fn undefined_procedure(&mut self, name: Atom, arity: usize) -> CallResult {
match self.machine_st.flags.unknown {
Unknown::Error => {
Err(self.machine_st.throw_undefined_error(name, arity))
}
Unknown::Error => Err(self.machine_st.throw_undefined_error(name, arity)),
Unknown::Fail => {
self.machine_st.fail = true;
Ok(())
}
Unknown::Warn => {
println!("warning: predicate {}/{} is undefined", name.as_str(), arity);
println!(
"warning: predicate {}/{} is undefined",
name.as_str(),
arity
);
self.machine_st.fail = true;
Ok(())
}
@@ -1100,9 +1151,7 @@ impl Machine {
self.machine_st.dynamic_mode = FirstOrNext::First;
self.machine_st.execute_at_index(arity, compiled_tl_index);
}
IndexPtrTag::Index => {
self.machine_st.execute_at_index(arity, compiled_tl_index)
}
IndexPtrTag::Index => self.machine_st.execute_at_index(arity, compiled_tl_index),
}
Ok(())
@@ -1127,7 +1176,9 @@ impl Machine {
}
} else {
let stub = functor_stub(name, arity);
let err = self.machine_st.module_resolution_error(module_name, name, arity);
let err = self
.machine_st
.module_resolution_error(module_name, name, arity);
Err(self.machine_st.error_form(err, stub))
}
@@ -1153,7 +1204,9 @@ impl Machine {
}
} else {
let stub = functor_stub(name, arity);
let err = self.machine_st.module_resolution_error(module_name, name, arity);
let err = self
.machine_st
.module_resolution_error(module_name, name, arity);
Err(self.machine_st.error_form(err, stub))
}
@@ -1187,12 +1240,16 @@ impl Machine {
let r_c_wo_h_atom = atom!("run_cleaners_without_handling");
let iso_ext = atom!("iso_ext");
RCWH = self.indices.get_predicate_code_index(r_c_w_h_atom, 0, iso_ext)
.and_then(|item| item.local())
.unwrap();
RCWOH = self.indices.get_predicate_code_index(r_c_wo_h_atom, 1, iso_ext)
.and_then(|item| item.local())
.unwrap();
RCWH = self
.indices
.get_predicate_code_index(r_c_w_h_atom, 0, iso_ext)
.and_then(|item| item.local())
.unwrap();
RCWOH = self
.indices
.get_predicate_code_index(r_c_wo_h_atom, 1, iso_ext)
.and_then(|item| item.local())
.unwrap();
});
(RCWH, RCWOH)
@@ -1203,9 +1260,8 @@ impl Machine {
let (idx, arity) = if self.machine_st.effective_block() > prev_block {
(r_c_w_h, 0)
} else {
self.machine_st.registers[1] = fixnum_as_cell!(
Fixnum::build_with(b_cutoff as i64)
);
self.machine_st.registers[1] =
fixnum_as_cell!(Fixnum::build_with(b_cutoff as i64));
(r_c_wo_h, 1)
};
@@ -1272,9 +1328,8 @@ impl Machine {
None => unreachable!(),
}
}
TrailEntryTag::TrailedAttachedValue => {
}
TrailEntryTag::TrailedAttachedValue => {}
}
}
}
}
}

View File

@@ -43,11 +43,10 @@ impl Into<Atom> for PartialString {
impl PartialString {
#[inline]
pub(super) fn new<'a>(src: &'a str, atom_tbl: &mut AtomTable) -> Option<(Self, &'a str)> {
pub(super) fn new<'a>(src: &'a str, atom_tbl: &AtomTable) -> Option<(Self, &'a str)> {
let terminator_idx = scan_for_terminator(src.chars());
let pstr = PartialString(atom_tbl.build_with(&src[.. terminator_idx]));
Some(if terminator_idx < src.as_bytes().len() {
let pstr = PartialString(AtomTable::build_with(&atom_tbl, &src[..terminator_idx]));
Some(if terminator_idx < src.as_bytes().len() {
(pstr, &src[terminator_idx + 1..])
} else {
(pstr, "")
@@ -55,8 +54,8 @@ impl PartialString {
}
#[inline(always)]
pub(crate) fn as_str_from(&self, n: usize) -> &str {
&self.0.as_str()[n..]
pub(crate) fn as_str_from(&self, n: usize) -> AtomString {
self.0.as_str().map(|str| &str[n..])
}
}
@@ -124,11 +123,15 @@ impl<'a> HeapPStrIter<'a> {
let mut final_result = None;
while let Some(PStrIterStep { iteratee, next_hare }) = self.step(self.brent_st.hare) {
while let Some(PStrIterStep {
iteratee,
next_hare,
}) = self.step(self.brent_st.hare)
{
self.brent_st.hare = next_hare;
self.focus = self.heap[iteratee.focus()];
result.focus = iteratee.focus();
result.focus = iteratee.focus();
result.offset = iteratee.offset();
match iteratee {
@@ -151,7 +154,7 @@ impl<'a> HeapPStrIter<'a> {
let s = &s[result.prefix_len..];
if s.len() >= t.len() {
if s.starts_with(t) {
if (&*s).starts_with(&*t) {
result.prefix_len += t.len();
result.offset += t.len();
} else {
@@ -202,7 +205,7 @@ impl<'a> HeapPStrIter<'a> {
self.brent_st.hare = self.orig_focus;
self.brent_st.tortoise = self.orig_focus;
for _ in 0 .. self.brent_st.lam {
for _ in 0..self.brent_st.lam {
self.brent_st.hare = self.step(self.brent_st.hare).unwrap().next_hare;
}
@@ -225,7 +228,7 @@ impl<'a> HeapPStrIter<'a> {
}
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
let pstr = PartialString::from(pstr_atom);
buf += pstr.as_str_from(n);
buf += &*pstr.as_str_from(n);
}
}
}
@@ -238,43 +241,43 @@ impl<'a> HeapPStrIter<'a> {
let mut focus = self.focus;
loop {
read_heap_cell!(focus,
(HeapCellValueTag::CStr | HeapCellValueTag::PStrLoc) => {
return true;
}
(HeapCellValueTag::Atom, (name, arity)) => { // TODO: use Str here?
return name == atom!(".") && arity == 2;
}
(HeapCellValueTag::Lis, h) => {
let value = self.heap[h];
let value = heap_bound_store(
self.heap,
heap_bound_deref(self.heap, value),
);
read_heap_cell!(focus,
(HeapCellValueTag::CStr | HeapCellValueTag::PStrLoc) => {
return true;
}
(HeapCellValueTag::Atom, (name, arity)) => { // TODO: use Str here?
return name == atom!(".") && arity == 2;
}
(HeapCellValueTag::Lis, h) => {
let value = self.heap[h];
let value = heap_bound_store(
self.heap,
heap_bound_deref(self.heap, value),
);
return read_heap_cell!(value,
(HeapCellValueTag::Atom, (name, arity)) => {
arity == 0 && name.as_char().is_some()
}
(HeapCellValueTag::Char) => {
true
}
_ => {
false
}
);
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
if focus == self.heap[h] {
return false;
}
return read_heap_cell!(value,
(HeapCellValueTag::Atom, (name, arity)) => {
arity == 0 && name.as_char().is_some()
}
(HeapCellValueTag::Char) => {
true
}
_ => {
false
}
);
}
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
if focus == self.heap[h] {
return false;
}
focus = self.heap[h];
}
_ => {
return false;
}
);
focus = self.heap[h];
}
_ => {
return false;
}
);
}
}
@@ -381,13 +384,15 @@ impl<'a> HeapPStrIter<'a> {
}
fn pre_cycle_discovery_stepper(&mut self) -> Option<PStrIteratee> {
let PStrIterStep { iteratee, next_hare } =
match self.step(self.brent_st.hare) {
Some(results) => results,
None => {
return None;
}
};
let PStrIterStep {
iteratee,
next_hare,
} = match self.step(self.brent_st.hare) {
Some(results) => results,
None => {
return None;
}
};
self.focus = self.heap[iteratee.focus()];
@@ -421,13 +426,15 @@ impl<'a> HeapPStrIter<'a> {
return None;
}
let PStrIterStep { iteratee, next_hare } =
match self.step(self.brent_st.hare) {
Some(results) => results,
None => {
return None;
}
};
let PStrIterStep {
iteratee,
next_hare,
} = match self.step(self.brent_st.hare) {
Some(results) => results,
None => {
return None;
}
};
self.focus = self.heap[next_hare];
self.brent_st.hare = next_hare;
@@ -515,11 +522,8 @@ impl<'a> Iterator for PStrCharsIter<'a> {
match pstr.as_str_from(n).chars().next() {
Some(c) => {
self.item = Some(PStrIteratee::PStrSegment(
f1,
pstr_atom,
n + c.len_utf8(),
));
self.item =
Some(PStrIteratee::PStrSegment(f1, pstr_atom, n + c.len_utf8()));
return Some(c);
}
@@ -684,8 +688,10 @@ pub fn compare_pstr_prefixes<'a>(
}
}
}
(PStrIteratee::PStrSegment(f1, pstr1_atom, n1),
PStrIteratee::PStrSegment(f2, pstr2_atom, n2)) => {
(
PStrIteratee::PStrSegment(f1, pstr1_atom, n1),
PStrIteratee::PStrSegment(f2, pstr2_atom, n2),
) => {
if pstr1_atom == pstr2_atom && n1 == n2 {
cycle_detection_step(i1, i2, &step_1);
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
@@ -707,7 +713,7 @@ pub fn compare_pstr_prefixes<'a>(
let str2 = pstr2.as_str_from(n2);
match str1.len().cmp(&str2.len()) {
Ordering::Equal if str1 == str2 => {
Ordering::Equal if &*str1 == &*str2 => {
cycle_detection_step(i1, i2, &step_1);
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
@@ -718,8 +724,9 @@ pub fn compare_pstr_prefixes<'a>(
continue;
}
}
Ordering::Less if str2.starts_with(str1) => {
step_2.iteratee = PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
Ordering::Less if str2.starts_with(&*str1) => {
step_2.iteratee =
PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
let c1_result = cycle_detection_step(i1, i2, &step_1);
r1 = step(i1, i1.brent_st.hare);
@@ -727,8 +734,9 @@ pub fn compare_pstr_prefixes<'a>(
continue;
}
}
Ordering::Greater if str1.starts_with(str2) => {
step_1.iteratee = PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
Ordering::Greater if str1.starts_with(&*str2) => {
step_1.iteratee =
PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
let c2_result = cycle_detection_step(i2, i1, &step_2);
r2 = step(i2, i2.brent_st.hare);
@@ -737,7 +745,7 @@ pub fn compare_pstr_prefixes<'a>(
}
}
_ => {
return PStrCmpResult::Ordered(str1.cmp(str2));
return PStrCmpResult::Ordered(str1.cmp(&*str2));
}
}
}
@@ -796,11 +804,8 @@ mod test {
fn pstr_iter_tests() {
let mut wam = MockWAM::new();
let pstr_var_cell = put_partial_string(
&mut wam.machine_st.heap,
"abc ",
&mut wam.machine_st.atom_tbl,
);
let pstr_var_cell =
put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
@@ -819,11 +824,8 @@ mod test {
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
let pstr_second_var_cell = put_partial_string(
&mut wam.machine_st.heap,
"def",
&mut wam.machine_st.atom_tbl,
);
let pstr_second_var_cell =
put_partial_string(&mut wam.machine_st.heap, "def", &wam.machine_st.atom_tbl);
let pstr_second_cell = wam.machine_st.heap[pstr_second_var_cell.get_value() as usize];
@@ -836,7 +838,11 @@ mod test {
);
assert_eq!(
iter.next(),
Some(PStrIteratee::PStrSegment(2, cell_as_atom!(pstr_second_cell), 0))
Some(PStrIteratee::PStrSegment(
2,
cell_as_atom!(pstr_second_cell),
0
))
);
assert_eq!(iter.next(), None);
@@ -855,7 +861,11 @@ mod test {
);
assert_eq!(
iter.next(),
Some(PStrIteratee::PStrSegment(2, cell_as_atom!(pstr_second_cell), 0))
Some(PStrIteratee::PStrSegment(
2,
cell_as_atom!(pstr_second_cell),
0
))
);
assert_eq!(iter.next(), None);
@@ -863,10 +873,14 @@ mod test {
}
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st
.heap
.push(pstr_loc_as_cell!(wam.machine_st.heap.len() + 1));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0)));
wam.machine_st
.heap
.push(fixnum_as_cell!(Fixnum::build_with(0)));
{
let mut iter = HeapPStrIter::new(&wam.machine_st.heap, 0);
@@ -892,31 +906,25 @@ mod test {
// construct a structurally similar but different cyclic partial string
// matching the one beginning at wam.machine_st.heap[0].
put_partial_string(
&mut wam.machine_st.heap,
"ab",
&mut wam.machine_st.atom_tbl,
);
put_partial_string(&mut wam.machine_st.heap, "ab", &wam.machine_st.atom_tbl);
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h+2));
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h + 2));
put_partial_string(
&mut wam.machine_st.heap,
"c ",
&mut wam.machine_st.atom_tbl,
);
put_partial_string(&mut wam.machine_st.heap, "c ", &wam.machine_st.atom_tbl);
wam.machine_st.heap.pop();
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h+4));
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h + 4));
wam.machine_st.heap.push(pstr_second_cell);
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h+6));
wam.machine_st.heap.push(pstr_loc_as_cell!(second_h + 6));
wam.machine_st.heap.push(pstr_offset_as_cell!(second_h));
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(0)));
wam.machine_st
.heap
.push(fixnum_as_cell!(Fixnum::build_with(0)));
let mut iter1 = HeapPStrIter::new(&wam.machine_st.heap, 0);
let mut iter2 = HeapPStrIter::new(&wam.machine_st.heap, second_h);
@@ -929,11 +937,7 @@ mod test {
wam.machine_st.heap.clear();
put_partial_string(
&mut wam.machine_st.heap,
"abc ",
&mut wam.machine_st.atom_tbl,
);
put_partial_string(&mut wam.machine_st.heap, "abc ", &wam.machine_st.atom_tbl);
let pstr_cell = wam.machine_st.heap[0];
@@ -963,11 +967,8 @@ mod test {
wam.machine_st.heap.clear();
let cstr_var_cell = put_complete_string(
&mut wam.machine_st.heap,
"abc",
&mut wam.machine_st.atom_tbl,
);
let cstr_var_cell =
put_complete_string(&mut wam.machine_st.heap, "abc", &wam.machine_st.atom_tbl);
wam.machine_st.heap.push(list_loc_as_cell!(2));
wam.machine_st.heap.push(heap_loc_as_cell!(2));
@@ -982,30 +983,18 @@ mod test {
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
assert_eq!(
wam.machine_st.heap[2],
char_as_cell!('a'),
);
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
assert_eq!(
wam.machine_st.heap[4],
char_as_cell!('b'),
);
assert_eq!(wam.machine_st.heap[4], char_as_cell!('b'),);
assert_eq!(
wam.machine_st.heap[6],
char_as_cell!('c'),
);
assert_eq!(wam.machine_st.heap[6], char_as_cell!('c'),);
// test "abc" = [X,Y,Z|D].
wam.machine_st.heap.clear();
let cstr_var_cell = put_complete_string(
&mut wam.machine_st.heap,
"abc",
&mut wam.machine_st.atom_tbl,
);
let cstr_var_cell =
put_complete_string(&mut wam.machine_st.heap, "abc", &wam.machine_st.atom_tbl);
wam.machine_st.heap.push(list_loc_as_cell!(2));
wam.machine_st.heap.push(heap_loc_as_cell!(2)); // X
@@ -1022,35 +1011,20 @@ mod test {
assert_eq!(wam.machine_st.fail, false);
assert_eq!(
wam.machine_st.heap[2],
char_as_cell!('a'),
);
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
assert_eq!(
wam.machine_st.heap[4],
char_as_cell!('b'),
);
assert_eq!(wam.machine_st.heap[4], char_as_cell!('b'),);
assert_eq!(
wam.machine_st.heap[6],
char_as_cell!('c'),
);
assert_eq!(wam.machine_st.heap[6], char_as_cell!('c'),);
assert_eq!(
wam.machine_st.heap[7],
empty_list_as_cell!(),
);
assert_eq!(wam.machine_st.heap[7], empty_list_as_cell!(),);
// test "d" = [d].
wam.machine_st.heap.clear();
let cstr_var_cell = put_complete_string(
&mut wam.machine_st.heap,
"d",
&mut wam.machine_st.atom_tbl,
);
let cstr_var_cell =
put_complete_string(&mut wam.machine_st.heap, "d", &wam.machine_st.atom_tbl);
wam.machine_st.heap.push(list_loc_as_cell!(2));
wam.machine_st.heap.push(char_as_cell!('d'));
@@ -1064,11 +1038,8 @@ mod test {
wam.machine_st.heap.clear();
let cstr_var_cell = put_complete_string(
&mut wam.machine_st.heap,
"abc",
&mut wam.machine_st.atom_tbl,
);
let cstr_var_cell =
put_complete_string(&mut wam.machine_st.heap, "abc", &wam.machine_st.atom_tbl);
wam.machine_st.heap.push(list_loc_as_cell!(2));
wam.machine_st.heap.push(heap_loc_as_cell!(2));
@@ -1085,30 +1056,17 @@ mod test {
assert_eq!(wam.machine_st.fail, false);
assert_eq!(
wam.machine_st.heap[2],
char_as_cell!('a'),
);
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
assert_eq!(
wam.machine_st.heap[4],
char_as_cell!('b'),
);
assert_eq!(wam.machine_st.heap[4], char_as_cell!('b'),);
assert_eq!(
wam.machine_st.heap[6],
char_as_cell!('c'),
);
assert_eq!(wam.machine_st.heap[6], char_as_cell!('c'),);
// test "abcdef" = [a,b,c|X].
wam.machine_st.heap.clear();
put_complete_string(
&mut wam.machine_st.heap,
"abcdef",
&mut wam.machine_st.atom_tbl,
);
put_complete_string(&mut wam.machine_st.heap, "abcdef", &wam.machine_st.atom_tbl);
wam.machine_st.heap.push(pstr_as_cell!(atom!("abc")));
wam.machine_st.heap.push(heap_loc_as_cell!(2));
@@ -1123,7 +1081,10 @@ mod test {
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(1));
assert_eq!(wam.machine_st.heap[4], atom_as_cstr_cell!(atom!("abcdef")));
assert_eq!(wam.machine_st.heap[5], pstr_offset_as_cell!(4));
assert_eq!(wam.machine_st.heap[6], fixnum_as_cell!(Fixnum::build_with("abc".len() as i64)));
assert_eq!(
wam.machine_st.heap[6],
fixnum_as_cell!(Fixnum::build_with("abc".len() as i64))
);
// test iteration on X = [b,c,b,c,b,c,b,c|...] as an offset.
@@ -1132,7 +1093,9 @@ mod test {
wam.machine_st.heap.push(pstr_as_cell!(atom!("abc")));
wam.machine_st.heap.push(pstr_loc_as_cell!(2));
wam.machine_st.heap.push(pstr_offset_as_cell!(0));
wam.machine_st.heap.push(fixnum_as_cell!(Fixnum::build_with(1)));
wam.machine_st
.heap
.push(fixnum_as_cell!(Fixnum::build_with(1)));
{
let mut iter = HeapPStrIter::new(&wam.machine_st.heap, 2);

View File

@@ -12,11 +12,7 @@ use indexmap::IndexSet;
use std::cell::Cell;
use std::convert::TryFrom;
pub(crate) fn to_op_decl(
prec: u16,
spec: Atom,
name: Atom,
) -> Result<OpDecl, CompilationError> {
pub(crate) fn to_op_decl(prec: u16, spec: Atom, name: Atom) -> Result<OpDecl, CompilationError> {
match spec {
atom!("xfx") => Ok(OpDecl::new(OpDesc::build_with(prec, XFX as u8), name)),
atom!("xfy") => Ok(OpDecl::new(OpDesc::build_with(prec, XFY as u8), name)),
@@ -29,19 +25,16 @@ pub(crate) fn to_op_decl(
}
}
fn setup_op_decl(
mut terms: Vec<Term>,
atom_tbl: &mut AtomTable,
) -> Result<OpDecl, CompilationError> {
fn setup_op_decl(mut terms: Vec<Term>, atom_tbl: &AtomTable) -> Result<OpDecl, CompilationError> {
let name = match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => name,
Term::Literal(_, Literal::Char(c)) => atom_tbl.build_with(&c.to_string()),
Term::Literal(_, Literal::Char(c)) => AtomTable::build_with(atom_tbl, &c.to_string()),
_ => return Err(CompilationError::InconsistentEntry),
};
let spec = match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => name,
Term::Literal(_, Literal::Char(c)) => atom_tbl.build_with(&c.to_string()),
Term::Literal(_, Literal::Char(c)) => AtomTable::build_with(atom_tbl, &c.to_string()),
_ => return Err(CompilationError::InconsistentEntry),
};
@@ -65,15 +58,20 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
let name = terms.pop().unwrap();
let arity = match arity {
Term::Literal(_, Literal::Integer(n)) => n.to_usize(),
Term::Literal(_, Literal::Integer(n)) => {
let value: usize = (&*n).try_into().unwrap();
Some(value)
},
Term::Literal(_, Literal::Fixnum(n)) => usize::try_from(n.get_num()).ok(),
_ => None,
}.ok_or(CompilationError::InvalidModuleExport)?;
}
.ok_or(CompilationError::InvalidModuleExport)?;
let name = match name {
Term::Literal(_, Literal::Atom(name)) => Some(name),
_ => None,
}.ok_or(CompilationError::InvalidModuleExport)?;
}
.ok_or(CompilationError::InvalidModuleExport)?;
if *slash == atom!("/") {
Ok((name, arity))
@@ -87,7 +85,7 @@ fn setup_predicate_indicator(term: &mut Term) -> Result<PredicateKey, Compilatio
fn setup_module_export(
mut term: Term,
atom_tbl: &mut AtomTable,
atom_tbl: &AtomTable,
) -> Result<ModuleExport, CompilationError> {
setup_predicate_indicator(&mut term)
.map(ModuleExport::PredicateKey)
@@ -113,7 +111,7 @@ pub(crate) fn build_rule_body(vars: &[Term], body_term: Term) -> Term {
pub(super) fn setup_module_export_list(
mut export_list: Term,
atom_tbl: &mut AtomTable,
atom_tbl: &AtomTable,
) -> Result<Vec<ModuleExport>, CompilationError> {
let mut exports = vec![];
@@ -133,7 +131,7 @@ pub(super) fn setup_module_export_list(
fn setup_module_decl(
mut terms: Vec<Term>,
atom_tbl: &mut AtomTable,
atom_tbl: &AtomTable,
) -> Result<ModuleDecl, CompilationError> {
let export_list = terms.pop().unwrap();
let name = terms.pop().unwrap();
@@ -141,7 +139,8 @@ fn setup_module_decl(
let name = match name {
Term::Literal(_, Literal::Atom(name)) => Some(name),
_ => None,
}.ok_or(CompilationError::InvalidModuleDecl)?;
}
.ok_or(CompilationError::InvalidModuleDecl)?;
let exports = setup_module_export_list(export_list, atom_tbl)?;
@@ -150,9 +149,7 @@ fn setup_module_decl(
fn setup_use_module_decl(mut terms: Vec<Term>) -> Result<ModuleSource, CompilationError> {
match terms.pop().unwrap() {
Term::Clause(_, name, mut terms)
if name == atom!("library") && terms.len() == 1 =>
{
Term::Clause(_, name, mut terms) if name == atom!("library") && terms.len() == 1 => {
match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => Ok(ModuleSource::Library(name)),
_ => Err(CompilationError::InvalidModuleDecl),
@@ -167,13 +164,11 @@ type UseModuleExport = (ModuleSource, IndexSet<ModuleExport>);
fn setup_qualified_import(
mut terms: Vec<Term>,
atom_tbl: &mut AtomTable,
atom_tbl: &AtomTable,
) -> Result<UseModuleExport, CompilationError> {
let mut export_list = terms.pop().unwrap();
let module_src = match terms.pop().unwrap() {
Term::Clause(_, name, mut terms)
if name == atom!("library") && terms.len() == 1 =>
{
Term::Clause(_, name, mut terms) if name == atom!("library") && terms.len() == 1 => {
match terms.pop().unwrap() {
Term::Literal(_, Literal::Atom(name)) => Ok(ModuleSource::Library(name)),
_ => Err(CompilationError::InvalidModuleDecl),
@@ -318,11 +313,11 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
}
(atom!("module"), 2) => {
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
Ok(Declaration::Module(setup_module_decl(terms, atom_tbl)?))
Ok(Declaration::Module(setup_module_decl(terms, &atom_tbl)?))
}
(atom!("op"), 3) => {
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
Ok(Declaration::Op(setup_op_decl(terms, atom_tbl)?))
Ok(Declaration::Op(setup_op_decl(terms, &atom_tbl)?))
}
(atom!("non_counted_backtracking"), 1) => {
let (name, arity) = setup_predicate_indicator(&mut terms.pop().unwrap())?;
@@ -331,7 +326,7 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
(atom!("use_module"), 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
(atom!("use_module"), 2) => {
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
let (name, exports) = setup_qualified_import(terms, atom_tbl)?;
let (name, exports) = setup_qualified_import(terms, &atom_tbl)?;
Ok(Declaration::UseQualifiedModule(name, exports))
}
@@ -381,19 +376,28 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
}
fn tag_with_module_name(module_name: Atom, term: Term) -> Term {
Term::Clause(Cell::default(), atom!(":"), vec![
Term::Literal(Cell::default(), Literal::Atom(module_name)),
term
])
Term::Clause(
Cell::default(),
atom!(":"),
vec![
Term::Literal(Cell::default(), Literal::Atom(module_name)),
term,
],
)
}
let process_term: fn(Atom, Term) -> Term;
let (module_name, key, term) = match term {
Term::Clause(cell, atom!(":"), mut terms) if terms.len() == 2 => {
if let Some((module_name, name)) = get_qualified_name(&terms[0], &terms[1]) {
if let Some((module_name, name)) = get_qualified_name(&terms[0], &terms[1])
{
process_term = tag_with_module_name;
(module_name, (name, terms[1].arity() + supp_args), terms.pop().unwrap())
(
module_name,
(name, terms[1].arity() + supp_args),
terms.pop().unwrap(),
)
} else {
arg_terms.push(Term::Clause(cell, atom!(":"), terms));
continue;
@@ -408,10 +412,8 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
let term = match term {
Term::Clause(cell, name, mut terms) => {
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
arg_terms.push(process_term(
module_name,
Term::Clause(cell, name, terms),
));
arg_terms
.push(process_term(module_name, Term::Clause(cell, name, terms)));
continue;
}
@@ -424,11 +426,14 @@ fn build_meta_predicate_clause<'a, LS: LoadState<'a>>(
Term::Literal(cell, Literal::Atom(name)) => {
let idx = loader.get_or_insert_qualified_code_index(module_name, key);
process_term(module_name, Term::Clause(
cell,
name,
vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
))
process_term(
module_name,
Term::Clause(
cell,
name,
vec![Term::Literal(Cell::default(), Literal::CodeIndex(idx))],
),
)
}
term => term,
};
@@ -462,12 +467,7 @@ pub(super) fn clause_to_query_term<'a, LS: LoadState<'a>>(
if let ClauseType::Named(arity, name, idx) = ct {
if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() {
let module_name = loader.payload.compilation_target.module_name();
let terms = build_meta_predicate_clause(
loader,
module_name,
terms,
meta_specs,
);
let terms = build_meta_predicate_clause(loader, module_name, terms, meta_specs);
return QueryTerm::Clause(
Cell::default(),
@@ -501,12 +501,7 @@ pub(super) fn qualified_clause_to_query_term<'a, LS: LoadState<'a>>(
if let ClauseType::Named(arity, name, idx) = ct {
if let Some(meta_specs) = loader.get_meta_specs(name, arity).cloned() {
let terms = build_meta_predicate_clause(
loader,
module_name,
terms,
meta_specs,
);
let terms = build_meta_predicate_clause(loader, module_name, terms, meta_specs);
return QueryTerm::Clause(
Cell::default(),
@@ -529,17 +524,13 @@ pub(crate) struct Preprocessor {
impl Preprocessor {
pub(super) fn new(settings: CodeGenSettings) -> Self {
Preprocessor {
settings,
}
Preprocessor { settings }
}
fn setup_fact(&mut self, term: Term) -> Result<(Fact, VarData), CompilationError> {
match term {
Term::Clause(..) | Term::Literal(_, Literal::Atom(..)) => {
let classifier = VariableClassifier::new(
self.settings.default_call_policy(),
);
let classifier = VariableClassifier::new(self.settings.default_call_policy());
let (head, var_data) = classifier.classify_fact(term)?;
Ok((Fact { head }, var_data))
@@ -554,21 +545,25 @@ impl Preprocessor {
head: Term,
body: Term,
) -> Result<(Rule, VarData), CompilationError> {
let classifier = VariableClassifier::new(
self.settings.default_call_policy(),
);
let classifier = VariableClassifier::new(self.settings.default_call_policy());
let (head, clauses, var_data) = classifier.classify_rule(loader, head, body)?;
match head {
Term::Clause(_, name, terms) => Ok((Rule {
head: (name, terms),
clauses,
}, var_data)),
Term::Literal(_, Literal::Atom(name)) => Ok((Rule {
head: (name, vec![]),
clauses,
}, var_data)),
Term::Clause(_, name, terms) => Ok((
Rule {
head: (name, terms),
clauses,
},
var_data,
)),
Term::Literal(_, Literal::Atom(name)) => Ok((
Rule {
head: (name, vec![]),
clauses,
},
var_data,
)),
_ => Err(CompilationError::InvalidRuleHead),
}
}

View File

@@ -30,12 +30,6 @@ pub struct Stack {
_marker: PhantomData<HeapCellValue>,
}
impl Drop for Stack {
fn drop(&mut self) {
self.buf.deallocate();
}
}
#[derive(Debug)]
pub(crate) struct AndFramePrelude {
pub(crate) num_cells: usize,
@@ -189,7 +183,7 @@ impl Stack {
let frame_size = AndFrame::size_of(num_cells);
unsafe {
let e = self.buf.ptr as usize - self.buf.base as usize;
let e = (*self.buf.ptr.get_mut()) as usize - self.buf.base as usize;
let new_ptr = self.alloc(frame_size);
let mut offset = prelude_size::<AndFramePrelude>();
@@ -213,7 +207,7 @@ impl Stack {
let frame_size = OrFrame::size_of(num_cells);
unsafe {
let b = self.buf.ptr as usize - self.buf.base as usize;
let b = (*self.buf.ptr.get_mut()) as usize - self.buf.base as usize;
let new_ptr = self.alloc(frame_size);
let mut offset = prelude_size::<OrFramePrelude>();
@@ -269,8 +263,8 @@ impl Stack {
pub(crate) fn truncate(&mut self, b: usize) {
let base = self.buf.base as usize + b;
if base < self.buf.ptr as usize {
self.buf.ptr = base as *mut _;
if base < (*self.buf.ptr.get_mut()) as usize {
*self.buf.ptr.get_mut() = base as *mut _;
}
}
}
@@ -290,7 +284,7 @@ mod tests {
assert_eq!(
e,
0// 10 * mem::size_of::<HeapCellValue>() + prelude_size::<AndFrame>()
0 // 10 * mem::size_of::<HeapCellValue>() + prelude_size::<AndFrame>()
);
assert_eq!(and_frame.prelude.num_cells, 10);
@@ -315,7 +309,10 @@ mod tests {
let and_frame = wam.machine_st.stack.index_and_frame_mut(next_e);
for idx in 0..9 {
assert_eq!(and_frame[idx + 1], stack_loc_as_cell!(AndFrame, next_e, idx + 1));
assert_eq!(
and_frame[idx + 1],
stack_loc_as_cell!(AndFrame, next_e, idx + 1)
);
}
let and_frame = wam.machine_st.stack.index_and_frame(e);

View File

@@ -4,13 +4,13 @@ use crate::parser::ast::*;
use crate::parser::char_reader::*;
use crate::read::*;
#[cfg(feature = "http")]
use crate::http::HttpResponse;
use crate::machine::heap::*;
use crate::machine::machine_errors::*;
use crate::machine::machine_indices::*;
use crate::machine::machine_state::*;
use crate::types::*;
#[cfg(feature = "http")]
use crate::http::HttpResponse;
pub use modular_bitfield::prelude::*;
@@ -19,11 +19,11 @@ use std::error::Error;
use std::fmt;
use std::fmt::Debug;
use std::fs::{File, OpenOptions};
use std::hash::{Hash};
use std::hash::Hash;
use std::io;
use std::io::{BufRead, Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
use std::mem;
use std::net::{TcpStream, Shutdown};
use std::net::{Shutdown, TcpStream};
use std::ops::{Deref, DerefMut};
use std::ptr;
@@ -154,8 +154,10 @@ impl StreamLayout<CharReader<InputFileStream>> {
fn position(&mut self) -> Option<u64> {
// stream is the internal CharReader. subtract
// its pending buffer length from position.
self.get_mut().file.seek(SeekFrom::Current(0))
.map(|pos| pos - self.stream.rem_buf_len() as u64)
self.get_mut()
.file
.seek(SeekFrom::Current(0))
.map(|pos| pos - self.stream.rem_buf_len() as u64)
.ok()
}
}
@@ -195,7 +197,7 @@ impl CharRead for StaticStringStream {
#[inline(always)]
fn peek_char(&mut self) -> Option<std::io::Result<char>> {
let pos = self.stream.position() as usize;
self.stream.get_ref()[pos ..].chars().next().map(Ok)
self.stream.get_ref()[pos..].chars().next().map(Ok)
}
#[inline(always)]
@@ -205,7 +207,9 @@ impl CharRead for StaticStringStream {
#[inline(always)]
fn put_back_char(&mut self, c: char) {
self.stream.seek(SeekFrom::Current(- (c.len_utf8() as i64))).unwrap();
self.stream
.seek(SeekFrom::Current(-(c.len_utf8() as i64)))
.unwrap();
}
}
@@ -294,7 +298,7 @@ pub struct HttpWriteStream {
#[cfg(feature = "http")]
impl Debug for HttpWriteStream {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
write!(f, "Http Write Stream")
write!(f, "Http Write Stream")
}
}
@@ -302,28 +306,27 @@ impl Debug for HttpWriteStream {
impl Write for HttpWriteStream {
#[inline]
fn write(&mut self, buf: &[u8]) -> std::io::Result<usize> {
self.buffer.extend_from_slice(buf);
Ok(buf.len())
self.buffer.extend_from_slice(buf);
Ok(buf.len())
}
#[inline]
fn flush(&mut self) -> std::io::Result<()> {
let (ready, response, cvar) = &**self.response;
let (ready, response, cvar) = &**self.response;
let mut ready = ready.lock().unwrap();
{
let mut response = response.lock().unwrap();
let bytes = bytes::Bytes::copy_from_slice(&self.buffer);
let mut response_ = hyper::Response::builder()
.status(self.status_code);
*response_.headers_mut().unwrap() = self.headers.clone();
*response = Some(response_.body(http_body_util::Full::new(bytes)).unwrap());
}
*ready = true;
cvar.notify_one();
let mut ready = ready.lock().unwrap();
{
let mut response = response.lock().unwrap();
Ok(())
let bytes = bytes::Bytes::copy_from_slice(&self.buffer);
let mut response_ = hyper::Response::builder().status(self.status_code);
*response_.headers_mut().unwrap() = self.headers.clone();
*response = Some(response_.body(http_body_util::Full::new(bytes)).unwrap());
}
*ready = true;
cvar.notify_one();
Ok(())
}
}
@@ -510,7 +513,9 @@ impl Stream {
#[inline]
pub fn from_owned_string(string: String, arena: &mut Arena) -> Stream {
Stream::Byte(arena_alloc!(
StreamLayout::new(CharReader::new(ByteStream(Cursor::new(string.into_bytes())))),
StreamLayout::new(CharReader::new(ByteStream(Cursor::new(
string.into_bytes()
)))),
arena
))
}
@@ -546,7 +551,7 @@ impl Stream {
#[cfg(feature = "http")]
ArenaHeaderTag::HttpReadStream => Stream::HttpRead(TypedArenaPtr::new(ptr as *mut _)),
#[cfg(feature = "http")]
ArenaHeaderTag::HttpWriteStream => Stream::HttpWrite(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::HttpWriteStream => Stream::HttpWrite(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::ReadlineStream => Stream::Readline(TypedArenaPtr::new(ptr as *mut _)),
ArenaHeaderTag::StaticStringStream => {
Stream::StaticString(TypedArenaPtr::new(ptr as *mut _))
@@ -603,7 +608,7 @@ impl Stream {
#[cfg(feature = "http")]
Stream::HttpRead(ptr) => ptr.header_ptr(),
#[cfg(feature = "http")]
Stream::HttpWrite(ptr) => ptr.header_ptr(),
Stream::HttpWrite(ptr) => ptr.header_ptr(),
Stream::Null(_) => ptr::null(),
Stream::Readline(ptr) => ptr.header_ptr(),
Stream::StandardOutput(ptr) => ptr.header_ptr(),
@@ -728,14 +733,14 @@ impl CharRead for Stream {
Stream::StaticString(src) => (*src).peek_char(),
Stream::Byte(cursor) => (*cursor).peek_char(),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => Some(Err(std::io::Error::new(
Stream::HttpWrite(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
))),
Stream::OutputFile(_) |
Stream::StandardError(_) |
Stream::StandardOutput(_) |
Stream::Null(_) => Some(Err(std::io::Error::new(
Stream::OutputFile(_)
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
))),
@@ -754,14 +759,14 @@ impl CharRead for Stream {
Stream::StaticString(src) => (*src).read_char(),
Stream::Byte(cursor) => (*cursor).read_char(),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => Some(Err(std::io::Error::new(
Stream::HttpWrite(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
))),
Stream::OutputFile(_) |
Stream::StandardError(_) |
Stream::StandardOutput(_) |
Stream::Null(_) => Some(Err(std::io::Error::new(
Stream::OutputFile(_)
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => Some(Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
))),
@@ -780,11 +785,11 @@ impl CharRead for Stream {
Stream::StaticString(src) => src.put_back_char(c),
Stream::Byte(cursor) => cursor.put_back_char(c),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => {}
Stream::OutputFile(_) |
Stream::StandardError(_) |
Stream::StandardOutput(_) |
Stream::Null(_) => {}
Stream::HttpWrite(_) => {}
Stream::OutputFile(_)
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => {}
}
}
@@ -800,11 +805,11 @@ impl CharRead for Stream {
Stream::StaticString(ref mut src) => src.consume(nread),
Stream::Byte(ref mut cursor) => cursor.consume(nread),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => {}
Stream::OutputFile(_) |
Stream::StandardError(_) |
Stream::StandardOutput(_) |
Stream::Null(_) => {}
Stream::HttpWrite(_) => {}
Stream::OutputFile(_)
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => {}
}
}
}
@@ -823,17 +828,17 @@ impl Read for Stream {
Stream::StaticString(src) => (*src).read(buf),
Stream::Byte(cursor) => (*cursor).read(buf),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => Err(std::io::Error::new(
Stream::HttpWrite(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
)),
Stream::OutputFile(_)
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
)),
| Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::Null(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::ReadFromOutputStream,
)),
};
bytes_read
@@ -851,16 +856,16 @@ impl Write for Stream {
Stream::StandardOutput(stream) => stream.write(buf),
Stream::StandardError(stream) => stream.write(buf),
#[cfg(feature = "http")]
Stream::HttpWrite(ref mut stream) => stream.get_mut().write(buf),
Stream::HttpWrite(ref mut stream) => stream.get_mut().write(buf),
#[cfg(feature = "http")]
Stream::HttpRead(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::WriteToInputStream,
)),
Stream::StaticString(_) |
Stream::Readline(_) |
Stream::InputFile(..) |
Stream::Null(_) => Err(std::io::Error::new(
Stream::StaticString(_)
| Stream::Readline(_)
| Stream::InputFile(..)
| Stream::Null(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::WriteToInputStream,
)),
@@ -877,16 +882,16 @@ impl Write for Stream {
Stream::StandardError(stream) => stream.stream.flush(),
Stream::StandardOutput(stream) => stream.stream.flush(),
#[cfg(feature = "http")]
Stream::HttpWrite(ref mut stream) => stream.stream.get_mut().flush(),
#[cfg(feature = "http")]
Stream::HttpWrite(ref mut stream) => stream.stream.get_mut().flush(),
#[cfg(feature = "http")]
Stream::HttpRead(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::FlushToInputStream,
)),
Stream::StaticString(_) |
Stream::Readline(_) |
Stream::InputFile(_) |
Stream::Null(_) => Err(std::io::Error::new(
Stream::StaticString(_)
| Stream::Readline(_)
| Stream::InputFile(_)
| Stream::Null(_) => Err(std::io::Error::new(
ErrorKind::PermissionDenied,
StreamError::FlushToInputStream,
)),
@@ -898,8 +903,10 @@ impl Write for Stream {
enum StreamError {
PeekByteFailed,
PeekByteFromNonPeekableStream,
#[allow(unused)] PeekCharFailed,
#[allow(unused)] PeekCharFromNonPeekableStream,
#[allow(unused)]
PeekCharFailed,
#[allow(unused)]
PeekCharFromNonPeekableStream,
ReadFromOutputStream,
WriteToInputStream,
FlushToInputStream,
@@ -958,7 +965,11 @@ impl PartialEq for Stream {
impl Eq for Stream {}
fn cursor_position<T>(past_end_of_stream: &mut bool, cursor: &Cursor<T>, cursor_len: u64) -> AtEndOfStream {
fn cursor_position<T>(
past_end_of_stream: &mut bool,
cursor: &Cursor<T>,
cursor_len: u64,
) -> AtEndOfStream {
let position = cursor.position();
let at_end_of_stream = match position.cmp(&cursor_len) {
@@ -984,17 +995,10 @@ impl Stream {
Stream::StaticString(string_stream_layout) => {
Some(string_stream_layout.stream.stream.position())
}
Stream::InputFile(file_stream) => {
file_stream.position()
}
Stream::InputFile(file_stream) => file_stream.position(),
#[cfg(feature = "tls")]
Stream::NamedTls(..) => {
Some(0)
}
Stream::NamedTcp(..)
| Stream::Readline(..) => {
Some(0)
}
Stream::NamedTls(..) => Some(0),
Stream::NamedTcp(..) | Stream::Readline(..) => Some(0),
_ => None,
};
@@ -1011,7 +1015,11 @@ impl Stream {
..
} = &mut **stream_layout;
stream.get_mut().file.seek(SeekFrom::Start(position)).unwrap();
stream
.get_mut()
.file
.seek(SeekFrom::Start(position))
.unwrap();
stream.reset_buffer(); // flush the internal buffer.
if let Ok(metadata) = stream.get_ref().file.metadata() {
@@ -1127,9 +1135,7 @@ impl Stream {
}
}
}
_ => {
AtEndOfStream::Not
}
_ => AtEndOfStream::Not,
}
}
@@ -1153,14 +1159,16 @@ impl Stream {
#[cfg(feature = "tls")]
Stream::NamedTls(..) => atom!("read_append"),
Stream::Byte(_)
| Stream::Readline(_)
| Stream::StaticString(_)
| Stream::InputFile(..) => atom!("read"),
| Stream::Readline(_)
| Stream::StaticString(_)
| Stream::InputFile(..) => atom!("read"),
Stream::NamedTcp(..) => atom!("read_append"),
Stream::OutputFile(file) if file.is_append => atom!("append"),
#[cfg(feature = "http")]
Stream::HttpWrite(_) => atom!("write"),
Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) => atom!("write"),
Stream::OutputFile(_) | Stream::StandardError(_) | Stream::StandardOutput(_) => {
atom!("write")
}
Stream::Null(_) => atom!(""),
}
}
@@ -1182,11 +1190,7 @@ impl Stream {
}
#[inline]
pub(crate) fn from_tcp_stream(
address: Atom,
tcp_stream: TcpStream,
arena: &mut Arena,
) -> Self {
pub(crate) fn from_tcp_stream(address: Atom, tcp_stream: TcpStream, arena: &mut Arena) -> Self {
tcp_stream.set_read_timeout(None).unwrap();
tcp_stream.set_write_timeout(None).unwrap();
@@ -1234,20 +1238,20 @@ impl Stream {
#[cfg(feature = "http")]
#[inline]
pub(crate) fn from_http_sender(
response: TypedArenaPtr<HttpResponse>,
status_code: u16,
headers: hyper::HeaderMap,
arena: &mut Arena,
response: TypedArenaPtr<HttpResponse>,
status_code: u16,
headers: hyper::HeaderMap,
arena: &mut Arena,
) -> Self {
Stream::HttpWrite(arena_alloc!(
StreamLayout::new(CharReader::new(HttpWriteStream {
response,
status_code,
headers,
buffer: Vec::new(),
})),
arena
))
Stream::HttpWrite(arena_alloc!(
StreamLayout::new(CharReader::new(HttpWriteStream {
response,
status_code,
headers,
buffer: Vec::new(),
})),
arena
))
}
#[inline]
@@ -1282,11 +1286,9 @@ impl Stream {
match stream {
Stream::NamedTcp(ref mut tcp_stream) => {
tcp_stream.inner_mut().tcp_stream.shutdown(Shutdown::Both)
},
#[cfg(feature = "tls")]
Stream::NamedTls(ref mut tls_stream) => {
tls_stream.inner_mut().tls_stream.shutdown()
}
#[cfg(feature = "tls")]
Stream::NamedTls(ref mut tls_stream) => tls_stream.inner_mut().tls_stream.shutdown(),
#[cfg(feature = "http")]
Stream::HttpRead(ref mut http_stream) => {
unsafe {
@@ -1297,14 +1299,14 @@ impl Stream {
Ok(())
}
#[cfg(feature = "http")]
Stream::HttpWrite(ref mut http_stream) => {
Stream::HttpWrite(ref mut http_stream) => {
unsafe {
http_stream.set_tag(ArenaHeaderTag::Dropped);
std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _);
}
Ok(())
}
}
Stream::InputFile(mut file_stream) => {
// close the stream by dropping the inner File.
unsafe {
@@ -1323,7 +1325,7 @@ impl Stream {
Ok(())
}
_ => Ok(())
_ => Ok(()),
}
}
@@ -1344,10 +1346,10 @@ impl Stream {
#[cfg(feature = "http")]
Stream::HttpRead(..) => true,
Stream::NamedTcp(..)
| Stream::Byte(_)
| Stream::Readline(_)
| Stream::StaticString(_)
| Stream::InputFile(..) => true,
| Stream::Byte(_)
| Stream::Readline(_)
| Stream::StaticString(_)
| Stream::InputFile(..) => true,
_ => false,
}
}
@@ -1360,10 +1362,10 @@ impl Stream {
#[cfg(feature = "http")]
Stream::HttpWrite(..) => true,
Stream::StandardError(_)
| Stream::StandardOutput(_)
| Stream::NamedTcp(..)
| Stream::Byte(_)
| Stream::OutputFile(..) => true,
| Stream::StandardOutput(_)
| Stream::NamedTcp(..)
| Stream::Byte(_)
| Stream::OutputFile(..) => true,
_ => false,
}
}
@@ -1381,7 +1383,12 @@ impl Stream {
return true;
}
Stream::InputFile(ref mut file_stream) => {
file_stream.stream.get_mut().file.seek(SeekFrom::Start(0)).unwrap();
file_stream
.stream
.get_mut()
.file
.seek(SeekFrom::Start(0))
.unwrap();
return true;
}
Stream::Readline(ref mut readline_stream) => {
@@ -1410,17 +1417,13 @@ impl Stream {
_ => Err(std::io::Error::new(ErrorKind::UnexpectedEof, "end of file")),
}
}
Stream::InputFile(ref mut file) => {
match file.peek_byte() {
Some(result) => {
Ok(result?)
}
_ => Err(std::io::Error::new(
ErrorKind::UnexpectedEof,
StreamError::PeekByteFailed,
)),
}
}
Stream::InputFile(ref mut file) => match file.peek_byte() {
Some(result) => Ok(result?),
_ => Err(std::io::Error::new(
ErrorKind::UnexpectedEof,
StreamError::PeekByteFailed,
)),
},
Stream::Readline(ref mut stream) => stream.stream.peek_byte(),
Stream::NamedTcp(ref mut stream) => {
let mut b = [0u8; 1];
@@ -1663,7 +1666,10 @@ impl MachineState {
}
}
pub(crate) fn open_parsing_stream(&mut self, mut stream: Stream) -> Result<Stream, ParserError> {
pub(crate) fn open_parsing_stream(
&mut self,
mut stream: Stream,
) -> Result<Stream, ParserError> {
match stream.peek_char() {
None => Ok(stream), // empty stream is handled gracefully by Lexer::eof
Some(Err(e)) => Err(ParserError::IO(e)),
@@ -1687,7 +1693,7 @@ impl MachineState {
arity: usize,
) -> MachineStub {
let stub = functor_stub(caller, arity);
let err = self.permission_error(
let err = self.permission_error(
perm,
err_atom,
if let Some(alias) = stream.options().get_alias() {
@@ -1723,7 +1729,7 @@ impl MachineState {
stub_arity: usize,
) -> MachineStub {
let stub = functor_stub(stub_name, stub_arity);
let err = self.permission_error(Permission::Open, atom!("source_sink"), culprit);
let err = self.permission_error(Permission::Open, atom!("source_sink"), culprit);
self.error_form(err, stub)
}
@@ -1847,7 +1853,7 @@ impl MachineState {
}
};
let file = match open_options.open(file_spec.as_str()) {
let file = match open_options.open(&*file_spec.as_str()) {
Ok(file) => file,
Err(err) => {
match err.kind() {
@@ -1855,15 +1861,18 @@ impl MachineState {
// 8.11.5.3j)
let stub = functor_stub(atom!("open"), 4);
let err = self.existence_error(
ExistenceError::SourceSink(self[temp_v!(1)]),
);
let err =
self.existence_error(ExistenceError::SourceSink(self[temp_v!(1)]));
return Err(self.error_form(err, stub));
}
ErrorKind::PermissionDenied => {
// 8.11.5.3k)
return Err(self.open_permission_error(self.registers[1], atom!("open"), 4));
return Err(self.open_permission_error(
self.registers[1],
atom!("open"),
4,
));
}
_ => {
let stub = functor_stub(atom!("open"), 4);

File diff suppressed because it is too large Load Diff

View File

@@ -1,8 +1,8 @@
use crate::forms::*;
use crate::machine::*;
use crate::machine::load_state::*;
use crate::machine::loader::*;
use crate::machine::machine_errors::*;
use crate::machine::*;
use crate::parser::ast::*;
use crate::parser::parser::*;
use crate::read::devour_whitespace;
@@ -45,7 +45,10 @@ impl<'a> BootstrappingTermStream<'a> {
listing_src: ListingSource,
) -> Self {
let parser = Parser::new(stream, machine_st);
Self { parser, listing_src }
Self {
parser,
listing_src,
}
}
}
@@ -101,7 +104,7 @@ impl<TS> LoadStatePayload<TS> {
non_counted_bt_preds: IndexSet::with_hasher(FxBuildHasher::default()),
predicates: predicate_queue![],
clause_clauses: vec![],
}
}
}
}
@@ -122,20 +125,18 @@ impl TermStream for LiveTermStream {
}
}
pub struct InlineTermStream {
}
pub struct InlineTermStream {}
impl TermStream for InlineTermStream {
fn next(&mut self, _: &CompositeOpDir) -> Result<Term, CompilationError> {
Err(CompilationError::from(ParserError::unexpected_eof()))
Err(CompilationError::from(ParserError::unexpected_eof()))
}
fn eof(&mut self) -> Result<bool, CompilationError> {
Ok(true)
Ok(true)
}
fn listing_src(&self) -> &ListingSource {
&ListingSource::User
&ListingSource::User
}
}

View File

@@ -1,9 +1,9 @@
use crate::arena::*;
use crate::forms::*;
use crate::heap_iter::stackful_preorder_iter;
use crate::machine::*;
use crate::machine::machine_state::*;
use crate::machine::partial_string::*;
use crate::machine::*;
use crate::types::*;
use std::cmp::Ordering;
@@ -12,6 +12,7 @@ use std::ops::{Deref, DerefMut};
use derive_deref::*;
use fxhash::FxBuildHasher;
use indexmap::IndexSet;
use num_order::NumOrd;
pub(crate) trait Unifier: DerefMut<Target = MachineState> {
fn unify_structure(&mut self, s1: usize, value: HeapCellValue) {
@@ -190,8 +191,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
machine_st.pdl.push(pstr_iter1.focus);
}
}
continuable @ PStrCmpResult::FirstIterContinuable(iteratee) |
continuable @ PStrCmpResult::SecondIterContinuable(iteratee) => {
continuable @ PStrCmpResult::FirstIterContinuable(iteratee)
| continuable @ PStrCmpResult::SecondIterContinuable(iteratee) => {
if continuable.is_second_iter() {
std::mem::swap(&mut pstr_iter1, &mut pstr_iter2);
}
@@ -426,8 +427,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
match Number::try_from(value) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if n1.get_num() == n2.get_num() => {}
Number::Integer(n2) if n1.get_num() == *n2 => {}
Number::Rational(n2) if n1.get_num() == *n2 => {}
Number::Integer(n2) if (*n2).num_eq(&n1.get_num()) => {}
Number::Rational(n2) if (*n2).num_eq(&Integer::from(n1.get_num())) => {}
_ => {
self.fail = true;
}
@@ -439,10 +440,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
}
fn unify_big_num<N>(&mut self, n1: TypedArenaPtr<N>, value: HeapCellValue)
where N: PartialEq<Rational>
+ PartialEq<Integer>
+ PartialEq<i64>
+ ArenaAllocated
where
N: PartialEq<Rational> + PartialEq<Integer> + PartialEq<i64> + ArenaAllocated,
{
if let Some(r) = value.as_var() {
Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
@@ -464,6 +463,48 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
}
}
fn unify_big_integer(&mut self, n1: TypedArenaPtr<Integer>, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
return;
}
match Number::try_from(value) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&n2.get_num()) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
Number::Rational(n2) if (*n2).num_eq(&*n1) => {}
_ => {
self.fail = true;
}
},
Err(_) => {
self.fail = true;
}
}
}
fn unify_big_rational(&mut self, n1: TypedArenaPtr<Rational>, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, typed_arena_ptr_as_cell!(n1));
return;
}
match Number::try_from(value) {
Ok(n2) => match n2 {
Number::Fixnum(n2) if (*n1).num_eq(&Integer::from(n2.get_num())) => {}
Number::Integer(n2) if (*n1).num_eq(&*n2) => {}
Number::Rational(n2) if n1 == n2 => {}
_ => {
self.fail = true;
}
},
Err(_) => {
self.fail = true;
}
}
}
fn unify_f64(&mut self, f1: F64Ptr, value: HeapCellValue) {
if let Some(r) = value.as_var() {
Self::bind(self, r, HeapCellValue::from(f1));
@@ -489,10 +530,10 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
match_untyped_arena_ptr!(ptr,
(ArenaHeaderTag::Integer, int_ptr) => {
Self::unify_big_num(self, int_ptr, value);
Self::unify_big_integer(self, int_ptr, value);
}
(ArenaHeaderTag::Rational, rat_ptr) => {
Self::unify_big_num(self, rat_ptr, value);
Self::unify_big_rational(self, rat_ptr, value);
}
(ArenaHeaderTag::Stream, stream) => {
read_heap_cell!(value,