Merge pull request #2147 from infogulch/lint-format
Resolve all lints and formating; split style checks into separate job
This commit is contained in:
2
.git-blame-ignore-revs
Normal file
2
.git-blame-ignore-revs
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
# Resolved all lints and formatted the codebase
|
||||||
|
9444e62df9820d6bfd96dbd8849e177bc5cecc2e
|
||||||
82
.github/workflows/ci.yml
vendored
82
.github/workflows/ci.yml
vendored
@@ -11,6 +11,47 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
|
style:
|
||||||
|
runs-on: ubuntu-22.04
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v3
|
||||||
|
- uses: dtolnay/rust-toolchain@master
|
||||||
|
id: toolchain
|
||||||
|
with:
|
||||||
|
toolchain: nightly
|
||||||
|
targets: x86_64-unknown-linux-gnu
|
||||||
|
components: clippy, rustfmt
|
||||||
|
- run: cargo install cargo2junit --force
|
||||||
|
- uses: actions/cache@v3
|
||||||
|
with:
|
||||||
|
path: |
|
||||||
|
~/.cargo/bin/
|
||||||
|
~/.cargo/registry/index/
|
||||||
|
~/.cargo/registry/cache/
|
||||||
|
~/.cargo/git/db/
|
||||||
|
target/
|
||||||
|
key: style_rustc-${{ steps.toolchain.outputs.cachekey }}_cargo-${{ hashFiles('**/Cargo.lock') }}
|
||||||
|
|
||||||
|
- name: Check formatting
|
||||||
|
run: cargo fmt --check
|
||||||
|
- name: Check clippy
|
||||||
|
run: cargo clippy --no-deps --all-targets
|
||||||
|
- name: Test and report
|
||||||
|
run: |
|
||||||
|
RUSTC_BOOTSTRAP=1 cargo test --all -- -Z unstable-options --format json --report-time | cargo2junit > cargo_test_results.xml
|
||||||
|
- name: Publish cargo test results artifact
|
||||||
|
uses: actions/upload-artifact@v3
|
||||||
|
with:
|
||||||
|
name: cargo-test-results
|
||||||
|
path: cargo_test_results.xml
|
||||||
|
- name: Publish cargo test summary
|
||||||
|
uses: EnricoMi/publish-unit-test-result-action/composite@master
|
||||||
|
with:
|
||||||
|
check_name: Cargo test summary
|
||||||
|
files: cargo_test_results.xml
|
||||||
|
fail_on: nothing
|
||||||
|
comment_mode: off
|
||||||
|
|
||||||
build-test:
|
build-test:
|
||||||
runs-on: ${{ matrix.os }}
|
runs-on: ${{ matrix.os }}
|
||||||
strategy:
|
strategy:
|
||||||
@@ -18,13 +59,13 @@ jobs:
|
|||||||
matrix:
|
matrix:
|
||||||
include:
|
include:
|
||||||
# operating systems
|
# operating systems
|
||||||
- { os: windows-latest, rust-version: stable, publish: true, target: 'x86_64-pc-windows-msvc'}
|
- { os: windows-latest, rust-version: stable, target: 'x86_64-pc-windows-msvc', publish: true }
|
||||||
- { os: macos-11, rust-version: stable, publish: true, target: 'x86_64-apple-darwin' }
|
- { os: macos-11, rust-version: stable, target: 'x86_64-apple-darwin', publish: true }
|
||||||
- { os: ubuntu-20.04, rust-version: stable, publish: true, target: 'x86_64-unknown-linux-gnu' }
|
- { os: ubuntu-20.04, rust-version: stable, target: 'x86_64-unknown-linux-gnu', publish: true }
|
||||||
# architectures
|
# architectures
|
||||||
- { os: ubuntu-22.04, rust-version: stable, publish: true, target: 'x86_64-unknown-linux-gnu', extra: true }
|
- { os: ubuntu-22.04, rust-version: stable, target: 'x86_64-unknown-linux-gnu', publish: true }
|
||||||
- { os: ubuntu-22.04, rust-version: stable, publish: true, target: 'i686-unknown-linux-gnu' }
|
- { os: ubuntu-22.04, rust-version: stable, target: 'i686-unknown-linux-gnu', publish: true }
|
||||||
- { os: ubuntu-22.04, rust-version: nightly, publish: true, target: 'wasm32-unknown-unknown', args: '--no-default-features' }
|
- { os: ubuntu-22.04, rust-version: nightly, target: 'wasm32-unknown-unknown', publish: true, args: '--no-default-features' }
|
||||||
# rust versions
|
# rust versions
|
||||||
- { os: ubuntu-22.04, rust-version: "1.70", target: 'x86_64-unknown-linux-gnu'}
|
- { os: ubuntu-22.04, rust-version: "1.70", target: 'x86_64-unknown-linux-gnu'}
|
||||||
- { os: ubuntu-22.04, rust-version: beta, target: 'x86_64-unknown-linux-gnu'}
|
- { os: ubuntu-22.04, rust-version: beta, target: 'x86_64-unknown-linux-gnu'}
|
||||||
@@ -39,7 +80,6 @@ jobs:
|
|||||||
with:
|
with:
|
||||||
toolchain: ${{ matrix.rust-version }}
|
toolchain: ${{ matrix.rust-version }}
|
||||||
targets: ${{ matrix.target }}
|
targets: ${{ matrix.target }}
|
||||||
components: clippy, rustfmt
|
|
||||||
- name: Install i686 dependencies
|
- name: Install i686 dependencies
|
||||||
if: "contains(matrix.target,'i686')"
|
if: "contains(matrix.target,'i686')"
|
||||||
run: |
|
run: |
|
||||||
@@ -62,36 +102,8 @@ jobs:
|
|||||||
- name: Build library
|
- name: Build library
|
||||||
run: cargo rustc --lib --target ${{ matrix.target }} ${{ matrix.args }} --verbose
|
run: cargo rustc --lib --target ${{ matrix.target }} ${{ matrix.args }} --verbose
|
||||||
- name: Test
|
- name: Test
|
||||||
if: "!matrix.extra"
|
|
||||||
run: cargo test --target ${{ matrix.target }} ${{ matrix.args }} --all --verbose || echo "::warning ::Tests failed"
|
run: cargo test --target ${{ matrix.target }} ${{ matrix.args }} --all --verbose || echo "::warning ::Tests failed"
|
||||||
|
|
||||||
# Extra steps only run once to avoid duplication, when matrix.extra is true
|
|
||||||
- name: Test and report
|
|
||||||
if: matrix.extra
|
|
||||||
run: |
|
|
||||||
cargo install cargo2junit --force
|
|
||||||
RUSTC_BOOTSTRAP=1 cargo test --all -- -Z unstable-options --format json --report-time | cargo2junit > cargo_test_results.xml
|
|
||||||
- name: Publish cargo test results artifact
|
|
||||||
if: matrix.extra
|
|
||||||
uses: actions/upload-artifact@v3
|
|
||||||
with:
|
|
||||||
name: cargo-test-results
|
|
||||||
path: cargo_test_results.xml
|
|
||||||
- name: Publish cargo test summary
|
|
||||||
if: matrix.extra
|
|
||||||
uses: EnricoMi/publish-unit-test-result-action/composite@master
|
|
||||||
with:
|
|
||||||
check_name: Cargo test summary
|
|
||||||
files: cargo_test_results.xml
|
|
||||||
fail_on: nothing
|
|
||||||
comment_mode: off
|
|
||||||
- name: Check formatting
|
|
||||||
if: matrix.extra
|
|
||||||
run: cargo fmt --check || echo "::warning ::cargo fmt found some formatting changes that may improve readability"
|
|
||||||
- name: Check clippy
|
|
||||||
if: matrix.extra
|
|
||||||
run: cargo clippy --no-deps || echo "::warning ::cargo clippy found some code style changes that may be more idiomatic"
|
|
||||||
|
|
||||||
# On stable rust builds, build a binary and publish as a github actions
|
# On stable rust builds, build a binary and publish as a github actions
|
||||||
# artifact. These binaries could be useful for testing the pipeline but
|
# artifact. These binaries could be useful for testing the pipeline but
|
||||||
# are only retained by github for 90 days.
|
# are only retained by github for 90 days.
|
||||||
|
|||||||
2
Cargo.lock
generated
2
Cargo.lock
generated
@@ -2032,7 +2032,7 @@ checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49"
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "scryer-prolog"
|
name = "scryer-prolog"
|
||||||
version = "0.9.2"
|
version = "0.9.3"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"assert_cmd",
|
"assert_cmd",
|
||||||
"base64 0.12.3",
|
"base64 0.12.3",
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ struct Level;
|
|||||||
struct NextOrFail;
|
struct NextOrFail;
|
||||||
struct RegType;
|
struct RegType;
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(ToDeriveInput, EnumDiscriminants)]
|
#[derive(ToDeriveInput, EnumDiscriminants)]
|
||||||
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
||||||
@@ -49,6 +50,7 @@ enum CompareNumber {
|
|||||||
NumberEqual(ArithmeticTerm, ArithmeticTerm),
|
NumberEqual(ArithmeticTerm, ArithmeticTerm),
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(ToDeriveInput, EnumDiscriminants)]
|
#[derive(ToDeriveInput, EnumDiscriminants)]
|
||||||
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
||||||
@@ -206,6 +208,7 @@ enum REPLCodePtr {
|
|||||||
AddNonCountedBacktracking,
|
AddNonCountedBacktracking,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[derive(ToDeriveInput, EnumDiscriminants)]
|
#[derive(ToDeriveInput, EnumDiscriminants)]
|
||||||
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
#[strum_discriminants(derive(EnumProperty, EnumString))]
|
||||||
@@ -897,13 +900,13 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ArithmeticTerm {
|
impl ArithmeticTerm {
|
||||||
fn into_functor(&self, arena: &mut Arena) -> MachineStub {
|
fn into_functor(self, arena: &mut Arena) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
ArithmeticTerm::Reg(r) => reg_type_into_functor(r),
|
||||||
&ArithmeticTerm::Interm(i) => {
|
ArithmeticTerm::Interm(i) => {
|
||||||
functor!(atom!("intermediate"), [fixnum(i)])
|
functor!(atom!("intermediate"), [fixnum(i)])
|
||||||
}
|
}
|
||||||
&ArithmeticTerm::Number(n) => {
|
ArithmeticTerm::Number(n) => {
|
||||||
vec![HeapCellValue::from((n, arena))]
|
vec![HeapCellValue::from((n, arena))]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -925,26 +928,17 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
impl NextOrFail {
|
impl NextOrFail {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_next(&self) -> bool {
|
pub fn is_next(&self) -> bool {
|
||||||
if let NextOrFail::Next(_) = self {
|
matches!(self, NextOrFail::Next(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(Debug, Default, Clone, Copy, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
pub enum Death {
|
pub enum Death {
|
||||||
Finite(usize),
|
Finite(usize),
|
||||||
|
#[default]
|
||||||
Infinity,
|
Infinity,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for Death {
|
|
||||||
fn default() -> Self {
|
|
||||||
Death::Infinity
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Clone, Copy, Debug)]
|
#[derive(Clone, Copy, Debug)]
|
||||||
pub enum IndexedChoiceInstruction {
|
pub enum IndexedChoiceInstruction {
|
||||||
Retry(usize),
|
Retry(usize),
|
||||||
@@ -956,30 +950,30 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
|
|
||||||
impl IndexedChoiceInstruction {
|
impl IndexedChoiceInstruction {
|
||||||
pub(crate) fn offset(&self) -> usize {
|
pub(crate) fn offset(&self) -> usize {
|
||||||
match self {
|
match *self {
|
||||||
&IndexedChoiceInstruction::Retry(offset) => offset,
|
IndexedChoiceInstruction::Retry(offset) => offset,
|
||||||
&IndexedChoiceInstruction::Trust(offset) => offset,
|
IndexedChoiceInstruction::Trust(offset) => offset,
|
||||||
&IndexedChoiceInstruction::Try(offset) => offset,
|
IndexedChoiceInstruction::Try(offset) => offset,
|
||||||
&IndexedChoiceInstruction::DefaultRetry(offset) => offset,
|
IndexedChoiceInstruction::DefaultRetry(offset) => offset,
|
||||||
&IndexedChoiceInstruction::DefaultTrust(offset) => offset,
|
IndexedChoiceInstruction::DefaultTrust(offset) => offset,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn to_functor(&self) -> MachineStub {
|
pub(crate) fn to_functor(self) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&IndexedChoiceInstruction::Try(offset) => {
|
IndexedChoiceInstruction::Try(offset) => {
|
||||||
functor!(atom!("try"), [fixnum(offset)])
|
functor!(atom!("try"), [fixnum(offset)])
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Trust(offset) => {
|
IndexedChoiceInstruction::Trust(offset) => {
|
||||||
functor!(atom!("trust"), [fixnum(offset)])
|
functor!(atom!("trust"), [fixnum(offset)])
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Retry(offset) => {
|
IndexedChoiceInstruction::Retry(offset) => {
|
||||||
functor!(atom!("retry"), [fixnum(offset)])
|
functor!(atom!("retry"), [fixnum(offset)])
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::DefaultTrust(offset) => {
|
IndexedChoiceInstruction::DefaultTrust(offset) => {
|
||||||
functor!(atom!("default_trust"), [fixnum(offset)])
|
functor!(atom!("default_trust"), [fixnum(offset)])
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::DefaultRetry(offset) => {
|
IndexedChoiceInstruction::DefaultRetry(offset) => {
|
||||||
functor!(atom!("default_retry"), [fixnum(offset)])
|
functor!(atom!("default_retry"), [fixnum(offset)])
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1038,7 +1032,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&IndexingInstruction::SwitchOnConstant(ref constants) => {
|
IndexingInstruction::SwitchOnConstant(constants) => {
|
||||||
let mut key_value_list_stub = vec![];
|
let mut key_value_list_stub = vec![];
|
||||||
let orig_h = h;
|
let orig_h = h;
|
||||||
|
|
||||||
@@ -1066,7 +1060,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
[key_value_list_stub]
|
[key_value_list_stub]
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
&IndexingInstruction::SwitchOnStructure(ref structures) => {
|
IndexingInstruction::SwitchOnStructure(structures) => {
|
||||||
let mut key_value_list_stub = vec![];
|
let mut key_value_list_stub = vec![];
|
||||||
let orig_h = h;
|
let orig_h = h;
|
||||||
|
|
||||||
@@ -1177,7 +1171,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_head_instr(&self) -> bool {
|
pub fn is_head_instr(&self) -> bool {
|
||||||
match self {
|
matches!(self,
|
||||||
Instruction::Deallocate |
|
Instruction::Deallocate |
|
||||||
Instruction::GetConstant(..) |
|
Instruction::GetConstant(..) |
|
||||||
Instruction::GetList(..) |
|
Instruction::GetList(..) |
|
||||||
@@ -1201,9 +1195,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
Instruction::SetLocalValue(..) |
|
Instruction::SetLocalValue(..) |
|
||||||
Instruction::SetVariable(..) |
|
Instruction::SetVariable(..) |
|
||||||
Instruction::SetValue(..) |
|
Instruction::SetValue(..) |
|
||||||
Instruction::SetVoid(..) => true,
|
Instruction::SetVoid(..))
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enqueue_functors(
|
pub fn enqueue_functors(
|
||||||
@@ -1213,7 +1205,7 @@ fn generate_instruction_preface() -> TokenStream {
|
|||||||
functors: &mut Vec<MachineStub>,
|
functors: &mut Vec<MachineStub>,
|
||||||
) {
|
) {
|
||||||
match self {
|
match self {
|
||||||
&Instruction::IndexingCode(ref indexing_instrs) => {
|
Instruction::IndexingCode(indexing_instrs) => {
|
||||||
for indexing_instr in indexing_instrs {
|
for indexing_instr in indexing_instrs {
|
||||||
match indexing_instr {
|
match indexing_instr {
|
||||||
IndexingLine::Indexing(indexing_instr) => {
|
IndexingLine::Indexing(indexing_instr) => {
|
||||||
@@ -2331,7 +2323,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
let mut is_inlined_arms = vec![];
|
let mut is_inlined_arms = vec![];
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(":-"), 1 | 2) => true
|
(atom!(":-"), 1 | 2)
|
||||||
});
|
});
|
||||||
|
|
||||||
for (name, arity, variant) in instr_data.compare_number_variants {
|
for (name, arity, variant) in instr_data.compare_number_variants {
|
||||||
@@ -2388,11 +2380,11 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
|
|
||||||
is_inlined_arms.push(quote! {
|
is_inlined_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2421,7 +2413,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2487,7 +2479,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2549,16 +2541,17 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
|
|
||||||
is_inlined_arms.push(quote! {
|
is_inlined_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
for (name, arity, variant) in instr_data.system_clause_type_variants {
|
for (name, arity, variant) in instr_data.system_clause_type_variants {
|
||||||
let ident = variant.ident.clone();
|
let ident = variant.ident.clone();
|
||||||
|
let ident_s = ident.to_string();
|
||||||
|
|
||||||
let variant_fields: Vec<_> = variant
|
let variant_fields: Vec<_> = variant
|
||||||
.fields
|
.fields
|
||||||
@@ -2574,19 +2567,13 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
.collect();
|
.collect();
|
||||||
|
|
||||||
clause_type_from_name_and_arity_arms.push(if !variant_fields.is_empty() {
|
clause_type_from_name_and_arity_arms.push(if !variant_fields.is_empty() {
|
||||||
if ident.to_string() == "SetCutPoint" {
|
if ident_s == "SetCutPoint" || ident_s == "SetCutPointByDefault" {
|
||||||
quote! {
|
quote! {
|
||||||
(atom!(#name), #arity) => ClauseType::System(
|
(atom!(#name), #arity) => ClauseType::System(
|
||||||
SystemClauseType::#ident(temp_v!(1))
|
SystemClauseType::#ident(temp_v!(1))
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
} else if ident.to_string() == "SetCutPointByDefault" {
|
} else if ident_s == "InlineCallN" {
|
||||||
quote! {
|
|
||||||
(atom!(#name), #arity) => ClauseType::System(
|
|
||||||
SystemClauseType::#ident(temp_v!(1))
|
|
||||||
)
|
|
||||||
}
|
|
||||||
} else if ident.to_string() == "InlineCallN" {
|
|
||||||
quote! {
|
quote! {
|
||||||
(atom!(#name), arity) => ClauseType::System(
|
(atom!(#name), arity) => ClauseType::System(
|
||||||
SystemClauseType::#ident(arity)
|
SystemClauseType::#ident(arity)
|
||||||
@@ -2649,11 +2636,11 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
|
|
||||||
is_inbuilt_arms.push(if let Arity::Ident("arity") = &arity {
|
is_inbuilt_arms.push(if let Arity::Ident("arity") = &arity {
|
||||||
quote! {
|
quote! {
|
||||||
(atom!(#name), _arity) => true
|
(atom!(#name), _)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2724,7 +2711,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), #arity) => true
|
(atom!(#name), #arity)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2798,7 +2785,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
});
|
});
|
||||||
|
|
||||||
is_inbuilt_arms.push(quote! {
|
is_inbuilt_arms.push(quote! {
|
||||||
(atom!(#name), _arity) => true
|
(atom!(#name), _)
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2819,8 +2806,8 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
let placeholder_ids: Vec<_> =
|
let placeholder_ids: Vec<_> =
|
||||||
(0..enum_arity).map(|n| format_ident!("f_{}", n)).collect();
|
(0..enum_arity).map(|n| format_ident!("f_{}", n)).collect();
|
||||||
|
|
||||||
if variant_string.starts_with("Call") {
|
if let Some(variant_suffix) = variant_string.strip_prefix("Call") {
|
||||||
let execute_ident = format_ident!("Execute{}", variant_string["Call".len()..]);
|
let execute_ident = format_ident!("Execute{}", variant_suffix);
|
||||||
|
|
||||||
Some(if enum_arity == 0 {
|
Some(if enum_arity == 0 {
|
||||||
quote! {
|
quote! {
|
||||||
@@ -2833,9 +2820,8 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
Instruction::#execute_ident(#(#placeholder_ids),*)
|
Instruction::#execute_ident(#(#placeholder_ids),*)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if variant_string.starts_with("DefaultCall") {
|
} else if let Some(variant_suffix) = variant_string.strip_prefix("DefaultCall") {
|
||||||
let execute_ident =
|
let execute_ident = format_ident!("DefaultExecute{}", variant_suffix);
|
||||||
format_ident!("DefaultExecute{}", variant_string["DefaultCall".len()..]);
|
|
||||||
|
|
||||||
Some(if enum_arity == 0 {
|
Some(if enum_arity == 0 {
|
||||||
quote! {
|
quote! {
|
||||||
@@ -2868,29 +2854,20 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
0
|
0
|
||||||
};
|
};
|
||||||
|
|
||||||
if variant_string.starts_with("Execute") {
|
if variant_string.starts_with("Execute") || variant_string.starts_with("DefaultExecute")
|
||||||
|
{
|
||||||
Some(if enum_arity == 0 {
|
Some(if enum_arity == 0 {
|
||||||
quote! {
|
quote! {
|
||||||
Instruction::#variant_ident => true
|
Instruction::#variant_ident
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
Instruction::#variant_ident(..) => true
|
Instruction::#variant_ident(..)
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if variant_string.starts_with("DefaultExecute") {
|
|
||||||
Some(if enum_arity == 0 {
|
|
||||||
quote! {
|
|
||||||
Instruction::#variant_ident => true
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
quote! {
|
|
||||||
Instruction::#variant_ident(..) => true
|
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
} else if variant_string == "JmpByExecute" {
|
} else if variant_string == "JmpByExecute" {
|
||||||
Some(quote! {
|
Some(quote! {
|
||||||
Instruction::#variant_ident(..) => true
|
Instruction::#variant_ident(..)
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -2955,11 +2932,11 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
|
|
||||||
Some(if enum_arity == 0 {
|
Some(if enum_arity == 0 {
|
||||||
quote! {
|
quote! {
|
||||||
Instruction::#variant_ident => true
|
Instruction::#variant_ident
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
quote! {
|
quote! {
|
||||||
Instruction::#variant_ident(..) => true
|
Instruction::#variant_ident(..)
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
@@ -2970,7 +2947,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
.iter()
|
.iter()
|
||||||
.rev() // produce default, execute & default & execute cases first.
|
.rev() // produce default, execute & default & execute cases first.
|
||||||
.cloned()
|
.cloned()
|
||||||
.filter_map(|(name, arity, _, variant)| {
|
.map(|(name, arity, _, variant)| {
|
||||||
let variant_ident = variant.ident.clone();
|
let variant_ident = variant.ident.clone();
|
||||||
let variant_string = variant.ident.to_string();
|
let variant_string = variant.ident.to_string();
|
||||||
let arity = match arity {
|
let arity = match arity {
|
||||||
@@ -2978,6 +2955,7 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
_ => 1,
|
_ => 1,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
#[allow(clippy::collapsible_else_if)]
|
||||||
Some(if variant_string.starts_with("Execute") {
|
Some(if variant_string.starts_with("Execute") {
|
||||||
if arity == 0 {
|
if arity == 0 {
|
||||||
quote! {
|
quote! {
|
||||||
@@ -3066,10 +3044,10 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
|
|
||||||
match arity {
|
match arity {
|
||||||
Arity::Static(_) if enum_arity == 0 => {
|
Arity::Static(_) if enum_arity == 0 => {
|
||||||
quote! { &Instruction::#ident => (atom!(#name), #arity) }
|
quote! { Instruction::#ident => (atom!(#name), #arity) }
|
||||||
}
|
}
|
||||||
Arity::Static(_) => {
|
Arity::Static(_) => {
|
||||||
quote! { &Instruction::#ident(..) => (atom!(#name), #arity) }
|
quote! { Instruction::#ident(..) => (atom!(#name), #arity) }
|
||||||
}
|
}
|
||||||
Arity::Ident(_) if enum_arity == 0 => {
|
Arity::Ident(_) if enum_arity == 0 => {
|
||||||
quote! { &Instruction::#ident(#arity) => (atom!(#name), #arity) }
|
quote! { &Instruction::#ident(#arity) => (atom!(#name), #arity) }
|
||||||
@@ -3169,12 +3147,9 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_inbuilt(name: Atom, arity: usize) -> bool {
|
pub fn is_inbuilt(name: Atom, arity: usize) -> bool {
|
||||||
match (name, arity) {
|
matches!((name, arity),
|
||||||
#(
|
#(#is_inbuilt_arms)|*
|
||||||
#is_inbuilt_arms,
|
)
|
||||||
)*
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn name(&self) -> Atom {
|
pub fn name(&self) -> Atom {
|
||||||
@@ -3186,12 +3161,9 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_inlined(name: Atom, arity: usize) -> bool {
|
pub fn is_inlined(name: Atom, arity: usize) -> bool {
|
||||||
match (name, arity) {
|
matches!((name, arity),
|
||||||
#(
|
#(#is_inlined_arms)|*
|
||||||
#is_inlined_arms,
|
)
|
||||||
)*
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3230,29 +3202,23 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_execute(&self) -> bool {
|
pub fn is_execute(&self) -> bool {
|
||||||
match self {
|
matches!(self,
|
||||||
#(
|
#(#is_execute_arms)|*
|
||||||
#is_execute_arms,
|
)
|
||||||
)*
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_ctrl_instr(&self) -> bool {
|
pub fn is_ctrl_instr(&self) -> bool {
|
||||||
match self {
|
matches!(self,
|
||||||
&Instruction::Allocate(_) |
|
Instruction::Allocate(_) |
|
||||||
&Instruction::Deallocate |
|
Instruction::Deallocate |
|
||||||
&Instruction::Proceed |
|
Instruction::Proceed |
|
||||||
&Instruction::RevJmpBy(_) => true,
|
Instruction::RevJmpBy(_) |
|
||||||
#(
|
#(#control_flow_arms)|*
|
||||||
#control_flow_arms,
|
)
|
||||||
)*
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn is_query_instr(&self) -> bool {
|
pub fn is_query_instr(&self) -> bool {
|
||||||
match self {
|
matches!(self,
|
||||||
&Instruction::GetVariable(..) |
|
&Instruction::GetVariable(..) |
|
||||||
&Instruction::PutConstant(..) |
|
&Instruction::PutConstant(..) |
|
||||||
&Instruction::PutList(..) |
|
&Instruction::PutList(..) |
|
||||||
@@ -3265,9 +3231,8 @@ pub fn generate_instructions_rs() -> TokenStream {
|
|||||||
&Instruction::SetLocalValue(..) |
|
&Instruction::SetLocalValue(..) |
|
||||||
&Instruction::SetVariable(..) |
|
&Instruction::SetVariable(..) |
|
||||||
&Instruction::SetValue(..) |
|
&Instruction::SetValue(..) |
|
||||||
&Instruction::SetVoid(..) => true,
|
&Instruction::SetVoid(..)
|
||||||
_ => false,
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -3335,7 +3300,8 @@ enum Arity {
|
|||||||
|
|
||||||
impl From<&'static str> for Arity {
|
impl From<&'static str> for Arity {
|
||||||
fn from(arity: &'static str) -> Self {
|
fn from(arity: &'static str) -> Self {
|
||||||
usize::from_str_radix(&arity, 10)
|
arity
|
||||||
|
.parse::<usize>()
|
||||||
.map(Arity::Static)
|
.map(Arity::Static)
|
||||||
.unwrap_or_else(|_| Arity::Ident(arity))
|
.unwrap_or_else(|_| Arity::Ident(arity))
|
||||||
}
|
}
|
||||||
@@ -3442,13 +3408,12 @@ impl InstructionData {
|
|||||||
panic!("type ID is: {}", id);
|
panic!("type ID is: {}", id);
|
||||||
};
|
};
|
||||||
|
|
||||||
let v_string = variant.ident.to_string();
|
let v_ident = variant
|
||||||
|
.ident
|
||||||
let v_ident = if v_string.starts_with("Call") {
|
.to_string()
|
||||||
format_ident!("{}", v_string["Call".len()..])
|
.strip_prefix("Call")
|
||||||
} else {
|
.map(|s| format_ident!("{}", s))
|
||||||
variant.ident.clone()
|
.unwrap_or_else(|| variant.ident.clone());
|
||||||
};
|
|
||||||
|
|
||||||
let generated_variant =
|
let generated_variant =
|
||||||
create_instr_variant(format_ident!("{}{}", prefix, v_ident), variant.clone());
|
create_instr_variant(format_ident!("{}{}", prefix, v_ident), variant.clone());
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ fn main() {
|
|||||||
let out_dir = env::var("OUT_DIR").unwrap();
|
let out_dir = env::var("OUT_DIR").unwrap();
|
||||||
let dest_path = Path::new(&out_dir).join("libraries.rs");
|
let dest_path = Path::new(&out_dir).join("libraries.rs");
|
||||||
|
|
||||||
let mut libraries = File::create(&dest_path).unwrap();
|
let mut libraries = File::create(dest_path).unwrap();
|
||||||
let lib_path = Path::new("src/lib");
|
let lib_path = Path::new("src/lib");
|
||||||
|
|
||||||
libraries
|
libraries
|
||||||
@@ -66,7 +66,7 @@ fn main() {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
find_prolog_files(&mut libraries, "", &lib_path);
|
find_prolog_files(&mut libraries, "", lib_path);
|
||||||
libraries.write_all(b"\n m\n };\n}\n").unwrap();
|
libraries.write_all(b"\n m\n };\n}\n").unwrap();
|
||||||
|
|
||||||
let instructions_path = Path::new(&out_dir).join("instructions.rs");
|
let instructions_path = Path::new(&out_dir).join("instructions.rs");
|
||||||
|
|||||||
@@ -35,7 +35,7 @@ impl Parse for ReadHeapCellExprAndArms {
|
|||||||
arms.push(input.parse()?);
|
arms.push(input.parse()?);
|
||||||
|
|
||||||
while !input.is_empty() {
|
while !input.is_empty() {
|
||||||
if let Ok(_) = input.parse::<Token![,]>() {}
|
let _ = input.parse::<Token![,]>();
|
||||||
arms.push(input.parse()?);
|
arms.push(input.parse()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ impl Parse for MacroFnArgs {
|
|||||||
}
|
}
|
||||||
|
|
||||||
while !input.is_empty() {
|
while !input.is_empty() {
|
||||||
if let Ok(_) = input.parse::<Token![,]>() {}
|
let _ = input.parse::<Token![,]>();
|
||||||
args.push(input.parse()?);
|
args.push(input.parse()?);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -65,22 +65,20 @@ impl<'ast> Visit<'ast> for StaticStrVisitor {
|
|||||||
let Macro { path, .. } = m;
|
let Macro { path, .. } = m;
|
||||||
|
|
||||||
if path.is_ident("atom") {
|
if path.is_ident("atom") {
|
||||||
if let Some(Lit::Str(string)) = m.parse_body::<Lit>().ok() {
|
if let Ok(Lit::Str(string)) = m.parse_body::<Lit>() {
|
||||||
self.static_strs.insert(string.value());
|
self.static_strs.insert(string.value());
|
||||||
}
|
}
|
||||||
} else if path.is_ident("read_heap_cell") || path.is_ident("match_untyped_arena_ptr") {
|
} else if path.is_ident("read_heap_cell") || path.is_ident("match_untyped_arena_ptr") {
|
||||||
if let Some(m) = m.parse_body::<ReadHeapCellExprAndArms>().ok() {
|
if let Ok(m) = m.parse_body::<ReadHeapCellExprAndArms>() {
|
||||||
self.visit_expr(&m.expr);
|
self.visit_expr(&m.expr);
|
||||||
|
|
||||||
for e in m.arms {
|
for e in m.arms {
|
||||||
self.visit_arm(&e);
|
self.visit_arm(&e);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if let Ok(m) = m.parse_body::<MacroFnArgs>() {
|
||||||
if let Some(m) = m.parse_body::<MacroFnArgs>().ok() {
|
for e in m.args {
|
||||||
for e in m.args {
|
self.visit_expr(&e);
|
||||||
self.visit_expr(&e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -147,9 +145,8 @@ pub fn index_static_strings(instruction_rs_path: &std::path::Path) -> TokenStrea
|
|||||||
visitor.visit_file(&syntax);
|
visitor.visit_file(&syntax);
|
||||||
}
|
}
|
||||||
|
|
||||||
match process_filepath(instruction_rs_path) {
|
if let Ok(syntax) = process_filepath(instruction_rs_path) {
|
||||||
Ok(syntax) => visitor.visit_file(&syntax),
|
visitor.visit_file(&syntax)
|
||||||
Err(_) => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let indices = (0..visitor.static_strs.len()).map(|i| (i << 3) as u64);
|
let indices = (0..visitor.static_strs.len()).map(|i| (i << 3) as u64);
|
||||||
@@ -161,7 +158,7 @@ pub fn index_static_strings(instruction_rs_path: &std::path::Path) -> TokenStrea
|
|||||||
quote! {
|
quote! {
|
||||||
use phf;
|
use phf;
|
||||||
|
|
||||||
static STRINGS: [&'static str; #static_strs_len] = [
|
static STRINGS: [&str; #static_strs_len] = [
|
||||||
#(
|
#(
|
||||||
#static_strs,
|
#static_strs,
|
||||||
)*
|
)*
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ pub(crate) trait Allocator {
|
|||||||
code: &mut CodeDeque,
|
code: &mut CodeDeque,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
|
fn mark_reserved_var<'a, Target: CompilationTarget<'a>>(
|
||||||
&mut self,
|
&mut self,
|
||||||
var_num: usize,
|
var_num: usize,
|
||||||
@@ -48,7 +49,7 @@ pub(crate) trait Allocator {
|
|||||||
|
|
||||||
fn reset(&mut self);
|
fn reset(&mut self);
|
||||||
fn reset_arg(&mut self, arg_num: usize);
|
fn reset_arg(&mut self, arg_num: usize);
|
||||||
fn reset_at_head(&mut self, args: &Vec<Term>);
|
fn reset_at_head(&mut self, args: &[Term]);
|
||||||
fn reset_contents(&mut self);
|
fn reset_contents(&mut self);
|
||||||
|
|
||||||
fn advance_arg(&mut self);
|
fn advance_arg(&mut self);
|
||||||
|
|||||||
108
src/arena.rs
108
src/arena.rs
@@ -91,14 +91,14 @@ pub fn lookup_float(
|
|||||||
) -> RcuRef<RawBlock<F64Table>, UnsafeCell<OrderedFloat<f64>>> {
|
) -> RcuRef<RawBlock<F64Table>, UnsafeCell<OrderedFloat<f64>>> {
|
||||||
let f64table = global_f64table()
|
let f64table = global_f64table()
|
||||||
.read()
|
.read()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.upgrade()
|
.upgrade()
|
||||||
.expect("We should only be looking up floats while there is a float table");
|
.expect("We should only be looking up floats while there is a float table");
|
||||||
|
|
||||||
RcuRef::try_map(f64table.block.active_epoch(), |raw_block| unsafe {
|
RcuRef::try_map(f64table.block.active_epoch(), |raw_block| unsafe {
|
||||||
raw_block
|
raw_block
|
||||||
.base
|
.base
|
||||||
.offset(offset.0 as isize)
|
.add(offset.0)
|
||||||
.cast_mut()
|
.cast_mut()
|
||||||
.cast::<UnsafeCell<OrderedFloat<f64>>>()
|
.cast::<UnsafeCell<OrderedFloat<f64>>>()
|
||||||
.as_ref()
|
.as_ref()
|
||||||
@@ -129,6 +129,7 @@ impl F64Table {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_safety_doc)]
|
||||||
pub unsafe fn build_with(&self, value: f64) -> F64Offset {
|
pub unsafe fn build_with(&self, value: f64) -> F64Offset {
|
||||||
let update_guard = self.update.lock();
|
let update_guard = self.update.lock();
|
||||||
|
|
||||||
@@ -152,9 +153,7 @@ impl F64Table {
|
|||||||
|
|
||||||
ptr::write(ptr as *mut OrderedFloat<f64>, OrderedFloat(value));
|
ptr::write(ptr as *mut OrderedFloat<f64>, OrderedFloat(value));
|
||||||
|
|
||||||
let float = F64Offset {
|
let float = F64Offset(ptr as usize - block_epoch.base as usize);
|
||||||
0: ptr as usize - block_epoch.base as usize,
|
|
||||||
};
|
|
||||||
|
|
||||||
// atometable would have to update the index table at this point
|
// atometable would have to update the index table at this point
|
||||||
|
|
||||||
@@ -230,7 +229,7 @@ impl<T: ?Sized + PartialOrd> PartialOrd for TypedArenaPtr<T> {
|
|||||||
|
|
||||||
impl<T: ?Sized + PartialEq> PartialEq for TypedArenaPtr<T> {
|
impl<T: ?Sized + PartialEq> PartialEq for TypedArenaPtr<T> {
|
||||||
fn eq(&self, other: &TypedArenaPtr<T>) -> bool {
|
fn eq(&self, other: &TypedArenaPtr<T>) -> bool {
|
||||||
self.0 == other.0 || &**self == &**other
|
self.0 == other.0 || **self == **other
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -245,13 +244,13 @@ impl<T: ?Sized + Ord> Ord for TypedArenaPtr<T> {
|
|||||||
impl<T: ?Sized + Hash> Hash for TypedArenaPtr<T> {
|
impl<T: ?Sized + Hash> Hash for TypedArenaPtr<T> {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||||
(&*self as &T).hash(hasher)
|
(self as &T).hash(hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T: ?Sized> Clone for TypedArenaPtr<T> {
|
impl<T: ?Sized> Clone for TypedArenaPtr<T> {
|
||||||
fn clone(&self) -> Self {
|
fn clone(&self) -> Self {
|
||||||
TypedArenaPtr(self.0)
|
*self
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -279,10 +278,10 @@ impl<T: fmt::Display> fmt::Display for TypedArenaPtr<T> {
|
|||||||
|
|
||||||
impl<T: ?Sized + ArenaAllocated> TypedArenaPtr<T> {
|
impl<T: ?Sized + ArenaAllocated> TypedArenaPtr<T> {
|
||||||
// data must be allocated in the arena already.
|
// data must be allocated in the arena already.
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub const fn new(data: *mut T) -> Self {
|
pub const fn new(data: *mut T) -> Self {
|
||||||
let result = unsafe { TypedArenaPtr(ptr::NonNull::new_unchecked(data)) };
|
unsafe { TypedArenaPtr(ptr::NonNull::new_unchecked(data)) }
|
||||||
result
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -347,6 +346,7 @@ pub trait ArenaAllocated: Sized {
|
|||||||
mem::size_of::<ArenaHeader>()
|
mem::size_of::<ArenaHeader>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::missing_safety_doc)]
|
||||||
unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
|
unsafe fn alloc(arena: &mut Arena, value: Self) -> Self::PtrToAllocated {
|
||||||
let size = value.size() + mem::size_of::<AllocSlab>();
|
let size = value.size() + mem::size_of::<AllocSlab>();
|
||||||
|
|
||||||
@@ -363,7 +363,7 @@ pub trait ArenaAllocated: Sized {
|
|||||||
(*slab).header = ArenaHeader::build_with(value.size() as u64, Self::tag());
|
(*slab).header = ArenaHeader::build_with(value.size() as u64, Self::tag());
|
||||||
|
|
||||||
let offset = (*slab).payload_offset();
|
let offset = (*slab).payload_offset();
|
||||||
let result = value.copy_to_arena(offset as *mut Self);
|
let result = value.copy_to_arena(offset);
|
||||||
|
|
||||||
arena.base = slab;
|
arena.base = slab;
|
||||||
|
|
||||||
@@ -390,7 +390,7 @@ impl Eq for F64Ptr {}
|
|||||||
|
|
||||||
impl PartialOrd for F64Ptr {
|
impl PartialOrd for F64Ptr {
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
(**self).partial_cmp(&**other)
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -403,13 +403,13 @@ impl Ord for F64Ptr {
|
|||||||
impl Hash for F64Ptr {
|
impl Hash for F64Ptr {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
fn hash<H: Hasher>(&self, hasher: &mut H) {
|
||||||
(&*self as &OrderedFloat<f64>).hash(hasher)
|
(self as &OrderedFloat<f64>).hash(hasher)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl fmt::Display for F64Ptr {
|
impl fmt::Display for F64Ptr {
|
||||||
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
||||||
write!(f, "{}", *self)
|
write!(f, "{}", self as &OrderedFloat<f64>)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -418,7 +418,7 @@ impl Deref for F64Ptr {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
unsafe { &*self.0.get().as_ref().unwrap() }
|
unsafe { self.0.get().as_ref().unwrap() }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -478,7 +478,7 @@ impl Eq for F64Offset {}
|
|||||||
impl PartialOrd for F64Offset {
|
impl PartialOrd for F64Offset {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
|
||||||
self.as_ptr().partial_cmp(&other.as_ptr())
|
Some(self.cmp(other))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -515,11 +515,12 @@ impl ArenaAllocated for Integer {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -537,11 +538,12 @@ impl ArenaAllocated for Rational {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -559,11 +561,12 @@ impl ArenaAllocated for LiveLoadState {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -581,11 +584,12 @@ impl ArenaAllocated for TcpListener {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -604,11 +608,12 @@ impl ArenaAllocated for HttpListener {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -627,11 +632,12 @@ impl ArenaAllocated for HttpResponse {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -649,11 +655,12 @@ impl ArenaAllocated for IndexPtr {
|
|||||||
mem::size_of::<Self>()
|
mem::size_of::<Self>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
ptr::write(dst, self);
|
ptr::write(dst, self);
|
||||||
TypedArenaPtr::new(dst as *mut Self)
|
TypedArenaPtr::new(dst)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -672,7 +679,10 @@ impl ArenaAllocated for IndexPtr {
|
|||||||
|
|
||||||
(*slab).next = arena.base;
|
(*slab).next = arena.base;
|
||||||
|
|
||||||
let result = value.copy_to_arena(mem::transmute::<_, *mut IndexPtr>(&(*slab).header));
|
let result = value.copy_to_arena(
|
||||||
|
&(*slab).header as *const crate::arena::ArenaHeader
|
||||||
|
as *mut crate::machine::machine_indices::IndexPtr,
|
||||||
|
);
|
||||||
arena.base = slab;
|
arena.base = slab;
|
||||||
|
|
||||||
result
|
result
|
||||||
@@ -697,6 +707,7 @@ pub struct Arena {
|
|||||||
unsafe impl Send for Arena {}
|
unsafe impl Send for Arena {}
|
||||||
unsafe impl Sync for Arena {}
|
unsafe impl Sync for Arena {}
|
||||||
|
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
impl Arena {
|
impl Arena {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
@@ -837,12 +848,12 @@ mod tests {
|
|||||||
let mut cell = HeapCellValue::from(fp.clone());
|
let mut cell = HeapCellValue::from(fp.clone());
|
||||||
|
|
||||||
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
|
assert_eq!(cell.get_tag(), HeapCellValueTag::F64);
|
||||||
assert_eq!(cell.get_mark_bit(), false);
|
assert!(!cell.get_mark_bit());
|
||||||
assert_eq!(fp.deref(), &OrderedFloat(f));
|
assert_eq!(fp.deref(), &OrderedFloat(f));
|
||||||
|
|
||||||
cell.set_mark_bit(true);
|
cell.set_mark_bit(true);
|
||||||
|
|
||||||
assert_eq!(cell.get_mark_bit(), true);
|
assert!(cell.get_mark_bit());
|
||||||
|
|
||||||
read_heap_cell!(cell,
|
read_heap_cell!(cell,
|
||||||
(HeapCellValueTag::F64, ptr) => {
|
(HeapCellValueTag::F64, ptr) => {
|
||||||
@@ -874,7 +885,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -890,7 +901,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -912,7 +923,6 @@ mod tests {
|
|||||||
let untyped_arena_ptr = match cell.to_untyped_arena_ptr() {
|
let untyped_arena_ptr = match cell.to_untyped_arena_ptr() {
|
||||||
Some(ptr) => ptr,
|
Some(ptr) => ptr,
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -954,7 +964,7 @@ mod tests {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false); // we fail.
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -991,7 +1001,7 @@ mod tests {
|
|||||||
assert_eq!(&*atom.as_str(), "f");
|
assert_eq!(&*atom.as_str(), "f");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1026,7 +1036,7 @@ mod tests {
|
|||||||
assert_eq!(&*pstr.as_str_from(0), "ronan");
|
assert_eq!(&*pstr.as_str_from(0), "ronan");
|
||||||
}
|
}
|
||||||
None => {
|
None => {
|
||||||
assert!(false);
|
unreachable!();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1046,7 +1056,7 @@ mod tests {
|
|||||||
|
|
||||||
match fixnum_cell.to_fixnum() {
|
match fixnum_cell.to_fixnum() {
|
||||||
Some(n) => assert_eq!(n.get_num(), 3),
|
Some(n) => assert_eq!(n.get_num(), 3),
|
||||||
None => assert!(false),
|
None => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
read_heap_cell!(fixnum_cell,
|
read_heap_cell!(fixnum_cell,
|
||||||
@@ -1062,52 +1072,48 @@ mod tests {
|
|||||||
|
|
||||||
match fixnum_b_cell.to_fixnum() {
|
match fixnum_b_cell.to_fixnum() {
|
||||||
Some(n) => assert_eq!(n.get_num(), 1 << 54),
|
Some(n) => assert_eq!(n.get_num(), 1 << 54),
|
||||||
None => assert!(false),
|
None => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(1 << 56) {
|
if Fixnum::build_with_checked(1 << 56).is_ok() {
|
||||||
Ok(_) => assert!(false),
|
unreachable!()
|
||||||
_ => assert!(true),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(i64::MAX) {
|
if Fixnum::build_with_checked(i64::MAX).is_ok() {
|
||||||
Ok(_) => assert!(false),
|
unreachable!()
|
||||||
_ => assert!(true),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(i64::MIN) {
|
if Fixnum::build_with_checked(i64::MIN).is_ok() {
|
||||||
Ok(_) => assert!(false),
|
unreachable!()
|
||||||
_ => assert!(true),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(-1) {
|
match Fixnum::build_with_checked(-1) {
|
||||||
Ok(n) => assert_eq!(n.get_num(), -1),
|
Ok(n) => assert_eq!(n.get_num(), -1),
|
||||||
_ => assert!(false),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked((1 << 55) - 1) {
|
match Fixnum::build_with_checked((1 << 55) - 1) {
|
||||||
Ok(n) => assert_eq!(n.get_num(), (1 << 55) - 1),
|
Ok(n) => assert_eq!(n.get_num(), (1 << 55) - 1),
|
||||||
_ => assert!(false),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(-(1 << 55)) {
|
match Fixnum::build_with_checked(-(1 << 55)) {
|
||||||
Ok(n) => assert_eq!(n.get_num(), -(1 << 55)),
|
Ok(n) => assert_eq!(n.get_num(), -(1 << 55)),
|
||||||
_ => assert!(false),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(-(1 << 55) - 1) {
|
if Fixnum::build_with_checked(-(1 << 55) - 1).is_ok() {
|
||||||
Ok(_n) => assert!(false),
|
unreachable!()
|
||||||
_ => assert!(true),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match Fixnum::build_with_checked(-1) {
|
match Fixnum::build_with_checked(-1) {
|
||||||
Ok(n) => assert_eq!(-n, Fixnum::build_with(1)),
|
Ok(n) => assert_eq!(-n, Fixnum::build_with(1)),
|
||||||
_ => assert!(false),
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
|
|
||||||
// float
|
// float
|
||||||
|
|
||||||
let float = 3.1415926f64;
|
let float = std::f64::consts::PI;
|
||||||
let float_ptr = float_alloc!(float, wam.machine_st.arena);
|
let float_ptr = float_alloc!(float, wam.machine_st.arena);
|
||||||
let cell = HeapCellValue::from(float_ptr);
|
let cell = HeapCellValue::from(float_ptr);
|
||||||
|
|
||||||
|
|||||||
@@ -268,7 +268,7 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
let ninterm = if a1.interm_or(0) == 0 {
|
let ninterm = if a1.interm_or(0) == 0 {
|
||||||
self.incr_interm()
|
self.incr_interm()
|
||||||
} else {
|
} else {
|
||||||
self.interm.push(a1.clone());
|
self.interm.push(a1);
|
||||||
a1.interm_or(0)
|
a1.interm_or(0)
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -312,9 +312,8 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
arg: usize,
|
arg: usize,
|
||||||
) -> Result<ArithCont, ArithmeticError> {
|
) -> Result<ArithCont, ArithmeticError> {
|
||||||
let mut code = CodeDeque::new();
|
let mut code = CodeDeque::new();
|
||||||
let mut iter = src.iter()?;
|
|
||||||
|
|
||||||
while let Some(term_ref) = iter.next() {
|
for term_ref in src.iter()? {
|
||||||
match term_ref? {
|
match term_ref? {
|
||||||
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
|
ArithTermRef::Literal(c) => push_literal(&mut self.interm, c)?,
|
||||||
ArithTermRef::Var(lvl, cell, name) => {
|
ArithTermRef::Var(lvl, cell, name) => {
|
||||||
@@ -353,17 +352,17 @@ impl<'a> ArithmeticEvaluator<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// integer division rounding function -- 9.1.3.1.
|
// integer division rounding function -- 9.1.3.1.
|
||||||
pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
|
pub(crate) fn rnd_i(n: &'_ Number, arena: &mut Arena) -> Number {
|
||||||
match n {
|
match n {
|
||||||
&Number::Integer(i) => {
|
&Number::Integer(i) => {
|
||||||
let result = (&*i).try_into();
|
let result = (&*i).try_into();
|
||||||
if let Ok(value) = result{
|
if let Ok(value) = result {
|
||||||
fixnum!(Number, value, arena)
|
fixnum!(Number, value, arena)
|
||||||
} else {
|
} else {
|
||||||
*n
|
*n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Number::Fixnum(_) => *n,
|
Number::Fixnum(_) => *n,
|
||||||
&Number::Float(f) => {
|
&Number::Float(f) => {
|
||||||
let f = f.floor();
|
let f = f.floor();
|
||||||
|
|
||||||
@@ -376,7 +375,7 @@ pub(crate) fn rnd_i<'a>(n: &'a Number, arena: &mut Arena) -> Number {
|
|||||||
Number::Integer(arena_alloc!(Integer::from(f.0 as i64), arena))
|
Number::Integer(arena_alloc!(Integer::from(f.0 as i64), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Number::Rational(ref r) => {
|
Number::Rational(ref r) => {
|
||||||
let (_, floor) = (r.fract(), r.floor());
|
let (_, floor) = (r.fract(), r.floor());
|
||||||
|
|
||||||
if let Ok(value) = (&floor).try_into() {
|
if let Ok(value) = (&floor).try_into() {
|
||||||
@@ -399,9 +398,9 @@ impl From<Fixnum> for Integer {
|
|||||||
pub(crate) fn rnd_f(n: &Number) -> f64 {
|
pub(crate) fn rnd_f(n: &Number) -> f64 {
|
||||||
match n {
|
match n {
|
||||||
&Number::Fixnum(n) => n.get_num() as f64,
|
&Number::Fixnum(n) => n.get_num() as f64,
|
||||||
&Number::Integer(ref n) => n.to_f64().value(),
|
Number::Integer(ref n) => n.to_f64().value(),
|
||||||
&Number::Float(OrderedFloat(f)) => f,
|
&Number::Float(OrderedFloat(f)) => f,
|
||||||
&Number::Rational(ref r) => r.to_f64().value(),
|
Number::Rational(ref r) => r.to_f64().value(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -529,47 +528,51 @@ impl PartialEq for Number {
|
|||||||
fn eq(&self, rhs: &Self) -> bool {
|
fn eq(&self, rhs: &Self) -> bool {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2),
|
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.eq(&n2),
|
||||||
(&Number::Fixnum(n1), &Number::Integer(ref n2)) => n1.get_num().num_eq(&**n2),
|
(&Number::Fixnum(n1), Number::Integer(ref n2)) => n1.get_num().num_eq(&**n2),
|
||||||
(&Number::Integer(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&n2.get_num()),
|
(Number::Integer(ref n1), &Number::Fixnum(n2)) => n1.num_eq(&n2.get_num()),
|
||||||
(&Number::Fixnum(n1), &Number::Rational(ref n2)) => Integer::from(n1.get_num()).num_eq(&**n2),
|
(&Number::Fixnum(n1), Number::Rational(ref n2)) => {
|
||||||
(&Number::Rational(ref n1), &Number::Fixnum(n2)) => (&**n1).num_eq(&Integer::from(n2.get_num())),
|
Integer::from(n1.get_num()).num_eq(&**n2)
|
||||||
|
}
|
||||||
|
(Number::Rational(ref n1), &Number::Fixnum(n2)) => {
|
||||||
|
n1.num_eq(&Integer::from(n2.get_num()))
|
||||||
|
}
|
||||||
(&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).eq(&n2),
|
(&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).eq(&n2),
|
||||||
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.eq(&OrderedFloat(n2.get_num() as f64)),
|
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.eq(&OrderedFloat(n2.get_num() as f64)),
|
||||||
(&Number::Integer(ref n1), &Number::Integer(ref n2)) => n1.eq(n2),
|
(Number::Integer(ref n1), Number::Integer(ref n2)) => n1.eq(n2),
|
||||||
(&Number::Integer(ref n1), Number::Float(n2)) => {
|
(Number::Integer(ref n1), Number::Float(n2)) => {
|
||||||
OrderedFloat(n1.to_f64().value()).eq(n2)
|
OrderedFloat(n1.to_f64().value()).eq(n2)
|
||||||
}
|
}
|
||||||
(&Number::Float(n1), &Number::Integer(ref n2)) => {
|
(&Number::Float(n1), Number::Integer(ref n2)) => {
|
||||||
n1.eq(&OrderedFloat(n2.to_f64().value()))
|
n1.eq(&OrderedFloat(n2.to_f64().value()))
|
||||||
}
|
}
|
||||||
(&Number::Integer(ref n1), &Number::Rational(ref n2)) => {
|
(Number::Integer(ref n1), Number::Rational(ref n2)) => {
|
||||||
#[cfg(feature = "num")]
|
#[cfg(feature = "num")]
|
||||||
{
|
{
|
||||||
&Rational::from(&**n1) == &**n2
|
&Rational::from(&**n1) == &**n2
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "num"))]
|
#[cfg(not(feature = "num"))]
|
||||||
{
|
{
|
||||||
(&**n1).num_eq(&**n2)
|
n1.num_eq(&**n2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&Number::Rational(ref n1), &Number::Integer(ref n2)) => {
|
(Number::Rational(ref n1), Number::Integer(ref n2)) => {
|
||||||
#[cfg(feature = "num")]
|
#[cfg(feature = "num")]
|
||||||
{
|
{
|
||||||
&**n1 == &Rational::from(&**n2)
|
n1 == &Rational::from(&**n2)
|
||||||
}
|
}
|
||||||
#[cfg(not(feature = "num"))]
|
#[cfg(not(feature = "num"))]
|
||||||
{
|
{
|
||||||
(&**n1).num_eq(&**n2)
|
n1.num_eq(&**n2)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&Number::Rational(ref n1), &Number::Float(n2)) => {
|
(Number::Rational(ref n1), &Number::Float(n2)) => {
|
||||||
OrderedFloat(n1.to_f64().value()).eq(&n2)
|
OrderedFloat(n1.to_f64().value()).eq(&n2)
|
||||||
}
|
}
|
||||||
(&Number::Float(n1), &Number::Rational(ref n2)) => {
|
(&Number::Float(n1), Number::Rational(ref n2)) => {
|
||||||
n1.eq(&OrderedFloat(n2.to_f64().value()))
|
n1.eq(&OrderedFloat(n2.to_f64().value()))
|
||||||
}
|
}
|
||||||
(&Number::Float(f1), &Number::Float(f2)) => f1.eq(&f2),
|
(&Number::Float(f1), &Number::Float(f2)) => f1.eq(&f2),
|
||||||
(&Number::Rational(ref r1), &Number::Rational(ref r2)) => r1.eq(&r2),
|
(Number::Rational(ref r1), Number::Rational(ref r2)) => r1.eq(r2),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -589,8 +592,8 @@ impl PartialOrd<usize> for Number {
|
|||||||
(n as usize).partial_cmp(rhs)
|
(n as usize).partial_cmp(rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Number::Integer(n) => Some((&**n).num_cmp(rhs)),
|
Number::Integer(n) => Some((n).num_cmp(rhs)),
|
||||||
Number::Rational(r) => Some((&**r).num_cmp(&Integer::from(*rhs))),
|
Number::Rational(r) => Some((r).num_cmp(&Integer::from(*rhs))),
|
||||||
Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)),
|
Number::Float(f) => f.partial_cmp(&OrderedFloat(*rhs as f64)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -609,8 +612,8 @@ impl PartialEq<usize> for Number {
|
|||||||
(n as usize).eq(rhs)
|
(n as usize).eq(rhs)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Number::Integer(n) => (&**n).num_eq(rhs),
|
Number::Integer(n) => (n).num_eq(rhs),
|
||||||
Number::Rational(r) => (&**r).num_eq(&Integer::from(*rhs)),
|
Number::Rational(r) => (r).num_eq(&Integer::from(*rhs)),
|
||||||
Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)),
|
Number::Float(f) => f.eq(&OrderedFloat(*rhs as f64)),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -626,17 +629,17 @@ impl Ord for Number {
|
|||||||
fn cmp(&self, rhs: &Number) -> Ordering {
|
fn cmp(&self, rhs: &Number) -> Ordering {
|
||||||
match (self, rhs) {
|
match (self, rhs) {
|
||||||
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.get_num().cmp(&n2.get_num()),
|
(&Number::Fixnum(n1), &Number::Fixnum(n2)) => n1.get_num().cmp(&n2.get_num()),
|
||||||
(&Number::Fixnum(n1), Number::Integer(n2)) => Integer::from(n1.get_num()).cmp(&*n2),
|
(&Number::Fixnum(n1), Number::Integer(n2)) => Integer::from(n1.get_num()).cmp(n2),
|
||||||
(Number::Integer(n1), &Number::Fixnum(n2)) => (&**n1).cmp(&Integer::from(n2.get_num())),
|
(Number::Integer(n1), &Number::Fixnum(n2)) => (**n1).cmp(&Integer::from(n2.get_num())),
|
||||||
(&Number::Fixnum(n1), Number::Rational(n2)) => Rational::from(n1.get_num()).cmp(&*n2),
|
(&Number::Fixnum(n1), Number::Rational(n2)) => Rational::from(n1.get_num()).cmp(n2),
|
||||||
(Number::Rational(n1), &Number::Fixnum(n2)) => {
|
(Number::Rational(n1), &Number::Fixnum(n2)) => {
|
||||||
(&**n1).cmp(&Rational::from(n2.get_num()))
|
(**n1).cmp(&Rational::from(n2.get_num()))
|
||||||
}
|
}
|
||||||
(&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).cmp(&n2),
|
(&Number::Fixnum(n1), &Number::Float(n2)) => OrderedFloat(n1.get_num() as f64).cmp(&n2),
|
||||||
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.cmp(&OrderedFloat(n2.get_num() as f64)),
|
(&Number::Float(n1), &Number::Fixnum(n2)) => n1.cmp(&OrderedFloat(n2.get_num() as f64)),
|
||||||
(&Number::Integer(n1), &Number::Integer(n2)) => (*n1).cmp(&*n2),
|
(&Number::Integer(n1), &Number::Integer(n2)) => (*n1).cmp(&*n2),
|
||||||
(&Number::Integer(n1), Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).cmp(n2),
|
(&Number::Integer(n1), Number::Float(n2)) => OrderedFloat(n1.to_f64().value()).cmp(n2),
|
||||||
(&Number::Float(n1), &Number::Integer(ref n2)) => {
|
(&Number::Float(n1), Number::Integer(ref n2)) => {
|
||||||
n1.cmp(&OrderedFloat(n2.to_f64().value()))
|
n1.cmp(&OrderedFloat(n2.to_f64().value()))
|
||||||
}
|
}
|
||||||
(&Number::Integer(n1), &Number::Rational(n2)) => {
|
(&Number::Integer(n1), &Number::Rational(n2)) => {
|
||||||
@@ -646,7 +649,7 @@ impl Ord for Number {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "num"))]
|
#[cfg(not(feature = "num"))]
|
||||||
{
|
{
|
||||||
(&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
|
(*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&Number::Rational(n1), &Number::Integer(n2)) => {
|
(&Number::Rational(n1), &Number::Integer(n2)) => {
|
||||||
@@ -656,7 +659,7 @@ impl Ord for Number {
|
|||||||
}
|
}
|
||||||
#[cfg(not(feature = "num"))]
|
#[cfg(not(feature = "num"))]
|
||||||
{
|
{
|
||||||
(&*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
|
(*n1).num_partial_cmp(&*n2).unwrap_or(Ordering::Less)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(&Number::Rational(n1), &Number::Float(n2)) => {
|
(&Number::Rational(n1), &Number::Float(n2)) => {
|
||||||
|
|||||||
@@ -186,7 +186,7 @@ impl Atom {
|
|||||||
unsafe {
|
unsafe {
|
||||||
AtomTableRef::try_map(atom_table.buf(), |buf| {
|
AtomTableRef::try_map(atom_table.buf(), |buf| {
|
||||||
(buf as *const u8)
|
(buf as *const u8)
|
||||||
.offset(((self.index as usize) - (STRINGS.len() << 3)) as isize)
|
.add((self.index as usize) - (STRINGS.len() << 3))
|
||||||
.as_ref()
|
.as_ref()
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
@@ -209,9 +209,13 @@ impl Atom {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn is_empty(self) -> bool {
|
||||||
|
self.len() == 0
|
||||||
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn flat_index(self) -> u64 {
|
pub fn flat_index(self) -> u64 {
|
||||||
(self.index >> 3) as u64
|
self.index >> 3
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_char(self) -> Option<char> {
|
pub fn as_char(self) -> Option<char> {
|
||||||
@@ -232,20 +236,17 @@ impl Atom {
|
|||||||
pub fn as_str(&self) -> AtomString<'static> {
|
pub fn as_str(&self) -> AtomString<'static> {
|
||||||
if self.is_static() {
|
if self.is_static() {
|
||||||
AtomString::Static(STRINGS[(self.index >> 3) as usize])
|
AtomString::Static(STRINGS[(self.index >> 3) as usize])
|
||||||
} else {
|
} else if let Some(ptr) = self.as_ptr() {
|
||||||
if let Some(ptr) = self.as_ptr() {
|
AtomString::Dynamic(AtomTableRef::map(ptr, |ptr| {
|
||||||
AtomString::Dynamic(AtomTableRef::map(ptr, |ptr| {
|
let header =
|
||||||
let header =
|
unsafe { ptr::read::<AtomHeader>(ptr as *const u8 as *const AtomHeader) };
|
||||||
unsafe { ptr::read::<AtomHeader>(ptr as *const u8 as *const AtomHeader) };
|
let len = header.len() as usize;
|
||||||
let len = header.len() as usize;
|
let buf = unsafe { (ptr as *const u8).add(mem::size_of::<AtomHeader>()) };
|
||||||
let buf =
|
|
||||||
unsafe { (ptr as *const u8).offset(mem::size_of::<AtomHeader>() as isize) };
|
|
||||||
|
|
||||||
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(buf, len)) }
|
unsafe { str::from_utf8_unchecked(slice::from_raw_parts(buf, len)) }
|
||||||
}))
|
}))
|
||||||
} else {
|
} else {
|
||||||
AtomString::Static(&STRINGS[(self.index >> 3) as usize])
|
AtomString::Static(STRINGS[(self.index >> 3) as usize])
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -258,14 +259,14 @@ impl Atom {
|
|||||||
return *self;
|
return *self;
|
||||||
};
|
};
|
||||||
|
|
||||||
AtomTable::build_with(&atom_tbl, &sub_str)
|
AtomTable::build_with(atom_tbl, sub_str)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
unsafe fn write_to_ptr(string: &str, ptr: *mut u8) {
|
unsafe fn write_to_ptr(string: &str, ptr: *mut u8) {
|
||||||
ptr::write(ptr as *mut _, AtomHeader::build_with(string.len() as u64));
|
ptr::write(ptr as *mut _, AtomHeader::build_with(string.len() as u64));
|
||||||
let str_ptr = (ptr as usize + mem::size_of::<AtomHeader>()) as *mut u8;
|
let str_ptr = (ptr as usize + mem::size_of::<AtomHeader>()) as *mut u8;
|
||||||
ptr::copy_nonoverlapping(string.as_ptr(), str_ptr as *mut u8, string.len());
|
ptr::copy_nonoverlapping(string.as_ptr(), str_ptr, string.len());
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialOrd for Atom {
|
impl PartialOrd for Atom {
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
fn main() -> std::process::ExitCode {
|
fn main() -> std::process::ExitCode {
|
||||||
use scryer_prolog::*;
|
|
||||||
use scryer_prolog::atom_table::Atom;
|
use scryer_prolog::atom_table::Atom;
|
||||||
|
use scryer_prolog::*;
|
||||||
use std::sync::atomic::Ordering;
|
use std::sync::atomic::Ordering;
|
||||||
|
|
||||||
#[cfg(feature = "repl")]
|
#[cfg(feature = "repl")]
|
||||||
|
|||||||
146
src/codegen.rs
146
src/codegen.rs
@@ -111,7 +111,7 @@ impl BranchCodeStack {
|
|||||||
jump_span -= code.len() + 1;
|
jump_span -= code.len() + 1;
|
||||||
} else {
|
} else {
|
||||||
jump_span -= code.len() + 1;
|
jump_span -= code.len() + 1;
|
||||||
code.push_back(instr!("jmp_by_call", jump_span as usize));
|
code.push_back(instr!("jmp_by_call", jump_span));
|
||||||
|
|
||||||
jump_span -= 1;
|
jump_span -= 1;
|
||||||
}
|
}
|
||||||
@@ -124,9 +124,9 @@ impl BranchCodeStack {
|
|||||||
|
|
||||||
for mut branch_arm in self.stack.drain(self.stack.len() - depth..).rev() {
|
for mut branch_arm in self.stack.drain(self.stack.len() - depth..).rev() {
|
||||||
let num_branch_arms = branch_arm.len();
|
let num_branch_arms = branch_arm.len();
|
||||||
branch_arm
|
if let Some(code) = branch_arm.last_mut() {
|
||||||
.last_mut()
|
code.extend(combined_code.drain(..))
|
||||||
.map(|code| code.extend(combined_code.drain(..)));
|
}
|
||||||
|
|
||||||
for (idx, code) in branch_arm.into_iter().enumerate() {
|
for (idx, code) in branch_arm.into_iter().enumerate() {
|
||||||
combined_code.push_back(if idx == 0 {
|
combined_code.push_back(if idx == 0 {
|
||||||
@@ -376,7 +376,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
Target: crate::targets::CompilationTarget<'a>,
|
Target: crate::targets::CompilationTarget<'a>,
|
||||||
{
|
{
|
||||||
if let Some(ref mut instr) = target.back_mut() {
|
if let Some(ref mut instr) = target.back_mut() {
|
||||||
if Target::is_void_instr(&*instr) {
|
if Target::is_void_instr(instr) {
|
||||||
Target::incr_void_instr(instr);
|
Target::incr_void_instr(instr);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@@ -418,10 +418,10 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
|
.mark_non_var::<Target>(Level::Deep, term_loc, cell, target);
|
||||||
target.push_back(Target::clause_arg_to_instr(cell.get()));
|
target.push_back(Target::clause_arg_to_instr(cell.get()));
|
||||||
}
|
}
|
||||||
&Term::Literal(_, ref constant) => {
|
Term::Literal(_, ref constant) => {
|
||||||
target.push_back(Target::constant_subterm(constant.clone()));
|
target.push_back(Target::constant_subterm(*constant));
|
||||||
}
|
}
|
||||||
&Term::Var(ref cell, ref var_ptr) => {
|
Term::Var(ref cell, ref var_ptr) => {
|
||||||
self.deep_var_instr::<Target>(
|
self.deep_var_instr::<Target>(
|
||||||
cell,
|
cell,
|
||||||
var_ptr.to_var_num().unwrap(),
|
var_ptr.to_var_num().unwrap(),
|
||||||
@@ -509,7 +509,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
TermRef::PartialString(lvl, cell, string, tail) => {
|
TermRef::PartialString(lvl, cell, string, tail) => {
|
||||||
self.marker
|
self.marker
|
||||||
.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
.mark_non_var::<Target>(lvl, term_loc, cell, &mut target);
|
||||||
let atom = AtomTable::build_with(&self.atom_tbl, &string);
|
let atom = AtomTable::build_with(self.atom_tbl, string);
|
||||||
|
|
||||||
target.push_back(Target::to_pstr(lvl, atom, cell.get(), true));
|
target.push_back(Target::to_pstr(lvl, atom, cell.get(), true));
|
||||||
self.subterm_to_instr::<Target>(tail, term_loc, &mut target);
|
self.subterm_to_instr::<Target>(tail, term_loc, &mut target);
|
||||||
@@ -558,10 +558,10 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_inlined<'a>(
|
fn compile_inlined(
|
||||||
&mut self,
|
&mut self,
|
||||||
ct: &InlinedClauseType,
|
ct: &InlinedClauseType,
|
||||||
terms: &'a Vec<Term>,
|
terms: &'_ [Term],
|
||||||
term_loc: GenContext,
|
term_loc: GenContext,
|
||||||
code: &mut CodeDeque,
|
code: &mut CodeDeque,
|
||||||
) -> Result<(), CompilationError> {
|
) -> Result<(), CompilationError> {
|
||||||
@@ -585,13 +585,13 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
compare_number_instr!(cmp, at_1, at_2)
|
compare_number_instr!(cmp, at_1, at_2)
|
||||||
}
|
}
|
||||||
&InlinedClauseType::IsAtom(..) => match &terms[0] {
|
InlinedClauseType::IsAtom(..) => match &terms[0] {
|
||||||
&Term::Literal(_, Literal::Char(_))
|
Term::Literal(_, Literal::Char(_))
|
||||||
| &Term::Literal(_, Literal::Atom(atom!("[]")))
|
| Term::Literal(_, Literal::Atom(atom!("[]")))
|
||||||
| &Term::Literal(_, Literal::Atom(..)) => {
|
| Term::Literal(_, Literal::Atom(..)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -608,21 +608,21 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsAtomic(..) => match &terms[0] {
|
InlinedClauseType::IsAtomic(..) => match &terms[0] {
|
||||||
&Term::AnonVar
|
Term::AnonVar
|
||||||
| &Term::Clause(..)
|
| Term::Clause(..)
|
||||||
| &Term::Cons(..)
|
| Term::Cons(..)
|
||||||
| &Term::PartialString(..)
|
| Term::PartialString(..)
|
||||||
| &Term::CompleteString(..) => {
|
| Term::CompleteString(..) => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
&Term::Literal(_, Literal::String(_)) => {
|
Term::Literal(_, Literal::String(_)) => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
&Term::Literal(..) => {
|
Term::Literal(..) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -636,15 +636,15 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("atomic", r)
|
instr!("atomic", r)
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsCompound(..) => match &terms[0] {
|
InlinedClauseType::IsCompound(..) => match &terms[0] {
|
||||||
&Term::Clause(..)
|
Term::Clause(..)
|
||||||
| &Term::Cons(..)
|
| Term::Cons(..)
|
||||||
| &Term::PartialString(..)
|
| Term::PartialString(..)
|
||||||
| &Term::CompleteString(..)
|
| Term::CompleteString(..)
|
||||||
| &Term::Literal(_, Literal::String(..)) => {
|
| Term::Literal(_, Literal::String(..)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -661,11 +661,11 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsRational(..) => match &terms[0] {
|
InlinedClauseType::IsRational(..) => match terms[0] {
|
||||||
&Term::Literal(_, Literal::Rational(_)) => {
|
Term::Literal(_, Literal::Rational(_)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
name.to_var_num().unwrap(),
|
name.to_var_num().unwrap(),
|
||||||
@@ -680,11 +680,11 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsFloat(..) => match &terms[0] {
|
InlinedClauseType::IsFloat(..) => match terms[0] {
|
||||||
&Term::Literal(_, Literal::Float(_)) => {
|
Term::Literal(_, Literal::Float(_)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -701,14 +701,14 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNumber(..) => match &terms[0] {
|
InlinedClauseType::IsNumber(..) => match terms[0] {
|
||||||
&Term::Literal(_, Literal::Float(_))
|
Term::Literal(_, Literal::Float(_))
|
||||||
| &Term::Literal(_, Literal::Rational(_))
|
| Term::Literal(_, Literal::Rational(_))
|
||||||
| &Term::Literal(_, Literal::Integer(_))
|
| Term::Literal(_, Literal::Integer(_))
|
||||||
| &Term::Literal(_, Literal::Fixnum(_)) => {
|
| Term::Literal(_, Literal::Fixnum(_)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -725,11 +725,11 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsNonVar(..) => match &terms[0] {
|
InlinedClauseType::IsNonVar(..) => match terms[0] {
|
||||||
&Term::AnonVar => {
|
Term::AnonVar => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -746,11 +746,11 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsInteger(..) => match &terms[0] {
|
InlinedClauseType::IsInteger(..) => match &terms[0] {
|
||||||
&Term::Literal(_, Literal::Integer(_)) | &Term::Literal(_, Literal::Fixnum(_)) => {
|
Term::Literal(_, Literal::Integer(_)) | Term::Literal(_, Literal::Fixnum(_)) => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -767,18 +767,18 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
&InlinedClauseType::IsVar(..) => match &terms[0] {
|
InlinedClauseType::IsVar(..) => match terms[0] {
|
||||||
&Term::Literal(..)
|
Term::Literal(..)
|
||||||
| &Term::Clause(..)
|
| Term::Clause(..)
|
||||||
| &Term::Cons(..)
|
| Term::Cons(..)
|
||||||
| &Term::PartialString(..)
|
| Term::PartialString(..)
|
||||||
| &Term::CompleteString(..) => {
|
| Term::CompleteString(..) => {
|
||||||
instr!("$fail")
|
instr!("$fail")
|
||||||
}
|
}
|
||||||
&Term::AnonVar => {
|
Term::AnonVar => {
|
||||||
instr!("$succeed")
|
instr!("$succeed")
|
||||||
}
|
}
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
self.marker.reset_arg(1);
|
self.marker.reset_arg(1);
|
||||||
|
|
||||||
let r = self.marker.mark_non_callable(
|
let r = self.marker.mark_non_callable(
|
||||||
@@ -813,7 +813,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
fn compile_is_call(
|
fn compile_is_call(
|
||||||
&mut self,
|
&mut self,
|
||||||
terms: &Vec<Term>,
|
terms: &[Term],
|
||||||
code: &mut CodeDeque,
|
code: &mut CodeDeque,
|
||||||
term_loc: GenContext,
|
term_loc: GenContext,
|
||||||
call_policy: CallPolicy,
|
call_policy: CallPolicy,
|
||||||
@@ -828,8 +828,8 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
self.marker.reset_arg(2);
|
self.marker.reset_arg(2);
|
||||||
|
|
||||||
let at = match &terms[0] {
|
let at = match terms[0] {
|
||||||
&Term::Var(ref vr, ref name) => {
|
Term::Var(ref vr, ref name) => {
|
||||||
let var_num = name.to_var_num().unwrap();
|
let var_num = name.to_var_num().unwrap();
|
||||||
|
|
||||||
if self.marker.var_data.records[var_num].num_occurrences > 1 {
|
if self.marker.var_data.records[var_num].num_occurrences > 1 {
|
||||||
@@ -871,7 +871,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
compile_expr!(self, &terms[1], term_loc, code)
|
compile_expr!(self, &terms[1], term_loc, code)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Term::Literal(
|
Term::Literal(
|
||||||
_,
|
_,
|
||||||
c @ Literal::Integer(_)
|
c @ Literal::Integer(_)
|
||||||
| c @ Literal::Float(_)
|
| c @ Literal::Float(_)
|
||||||
@@ -896,7 +896,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn compile_seq<'a>(
|
fn compile_seq(
|
||||||
&mut self,
|
&mut self,
|
||||||
clauses: &ChunkedTermVec,
|
clauses: &ChunkedTermVec,
|
||||||
code: &mut CodeDeque,
|
code: &mut CodeDeque,
|
||||||
@@ -1066,7 +1066,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
self.marker.reset_at_head(args);
|
self.marker.reset_at_head(args);
|
||||||
|
|
||||||
let iter = FactIterator::from_rule_head_clause(&args);
|
let iter = FactIterator::from_rule_head_clause(args);
|
||||||
let fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head);
|
let fact = self.compile_target::<FactInstruction, _>(iter, GenContext::Head);
|
||||||
|
|
||||||
if self.marker.max_reg_allocated() > MAX_ARITY {
|
if self.marker.max_reg_allocated() > MAX_ARITY {
|
||||||
@@ -1074,7 +1074,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
self.marker.reset_free_list();
|
self.marker.reset_free_list();
|
||||||
code.extend(fact.into_iter());
|
code.extend(fact);
|
||||||
|
|
||||||
self.compile_seq(clauses, &mut code)?;
|
self.compile_seq(clauses, &mut code)?;
|
||||||
|
|
||||||
@@ -1099,7 +1099,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
return Err(CompilationError::ExceededMaxArity);
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
|
|
||||||
code.extend(compiled_fact.into_iter());
|
code.extend(compiled_fact);
|
||||||
}
|
}
|
||||||
|
|
||||||
code.push(instr!("proceed"));
|
code.push(instr!("proceed"));
|
||||||
@@ -1112,7 +1112,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
let iter = QueryIterator::new(term);
|
let iter = QueryIterator::new(term);
|
||||||
let query = self.compile_target::<QueryInstruction, _>(iter, term_loc);
|
let query = self.compile_target::<QueryInstruction, _>(iter, term_loc);
|
||||||
|
|
||||||
code.extend(query.into_iter());
|
code.extend(query);
|
||||||
|
|
||||||
match term {
|
match term {
|
||||||
&QueryTerm::Clause(_, ref ct, _, call_policy) => {
|
&QueryTerm::Clause(_, ref ct, _, call_policy) => {
|
||||||
@@ -1204,12 +1204,12 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
|
|
||||||
let clause_code = match clause {
|
let clause_code = match clause {
|
||||||
PredicateClause::Fact(fact, var_data) => {
|
PredicateClause::Fact(fact, var_data) => {
|
||||||
let var_data = std::mem::replace(var_data, VarData::default());
|
let var_data = std::mem::take(var_data);
|
||||||
self.compile_fact(&fact, var_data)?
|
self.compile_fact(fact, var_data)?
|
||||||
}
|
}
|
||||||
PredicateClause::Rule(rule, var_data) => {
|
PredicateClause::Rule(rule, var_data) => {
|
||||||
let var_data = std::mem::replace(var_data, VarData::default());
|
let var_data = std::mem::take(var_data);
|
||||||
self.compile_rule(&rule, var_data)?
|
self.compile_rule(rule, var_data)?
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1237,9 +1237,7 @@ impl<'b> CodeGenerator<'b> {
|
|||||||
skip_stub_try_me_else = !self.settings.is_dynamic();
|
skip_stub_try_me_else = !self.settings.is_dynamic();
|
||||||
}
|
}
|
||||||
|
|
||||||
let arg = clause
|
let arg = clause.args().and_then(|args| args.get(optimal_index));
|
||||||
.args()
|
|
||||||
.and_then(|args| args.iter().nth(optimal_index));
|
|
||||||
|
|
||||||
if let Some(arg) = arg {
|
if let Some(arg) = arg {
|
||||||
let index = code.len();
|
let index = code.len();
|
||||||
|
|||||||
@@ -295,11 +295,9 @@ impl DebrayAllocator {
|
|||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
|
|
||||||
for reg in self.temp_lb.. {
|
for reg in self.temp_lb.. {
|
||||||
if !self.is_in_use(reg) {
|
if !self.is_in_use(reg) && !temp_var_data.no_use_set.contains(reg) {
|
||||||
if !temp_var_data.no_use_set.contains(reg) {
|
result = reg;
|
||||||
result = reg;
|
break;
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -321,13 +319,12 @@ impl DebrayAllocator {
|
|||||||
let mut result = 0;
|
let mut result = 0;
|
||||||
|
|
||||||
for reg in self.temp_lb.. {
|
for reg in self.temp_lb.. {
|
||||||
if !self.is_in_use(reg) {
|
if !self.is_in_use(reg)
|
||||||
if !temp_var_data.no_use_set.contains(reg) {
|
&& !temp_var_data.no_use_set.contains(reg)
|
||||||
if !temp_var_data.conflict_set.contains(reg) {
|
&& !temp_var_data.conflict_set.contains(reg)
|
||||||
result = reg;
|
{
|
||||||
break;
|
result = reg;
|
||||||
}
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -349,16 +346,15 @@ impl DebrayAllocator {
|
|||||||
// consider its use set. T == par_k iff
|
// consider its use set. T == par_k iff
|
||||||
// (GenContext::Last(_), k) is in t_var.use_set.
|
// (GenContext::Last(_), k) is in t_var.use_set.
|
||||||
|
|
||||||
match &self.var_data.records[t_var].allocation {
|
if let VarAlloc::Temp { temp_var_data, .. } =
|
||||||
VarAlloc::Temp { temp_var_data, .. } => {
|
&self.var_data.records[t_var].allocation
|
||||||
if !temp_var_data
|
{
|
||||||
.use_set
|
if !temp_var_data
|
||||||
.contains(&(GenContext::Last(chunk_num), k))
|
.use_set
|
||||||
{
|
.contains(&(GenContext::Last(chunk_num), k))
|
||||||
return Some((t_var, self.alloc_with_ca(t_var)));
|
{
|
||||||
}
|
return Some((t_var, self.alloc_with_ca(t_var)));
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -372,25 +368,22 @@ impl DebrayAllocator {
|
|||||||
chunk_num: usize,
|
chunk_num: usize,
|
||||||
code: &mut CodeDeque,
|
code: &mut CodeDeque,
|
||||||
) {
|
) {
|
||||||
match self.alloc_in_last_goal_hint(chunk_num) {
|
if let Some((var_num, r)) = self.alloc_in_last_goal_hint(chunk_num) {
|
||||||
Some((var_num, r)) => {
|
let k = self.arg_c;
|
||||||
let k = self.arg_c;
|
|
||||||
|
|
||||||
if r != k {
|
if r != k {
|
||||||
let r = RegType::Temp(r);
|
let r = RegType::Temp(r);
|
||||||
|
|
||||||
code.push_back(Target::move_to_register(r, k));
|
code.push_back(Target::move_to_register(r, k));
|
||||||
|
|
||||||
self.shallow_temp_mappings.swap_remove(&k);
|
self.shallow_temp_mappings.swap_remove(&k);
|
||||||
self.shallow_temp_mappings.insert(r.reg_num(), var_num);
|
self.shallow_temp_mappings.insert(r.reg_num(), var_num);
|
||||||
|
|
||||||
self.var_data.records[var_num]
|
self.var_data.records[var_num]
|
||||||
.allocation
|
.allocation
|
||||||
.set_register(r.reg_num());
|
.set_register(r.reg_num());
|
||||||
self.in_use.insert(r.reg_num());
|
self.in_use.insert(r.reg_num());
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -493,11 +486,8 @@ impl DebrayAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) {
|
fn add_perm_to_free_list(&mut self, chunk_num: usize, var_num: usize) {
|
||||||
match &self.var_data.records[var_num].allocation {
|
if let VarAlloc::Perm(..) = &self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm(..) => {
|
self.perm_free_list.push_back((chunk_num, var_num));
|
||||||
self.perm_free_list.push_back((chunk_num, var_num));
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -521,12 +511,9 @@ impl DebrayAllocator {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn free_var(&mut self, chunk_num: usize, var_num: usize) {
|
pub(crate) fn free_var(&mut self, chunk_num: usize, var_num: usize) {
|
||||||
match &mut self.var_data.records[var_num].allocation {
|
if let VarAlloc::Perm(_, allocation) = &mut self.var_data.records[var_num].allocation {
|
||||||
VarAlloc::Perm(_, allocation) => {
|
*allocation = PermVarAllocation::Pending;
|
||||||
*allocation = PermVarAllocation::Pending;
|
self.add_perm_to_free_list(chunk_num, var_num);
|
||||||
self.add_perm_to_free_list(chunk_num, var_num);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -570,18 +557,15 @@ impl DebrayAllocator {
|
|||||||
*shallow_safety = VarSafetyStatus::unneeded(branch_designator);
|
*shallow_safety = VarSafetyStatus::unneeded(branch_designator);
|
||||||
} else if term_loc == GenContext::Head {
|
} else if term_loc == GenContext::Head {
|
||||||
*shallow_safety = VarSafetyStatus::GloballyUnneeded;
|
*shallow_safety = VarSafetyStatus::GloballyUnneeded;
|
||||||
} else {
|
} else if let Some(&temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c) {
|
||||||
if let Some(temp_var_num) = self.shallow_temp_mappings.get(&self.arg_c).cloned()
|
match &mut self.var_data.records[temp_var_num].allocation {
|
||||||
{
|
VarAlloc::Temp {
|
||||||
match &mut self.var_data.records[temp_var_num].allocation {
|
ref mut to_perm_var_num,
|
||||||
VarAlloc::Temp {
|
..
|
||||||
ref mut to_perm_var_num,
|
} => {
|
||||||
..
|
*to_perm_var_num = Some(var_num);
|
||||||
} => {
|
|
||||||
*to_perm_var_num = Some(var_num);
|
|
||||||
}
|
|
||||||
_ => unreachable!(),
|
|
||||||
}
|
}
|
||||||
|
_ => unreachable!(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -886,12 +870,12 @@ impl Allocator for DebrayAllocator {
|
|||||||
self.arg_c += 1;
|
self.arg_c += 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_at_head(&mut self, args: &Vec<Term>) {
|
fn reset_at_head(&mut self, args: &[Term]) {
|
||||||
self.reset_arg(args.len());
|
self.reset_arg(args.len());
|
||||||
self.arity = args.len();
|
self.arity = args.len();
|
||||||
|
|
||||||
for (idx, arg) in args.iter().enumerate() {
|
for (idx, arg) in args.iter().enumerate() {
|
||||||
if let &Term::Var(_, ref var) = arg {
|
if let Term::Var(_, ref var) = arg {
|
||||||
let var_num = var.to_var_num().unwrap();
|
let var_num = var.to_var_num().unwrap();
|
||||||
let r = self.get_binding(var_num);
|
let r = self.get_binding(var_num);
|
||||||
|
|
||||||
|
|||||||
44
src/ffi.rs
44
src/ffi.rs
@@ -28,7 +28,8 @@ use std::convert::TryFrom;
|
|||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::ffi::{c_void, CString};
|
use std::ffi::{c_void, CString};
|
||||||
|
|
||||||
use libffi::low::{ffi_abi_FFI_DEFAULT_ABI, ffi_cif, ffi_type, prep_cif, type_tag, types, CodePtr};
|
use libffi::low::type_tag::STRUCT;
|
||||||
|
use libffi::low::{ffi_abi_FFI_DEFAULT_ABI, ffi_cif, ffi_type, prep_cif, types, CodePtr};
|
||||||
use libloading::{Library, Symbol};
|
use libloading::{Library, Symbol};
|
||||||
|
|
||||||
pub struct FunctionDefinition {
|
pub struct FunctionDefinition {
|
||||||
@@ -69,11 +70,13 @@ impl ForeignFunctionTable {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn define_struct(&mut self, name: &str, atom_fields: Vec<Atom>) {
|
pub fn define_struct(&mut self, name: &str, atom_fields: Vec<Atom>) {
|
||||||
let mut fields: Vec<_> = atom_fields.iter().map(|x| self.map_type_ffi(&x)).collect();
|
let mut fields: Vec<_> = atom_fields.iter().map(|x| self.map_type_ffi(x)).collect();
|
||||||
fields.push(std::ptr::null_mut::<ffi_type>());
|
fields.push(std::ptr::null_mut::<ffi_type>());
|
||||||
let mut struct_type: ffi_type = Default::default();
|
let struct_type = ffi_type {
|
||||||
struct_type.type_ = type_tag::STRUCT;
|
type_: STRUCT,
|
||||||
struct_type.elements = fields.as_mut_ptr();
|
elements: fields.as_mut_ptr(),
|
||||||
|
..Default::default()
|
||||||
|
};
|
||||||
self.structs.insert(
|
self.structs.insert(
|
||||||
name.to_string(),
|
name.to_string(),
|
||||||
StructImpl {
|
StructImpl {
|
||||||
@@ -121,11 +124,7 @@ impl ForeignFunctionTable {
|
|||||||
let symbol_name: CString = CString::new(function.name.clone())?;
|
let symbol_name: CString = CString::new(function.name.clone())?;
|
||||||
let code_ptr: Symbol<*mut c_void> =
|
let code_ptr: Symbol<*mut c_void> =
|
||||||
library.get(&symbol_name.into_bytes_with_nul())?;
|
library.get(&symbol_name.into_bytes_with_nul())?;
|
||||||
let mut args: Vec<_> = function
|
let mut args: Vec<_> = function.args.iter().map(|x| self.map_type_ffi(x)).collect();
|
||||||
.args
|
|
||||||
.iter()
|
|
||||||
.map(|x| self.map_type_ffi(&x))
|
|
||||||
.collect();
|
|
||||||
let mut cif: ffi_cif = Default::default();
|
let mut cif: ffi_cif = Default::default();
|
||||||
prep_cif(
|
prep_cif(
|
||||||
&mut cif,
|
&mut cif,
|
||||||
@@ -163,7 +162,7 @@ impl ForeignFunctionTable {
|
|||||||
|
|
||||||
fn build_pointer_args(
|
fn build_pointer_args(
|
||||||
args: &mut Vec<Value>,
|
args: &mut Vec<Value>,
|
||||||
type_args: &Vec<*mut ffi_type>,
|
type_args: &[*mut ffi_type],
|
||||||
structs_table: &mut HashMap<String, StructImpl>,
|
structs_table: &mut HashMap<String, StructImpl>,
|
||||||
) -> Result<PointerArgs, FFIError> {
|
) -> Result<PointerArgs, FFIError> {
|
||||||
let mut pointers = Vec::with_capacity(args.len());
|
let mut pointers = Vec::with_capacity(args.len());
|
||||||
@@ -237,6 +236,7 @@ impl ForeignFunctionTable {
|
|||||||
let ptr = alloc(layout) as *mut c_void;
|
let ptr = alloc(layout) as *mut c_void;
|
||||||
let mut field_ptr = ptr;
|
let mut field_ptr = ptr;
|
||||||
|
|
||||||
|
#[allow(clippy::needless_range_loop)]
|
||||||
for i in 0..(struct_type.fields.len() - 1) {
|
for i in 0..(struct_type.fields.len() - 1) {
|
||||||
macro_rules! try_write_int {
|
macro_rules! try_write_int {
|
||||||
($type:ty) => {{
|
($type:ty) => {{
|
||||||
@@ -283,7 +283,7 @@ impl ForeignFunctionTable {
|
|||||||
|
|
||||||
std::ptr::copy(
|
std::ptr::copy(
|
||||||
&*struct_ptr as *const _ as *const c_void,
|
&*struct_ptr as *const _ as *const c_void,
|
||||||
field_ptr as *mut c_void,
|
field_ptr,
|
||||||
struct_size,
|
struct_size,
|
||||||
);
|
);
|
||||||
field_ptr = field_ptr.add(struct_size);
|
field_ptr = field_ptr.add(struct_size);
|
||||||
@@ -293,12 +293,13 @@ impl ForeignFunctionTable {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Ok((Box::from_raw(ptr), size, align));
|
#[allow(clippy::from_raw_with_void_ptr)]
|
||||||
|
Ok((Box::from_raw(ptr), size, align))
|
||||||
} else {
|
} else {
|
||||||
return Err(FFIError::InvalidStructName);
|
Err(FFIError::InvalidStructName)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => return Err(FFIError::ValueCast),
|
_ => Err(FFIError::ValueCast),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -336,7 +337,7 @@ impl ForeignFunctionTable {
|
|||||||
&mut function_impl.cif,
|
&mut function_impl.cif,
|
||||||
Some(*function_impl.code_ptr.as_safe_fun()),
|
Some(*function_impl.code_ptr.as_safe_fun()),
|
||||||
&mut *n as *mut _ as *mut c_void,
|
&mut *n as *mut _ as *mut c_void,
|
||||||
pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
|
pointer_args.pointers.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
Ok(Value::Int(
|
Ok(Value::Int(
|
||||||
i64::try_from(*n).map_err(|_| FFIError::ValueDontFit)?,
|
i64::try_from(*n).map_err(|_| FFIError::ValueDontFit)?,
|
||||||
@@ -350,7 +351,7 @@ impl ForeignFunctionTable {
|
|||||||
&mut function_impl.cif,
|
&mut function_impl.cif,
|
||||||
Some(*function_impl.code_ptr.as_safe_fun()),
|
Some(*function_impl.code_ptr.as_safe_fun()),
|
||||||
&mut *n as *mut _ as *mut c_void,
|
&mut *n as *mut _ as *mut c_void,
|
||||||
pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
|
pointer_args.pointers.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
Ok(Value::Float((*n).into()))
|
Ok(Value::Float((*n).into()))
|
||||||
}
|
}
|
||||||
@@ -360,7 +361,7 @@ impl ForeignFunctionTable {
|
|||||||
&mut function_impl.cif,
|
&mut function_impl.cif,
|
||||||
Some(*function_impl.code_ptr.as_safe_fun()),
|
Some(*function_impl.code_ptr.as_safe_fun()),
|
||||||
&mut *n as *mut _ as *mut c_void,
|
&mut *n as *mut _ as *mut c_void,
|
||||||
pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
|
pointer_args.pointers.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
Ok(Value::Float(*n))
|
Ok(Value::Float(*n))
|
||||||
}
|
}
|
||||||
@@ -380,10 +381,11 @@ impl ForeignFunctionTable {
|
|||||||
libffi::raw::ffi_call(
|
libffi::raw::ffi_call(
|
||||||
&mut function_impl.cif,
|
&mut function_impl.cif,
|
||||||
Some(*function_impl.code_ptr.as_safe_fun()),
|
Some(*function_impl.code_ptr.as_safe_fun()),
|
||||||
&mut *ptr as *mut _ as *mut c_void,
|
&mut *ptr as *mut _,
|
||||||
pointer_args.pointers.as_mut_ptr() as *mut *mut c_void,
|
pointer_args.pointers.as_mut_ptr(),
|
||||||
);
|
);
|
||||||
let struct_val = self.read_struct(ptr, name, struct_type);
|
let struct_val = self.read_struct(ptr, name, struct_type);
|
||||||
|
#[allow(clippy::from_raw_with_void_ptr)]
|
||||||
drop(Box::from_raw(ptr));
|
drop(Box::from_raw(ptr));
|
||||||
struct_val
|
struct_val
|
||||||
}
|
}
|
||||||
@@ -441,7 +443,7 @@ impl ForeignFunctionTable {
|
|||||||
.ok_or(FFIError::StructNotFound)?;
|
.ok_or(FFIError::StructNotFound)?;
|
||||||
field_ptr = field_ptr
|
field_ptr = field_ptr
|
||||||
.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
|
.add(field_ptr.align_offset(struct_type.ffi_type.alignment as usize));
|
||||||
let struct_val = self.read_struct(field_ptr, &*substruct, struct_type);
|
let struct_val = self.read_struct(field_ptr, &substruct, struct_type);
|
||||||
returns.push(struct_val?);
|
returns.push(struct_val?);
|
||||||
field_ptr = field_ptr.add(struct_type.ffi_type.size);
|
field_ptr = field_ptr.add(struct_type.ffi_type.size);
|
||||||
}
|
}
|
||||||
|
|||||||
85
src/forms.rs
85
src/forms.rs
@@ -11,6 +11,7 @@ use crate::parser::dashu::{Integer, Rational};
|
|||||||
use crate::parser::parser::CompositeOpDesc;
|
use crate::parser::parser::CompositeOpDesc;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
use dashu::base::Signed;
|
||||||
use fxhash::FxBuildHasher;
|
use fxhash::FxBuildHasher;
|
||||||
|
|
||||||
use indexmap::{IndexMap, IndexSet};
|
use indexmap::{IndexMap, IndexSet};
|
||||||
@@ -99,11 +100,7 @@ pub enum RootIterationPolicy {
|
|||||||
impl RootIterationPolicy {
|
impl RootIterationPolicy {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn iterable(&self) -> bool {
|
pub fn iterable(&self) -> bool {
|
||||||
if let RootIterationPolicy::Iterated = self {
|
matches!(self, RootIterationPolicy::Iterated)
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -151,6 +148,7 @@ impl DerefMut for ChunkedTermVec {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl ChunkedTermVec {
|
impl ChunkedTermVec {
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
Self {
|
Self {
|
||||||
@@ -202,8 +200,8 @@ pub enum QueryTerm {
|
|||||||
// register, clause type, subterms, clause call policy.
|
// register, clause type, subterms, clause call policy.
|
||||||
Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
|
Clause(Cell<RegType>, ClauseType, Vec<Term>, CallPolicy),
|
||||||
Fail,
|
Fail,
|
||||||
LocalCut { var_num: usize, cut_prev: bool }, // var_num
|
LocalCut { var_num: usize, cut_prev: bool }, // var_num
|
||||||
GlobalCut(usize), // var_num
|
GlobalCut(usize), // var_num
|
||||||
GetCutPoint { var_num: usize, prev_b: bool },
|
GetCutPoint { var_num: usize, prev_b: bool },
|
||||||
GetLevel(usize), // var_num
|
GetLevel(usize), // var_num
|
||||||
}
|
}
|
||||||
@@ -211,7 +209,7 @@ pub enum QueryTerm {
|
|||||||
impl QueryTerm {
|
impl QueryTerm {
|
||||||
pub(crate) fn arity(&self) -> usize {
|
pub(crate) fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&QueryTerm::Clause(_, _, ref subterms, ..) => subterms.len(),
|
QueryTerm::Clause(_, _, subterms, ..) => subterms.len(),
|
||||||
&QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1,
|
&QueryTerm::GetLevel(_) | &QueryTerm::GetCutPoint { .. } => 1,
|
||||||
_ => 0,
|
_ => 0,
|
||||||
}
|
}
|
||||||
@@ -316,15 +314,15 @@ impl ClauseInfo for Rule {
|
|||||||
impl ClauseInfo for PredicateClause {
|
impl ClauseInfo for PredicateClause {
|
||||||
fn name(&self) -> Option<Atom> {
|
fn name(&self) -> Option<Atom> {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => term.head.name(),
|
PredicateClause::Fact(ref term, ..) => term.head.name(),
|
||||||
&PredicateClause::Rule(ref rule, ..) => rule.name(),
|
PredicateClause::Rule(ref rule, ..) => rule.name(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn arity(&self) -> usize {
|
fn arity(&self) -> usize {
|
||||||
match self {
|
match self {
|
||||||
&PredicateClause::Fact(ref term, ..) => term.head.arity(),
|
PredicateClause::Fact(ref term, ..) => term.head.arity(),
|
||||||
&PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
PredicateClause::Rule(ref rule, ..) => rule.arity(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -339,7 +337,7 @@ impl PredicateClause {
|
|||||||
pub(crate) fn args(&self) -> Option<&[Term]> {
|
pub(crate) fn args(&self) -> Option<&[Term]> {
|
||||||
match self {
|
match self {
|
||||||
PredicateClause::Fact(term, ..) => match &term.head {
|
PredicateClause::Fact(term, ..) => match &term.head {
|
||||||
Term::Clause(_, _, args) => Some(&args),
|
Term::Clause(_, _, args) => Some(args),
|
||||||
_ => None,
|
_ => None,
|
||||||
},
|
},
|
||||||
PredicateClause::Rule(rule, ..) => {
|
PredicateClause::Rule(rule, ..) => {
|
||||||
@@ -433,13 +431,10 @@ impl OpDecl {
|
|||||||
pub(crate) fn insert_into_op_dir(&self, op_dir: &mut OpDir) -> Option<OpDesc> {
|
pub(crate) fn insert_into_op_dir(&self, op_dir: &mut OpDir) -> Option<OpDesc> {
|
||||||
let key = (self.name, fixity(self.op_desc.get_spec() as u32));
|
let key = (self.name, fixity(self.op_desc.get_spec() as u32));
|
||||||
|
|
||||||
match op_dir.get_mut(&key) {
|
if let Some(cell) = op_dir.get_mut(&key) {
|
||||||
Some(cell) => {
|
let (old_prec, old_spec) = cell.get();
|
||||||
let (old_prec, old_spec) = cell.get();
|
cell.set(self.op_desc.get_prec(), self.op_desc.get_spec());
|
||||||
cell.set(self.op_desc.get_prec(), self.op_desc.get_spec());
|
return Some(OpDesc::build_with(old_prec, old_spec));
|
||||||
return Some(OpDesc::build_with(old_prec, old_spec));
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
op_dir.insert(key, self.op_desc)
|
op_dir.insert(key, self.op_desc)
|
||||||
@@ -450,7 +445,7 @@ impl OpDecl {
|
|||||||
existing_desc: Option<CompositeOpDesc>,
|
existing_desc: Option<CompositeOpDesc>,
|
||||||
op_dir: &mut OpDir,
|
op_dir: &mut OpDir,
|
||||||
) -> Result<(), SessionError> {
|
) -> Result<(), SessionError> {
|
||||||
let (spec, name) = (self.op_desc.get_spec(), self.name.clone());
|
let (spec, name) = (self.op_desc.get_spec(), self.name);
|
||||||
|
|
||||||
if is_infix!(spec as u32) {
|
if is_infix!(spec as u32) {
|
||||||
if let Some(desc) = existing_desc {
|
if let Some(desc) = existing_desc {
|
||||||
@@ -484,7 +479,7 @@ impl AtomOrString {
|
|||||||
pub fn as_atom(&self, atom_tbl: &AtomTable) -> Atom {
|
pub fn as_atom(&self, atom_tbl: &AtomTable) -> Atom {
|
||||||
match self {
|
match self {
|
||||||
&AtomOrString::Atom(atom) => atom,
|
&AtomOrString::Atom(atom) => atom,
|
||||||
AtomOrString::String(string) => AtomTable::build_with(atom_tbl, &string),
|
AtomOrString::String(string) => AtomTable::build_with(atom_tbl, string),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -496,10 +491,11 @@ impl AtomOrString {
|
|||||||
AtomOrString::String(string) => AtomString::Static(string.as_str()),
|
AtomOrString::String(string) => AtomString::Static(string.as_str()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[inline]
|
impl From<AtomOrString> for String {
|
||||||
pub fn to_string(self) -> String {
|
fn from(val: AtomOrString) -> Self {
|
||||||
match self {
|
match val {
|
||||||
AtomOrString::Atom(atom) => atom.as_str().to_owned(),
|
AtomOrString::Atom(atom) => atom.as_str().to_owned(),
|
||||||
AtomOrString::String(string) => string,
|
AtomOrString::String(string) => string,
|
||||||
}
|
}
|
||||||
@@ -543,7 +539,7 @@ pub(crate) fn fetch_op_spec(name: Atom, arity: usize, op_dir: &OpDir) -> Option<
|
|||||||
}
|
}
|
||||||
}),
|
}),
|
||||||
1 => {
|
1 => {
|
||||||
if let Some(op_desc) = op_dir.get(&(name.clone(), Fixity::Pre)) {
|
if let Some(op_desc) = op_dir.get(&(name, Fixity::Pre)) {
|
||||||
if op_desc.get_prec() > 0 {
|
if op_desc.get_prec() > 0 {
|
||||||
return Some(*op_desc);
|
return Some(*op_desc);
|
||||||
}
|
}
|
||||||
@@ -744,8 +740,8 @@ impl ArenaFrom<Number> for HeapCellValue {
|
|||||||
impl Number {
|
impl Number {
|
||||||
pub(crate) fn sign(&self) -> Number {
|
pub(crate) fn sign(&self) -> Number {
|
||||||
match self {
|
match self {
|
||||||
&Number::Float(f) if f == 0.0 => Number::Float(OrderedFloat(0f64)),
|
Number::Float(f) if *f == 0.0 => Number::Float(OrderedFloat(0f64)),
|
||||||
&Number::Float(f) => Number::Float(OrderedFloat(f.signum())),
|
Number::Float(f) => Number::Float(OrderedFloat(f.signum())),
|
||||||
_ => {
|
_ => {
|
||||||
if self.is_positive() {
|
if self.is_positive() {
|
||||||
Number::Fixnum(Fixnum::build_with(1))
|
Number::Fixnum(Fixnum::build_with(1))
|
||||||
@@ -761,39 +757,36 @@ impl Number {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_positive(&self) -> bool {
|
pub(crate) fn is_positive(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&Number::Fixnum(n) => n.get_num() > 0,
|
Number::Fixnum(n) => n.get_num() > 0,
|
||||||
&Number::Integer(ref n) => &**n > &Integer::from(0),
|
Number::Integer(ref n) => n.is_positive(),
|
||||||
&Number::Float(f) => f.is_sign_positive(),
|
Number::Float(f) => f.is_sign_positive(),
|
||||||
&Number::Rational(ref r) => &**r > &Rational::from(0),
|
Number::Rational(ref r) => r.is_positive(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_negative(&self) -> bool {
|
pub(crate) fn is_negative(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&Number::Fixnum(n) => n.get_num() < 0,
|
Number::Fixnum(n) => n.get_num() < 0,
|
||||||
&Number::Integer(ref n) => &**n < &Integer::from(0),
|
Number::Integer(ref n) => n.is_negative(),
|
||||||
&Number::Float(OrderedFloat(f)) => f.is_sign_negative() && OrderedFloat(f) != -0f64,
|
&Number::Float(OrderedFloat(f)) => f.is_sign_negative() && f != -0f64,
|
||||||
&Number::Rational(ref r) => &**r < &Rational::from(0),
|
Number::Rational(ref r) => r.is_negative(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_zero(&self) -> bool {
|
pub(crate) fn is_zero(&self) -> bool {
|
||||||
match self {
|
match self {
|
||||||
&Number::Fixnum(n) => n.get_num() == 0,
|
Number::Fixnum(n) => n.get_num() == 0,
|
||||||
&Number::Integer(ref n) => &**n == &Integer::from(0),
|
Number::Integer(ref n) => n.is_zero(),
|
||||||
&Number::Float(f) => f == OrderedFloat(0f64) || f == OrderedFloat(-0f64),
|
&Number::Float(OrderedFloat(f)) => f == 0.0 || f == -0.0,
|
||||||
&Number::Rational(ref r) => &**r == &Rational::from(0),
|
Number::Rational(ref r) => r.is_zero(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_integer(&self) -> bool {
|
pub(crate) fn is_integer(&self) -> bool {
|
||||||
match self {
|
matches!(self, Number::Fixnum(_) | Number::Integer(_))
|
||||||
Number::Fixnum(_) | Number::Integer(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -963,7 +956,7 @@ impl LocalPredicateSkeleton {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn add_retracted_dynamic_clause_info(&mut self, clause_info: ClauseIndexInfo) {
|
pub(crate) fn add_retracted_dynamic_clause_info(&mut self, clause_info: ClauseIndexInfo) {
|
||||||
debug_assert_eq!(self.is_dynamic, true);
|
debug_assert!(self.is_dynamic);
|
||||||
|
|
||||||
if self.retracted_dynamic_clauses.is_none() {
|
if self.retracted_dynamic_clauses.is_none() {
|
||||||
self.retracted_dynamic_clauses = Some(vec![]);
|
self.retracted_dynamic_clauses = Some(vec![]);
|
||||||
@@ -1008,7 +1001,7 @@ impl PredicateSkeleton {
|
|||||||
) -> Option<usize> {
|
) -> Option<usize> {
|
||||||
let search_result = self.core.clause_clause_locs.make_contiguous()
|
let search_result = self.core.clause_clause_locs.make_contiguous()
|
||||||
[0..self.core.clause_assert_margin]
|
[0..self.core.clause_assert_margin]
|
||||||
.binary_search_by(|loc| clause_clause_loc.cmp(&loc));
|
.binary_search_by(|loc| clause_clause_loc.cmp(loc));
|
||||||
|
|
||||||
match search_result {
|
match search_result {
|
||||||
Ok(loc) => Some(loc),
|
Ok(loc) => Some(loc),
|
||||||
|
|||||||
101
src/heap_iter.rs
101
src/heap_iter.rs
@@ -43,7 +43,7 @@ impl<'a> Drop for EagerStackfulPreOrderHeapIter<'a> {
|
|||||||
self.start_value.set_mark_bit(true);
|
self.start_value.set_mark_bit(true);
|
||||||
self.iter_stack.push(self.start_value);
|
self.iter_stack.push(self.start_value);
|
||||||
|
|
||||||
while let Some(_) = self.follow() {}
|
while self.follow().is_some() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -87,22 +87,22 @@ impl<'a> EagerStackfulPreOrderHeapIter<'a> {
|
|||||||
let arity = cell_as_atom_cell!(self.heap[s]).get_arity();
|
let arity = cell_as_atom_cell!(self.heap[s]).get_arity();
|
||||||
|
|
||||||
for idx in (s + 1 .. s + arity + 1).rev() {
|
for idx in (s + 1 .. s + arity + 1).rev() {
|
||||||
if self.heap[idx].get_mark_bit() != self.mark_phase {
|
if self.heap[idx].get_mark_bit() != self.mark_phase {
|
||||||
self.iter_stack.push(self.heap[idx]);
|
self.iter_stack.push(self.heap[idx]);
|
||||||
self.heap[idx].set_mark_bit(self.mark_phase);
|
self.heap[idx].set_mark_bit(self.mark_phase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, l) => {
|
(HeapCellValueTag::Lis, l) => {
|
||||||
if self.heap[l+1].get_mark_bit() != self.mark_phase {
|
if self.heap[l+1].get_mark_bit() != self.mark_phase {
|
||||||
self.iter_stack.push(self.heap[l+1]);
|
self.iter_stack.push(self.heap[l+1]);
|
||||||
self.heap[l+1].set_mark_bit(self.mark_phase);
|
self.heap[l+1].set_mark_bit(self.mark_phase);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.heap[l].get_mark_bit() != self.mark_phase {
|
if self.heap[l].get_mark_bit() != self.mark_phase {
|
||||||
self.iter_stack.push(self.heap[l]);
|
self.iter_stack.push(self.heap[l]);
|
||||||
self.heap[l].set_mark_bit(self.mark_phase);
|
self.heap[l].set_mark_bit(self.mark_phase);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
(HeapCellValueTag::AttrVar | HeapCellValueTag::Var, h) => {
|
||||||
let var_value = self.heap[h];
|
let var_value = self.heap[h];
|
||||||
@@ -270,7 +270,9 @@ pub trait FocusedHeapIter: Iterator<Item = HeapCellValue> {
|
|||||||
fn focus(&self) -> IterStackLoc;
|
fn focus(&self) -> IterStackLoc;
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a, ElideLists: ListElisionPolicy> FocusedHeapIter for StackfulPreOrderHeapIter<'a, ElideLists> {
|
impl<'a, ElideLists: ListElisionPolicy> FocusedHeapIter
|
||||||
|
for StackfulPreOrderHeapIter<'a, ElideLists>
|
||||||
|
{
|
||||||
#[inline]
|
#[inline]
|
||||||
fn focus(&self) -> IterStackLoc {
|
fn focus(&self) -> IterStackLoc {
|
||||||
self.h
|
self.h
|
||||||
@@ -506,10 +508,10 @@ impl<'a, ElideLists: ListElisionPolicy> Iterator for StackfulPreOrderHeapIter<'a
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn cycle_detecting_stackless_preorder_iter<'a>(
|
pub(crate) fn cycle_detecting_stackless_preorder_iter(
|
||||||
heap: &'a mut [HeapCellValue],
|
heap: &'_ mut [HeapCellValue],
|
||||||
start: usize,
|
start: usize,
|
||||||
) -> CycleDetectingIter<'a, true> {
|
) -> CycleDetectingIter<'_, true> {
|
||||||
// const generics argument of true so that cycle discovery stops
|
// const generics argument of true so that cycle discovery stops
|
||||||
// the iterator.
|
// the iterator.
|
||||||
CycleDetectingIter::new(heap, start)
|
CycleDetectingIter::new(heap, start)
|
||||||
@@ -660,25 +662,25 @@ pub(crate) fn stackful_post_order_iter<'a, ElideLists: ListElisionPolicy>(
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
use crate::machine::gc::IteratorUMP;
|
||||||
use crate::machine::mock_wam::*;
|
use crate::machine::mock_wam::*;
|
||||||
use crate::machine::gc::{IteratorUMP};
|
|
||||||
|
|
||||||
pub(crate) type RightistPostOrderHeapIter<'a> =
|
pub(crate) type RightistPostOrderHeapIter<'a> =
|
||||||
PostOrderIterator<StacklessPreOrderHeapIter<'a, IteratorUMP>>;
|
PostOrderIterator<StacklessPreOrderHeapIter<'a, IteratorUMP>>;
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn stackless_preorder_iter(
|
pub(crate) fn stackless_preorder_iter(
|
||||||
heap: &mut Vec<HeapCellValue>,
|
heap: &mut [HeapCellValue],
|
||||||
start: usize,
|
start: usize,
|
||||||
) -> StacklessPreOrderHeapIter<IteratorUMP> {
|
) -> StacklessPreOrderHeapIter<IteratorUMP> {
|
||||||
StacklessPreOrderHeapIter::<IteratorUMP>::new(heap, start)
|
StacklessPreOrderHeapIter::<IteratorUMP>::new(heap, start)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn stackless_post_order_iter<'a>(
|
pub(crate) fn stackless_post_order_iter(
|
||||||
heap: &'a mut Heap,
|
heap: &'_ mut Heap,
|
||||||
start: usize,
|
start: usize,
|
||||||
) -> RightistPostOrderHeapIter<'a> {
|
) -> RightistPostOrderHeapIter {
|
||||||
PostOrderIterator::new(stackless_preorder_iter(heap, start))
|
PostOrderIterator::new(stackless_preorder_iter(heap, start))
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -954,7 +956,10 @@ mod tests {
|
|||||||
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), fixnum_as_cell!(Fixnum::build_with(2)));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
|
fixnum_as_cell!(Fixnum::build_with(2))
|
||||||
|
);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
|
||||||
|
|
||||||
@@ -999,11 +1004,17 @@ mod tests {
|
|||||||
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
let pstr_offset_cell = pstr_offset_as_cell!(0);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_loc_as_cell!(4));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
|
pstr_loc_as_cell!(4)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_offset_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), fixnum_as_cell!(Fixnum::build_with(0)));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
|
fixnum_as_cell!(Fixnum::build_with(0))
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
@@ -1016,7 +1027,10 @@ mod tests {
|
|||||||
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 6);
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 6);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_loc_as_cell!(4));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
|
pstr_loc_as_cell!(4)
|
||||||
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
@@ -1035,7 +1049,10 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[4], pstr_offset_as_cell!(0));
|
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(1i64)));
|
assert_eq!(
|
||||||
|
wam.machine_st.heap[5],
|
||||||
|
fixnum_as_cell!(Fixnum::build_with(1i64))
|
||||||
|
);
|
||||||
|
|
||||||
all_cells_unmarked(&wam.machine_st.heap);
|
all_cells_unmarked(&wam.machine_st.heap);
|
||||||
|
|
||||||
@@ -1501,7 +1518,9 @@ mod tests {
|
|||||||
wam.machine_st.heap.clear();
|
wam.machine_st.heap.clear();
|
||||||
|
|
||||||
{
|
{
|
||||||
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 = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 0);
|
||||||
|
|
||||||
@@ -1536,7 +1555,10 @@ mod tests {
|
|||||||
atom_as_cell!(atom!("y"))
|
atom_as_cell!(atom!("y"))
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), heap_loc_as_cell!(0));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
|
heap_loc_as_cell!(0)
|
||||||
|
);
|
||||||
|
|
||||||
assert!(iter.next().is_none());
|
assert!(iter.next().is_none());
|
||||||
}
|
}
|
||||||
@@ -1685,10 +1707,7 @@ mod tests {
|
|||||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter = stackless_preorder_iter(
|
let mut iter = stackless_preorder_iter(&mut wam.machine_st.heap, 9);
|
||||||
&mut wam.machine_st.heap,
|
|
||||||
9,
|
|
||||||
);
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
while let Some(_) = iter.next() {
|
while let Some(_) = iter.next() {
|
||||||
@@ -2889,8 +2908,7 @@ mod tests {
|
|||||||
{
|
{
|
||||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||||
|
|
||||||
let mut iter =
|
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
||||||
stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
@@ -2931,8 +2949,7 @@ mod tests {
|
|||||||
wam.machine_st.heap.push(empty_list_as_cell!());
|
wam.machine_st.heap.push(empty_list_as_cell!());
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter =
|
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
||||||
stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
@@ -2964,8 +2981,7 @@ mod tests {
|
|||||||
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
wam.machine_st.heap.push(heap_loc_as_cell!(0));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter =
|
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
||||||
stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
|
||||||
|
|
||||||
// the cycle will be iterated twice before being detected.
|
// the cycle will be iterated twice before being detected.
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -2993,8 +3009,7 @@ mod tests {
|
|||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter =
|
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
||||||
stackless_post_order_iter(&mut wam.machine_st.heap, 0);
|
|
||||||
|
|
||||||
// cut the iteration short to check that all cells are
|
// cut the iteration short to check that all cells are
|
||||||
// unmarked and unforwarded by the Drop instance of
|
// unmarked and unforwarded by the Drop instance of
|
||||||
@@ -3031,8 +3046,7 @@ mod tests {
|
|||||||
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
|
wam.machine_st.heap.push(pstr_loc_as_cell!(0));
|
||||||
|
|
||||||
{
|
{
|
||||||
let mut iter =
|
let mut iter = stackless_post_order_iter(&mut wam.machine_st.heap, 2);
|
||||||
stackless_post_order_iter(&mut wam.machine_st.heap, 2);
|
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
@@ -3119,10 +3133,7 @@ mod tests {
|
|||||||
unmark_cell_bits!(iter.next().unwrap()),
|
unmark_cell_bits!(iter.next().unwrap()),
|
||||||
heap_loc_as_cell!(3)
|
heap_loc_as_cell!(3)
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_second_cell);
|
||||||
unmark_cell_bits!(iter.next().unwrap()),
|
|
||||||
pstr_second_cell
|
|
||||||
);
|
|
||||||
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
assert_eq!(unmark_cell_bits!(iter.next().unwrap()), pstr_cell);
|
||||||
assert_eq!(iter.next(), None);
|
assert_eq!(iter.next(), None);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
use crate::arena::*;
|
use crate::arena::*;
|
||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use crate::parser::ast::*;
|
use crate::parser::ast::*;
|
||||||
use crate::parser::dashu::{ibig, Integer, Rational};
|
|
||||||
use crate::parser::dashu::base::RemEuclid;
|
use crate::parser::dashu::base::RemEuclid;
|
||||||
use crate::parser::dashu::integer::Sign;
|
use crate::parser::dashu::integer::Sign;
|
||||||
|
use crate::parser::dashu::{ibig, Integer, Rational};
|
||||||
use crate::{
|
use crate::{
|
||||||
alpha_numeric_char, capital_letter_char, cut_char, decimal_digit_char, graphic_token_char,
|
alpha_numeric_char, capital_letter_char, cut_char, decimal_digit_char, graphic_token_char,
|
||||||
is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char,
|
is_fx, is_infix, is_postfix, is_prefix, is_xf, is_xfx, is_xfy, is_yfx, semicolon_char,
|
||||||
@@ -20,6 +20,7 @@ use crate::machine::stack::*;
|
|||||||
use crate::machine::streams::*;
|
use crate::machine::streams::*;
|
||||||
use crate::types::*;
|
use crate::types::*;
|
||||||
|
|
||||||
|
use dashu::base::Signed;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
@@ -258,9 +259,7 @@ pub(crate) fn requires_space(atom: &str, op: &str) -> bool {
|
|||||||
oc == '(' || alpha_numeric_char!(oc)
|
oc == '(' || alpha_numeric_char!(oc)
|
||||||
} else if graphic_token_char!(ac) {
|
} else if graphic_token_char!(ac) {
|
||||||
graphic_token_char!(oc)
|
graphic_token_char!(oc)
|
||||||
} else if variable_indicator_char!(ac) {
|
} else if variable_indicator_char!(ac) || capital_letter_char!(ac) {
|
||||||
alpha_numeric_char!(oc)
|
|
||||||
} else if capital_letter_char!(ac) {
|
|
||||||
alpha_numeric_char!(oc)
|
alpha_numeric_char!(oc)
|
||||||
} else if sign_char!(ac) {
|
} else if sign_char!(ac) {
|
||||||
sign_char!(oc) || decimal_digit_char!(oc)
|
sign_char!(oc) || decimal_digit_char!(oc)
|
||||||
@@ -277,7 +276,7 @@ pub(crate) fn requires_space(atom: &str, op: &str) -> bool {
|
|||||||
|
|
||||||
fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char) -> bool {
|
fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char) -> bool {
|
||||||
if c == '/' {
|
if c == '/' {
|
||||||
return match iter.next() {
|
match iter.next() {
|
||||||
None => true,
|
None => true,
|
||||||
Some('*') => false, // if we start with comment token, we must quote.
|
Some('*') => false, // if we start with comment token, we must quote.
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
@@ -287,9 +286,9 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else if c == '.' {
|
} else if c == '.' {
|
||||||
return match iter.next() {
|
match iter.next() {
|
||||||
None => false,
|
None => false,
|
||||||
Some(c) => {
|
Some(c) => {
|
||||||
if graphic_token_char!(c) {
|
if graphic_token_char!(c) {
|
||||||
@@ -298,7 +297,7 @@ fn non_quoted_graphic_token<Iter: Iterator<Item = char>>(mut iter: Iter, c: char
|
|||||||
false
|
false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
}
|
||||||
} else {
|
} else {
|
||||||
iter.all(|c| graphic_token_char!(c))
|
iter.all(|c| graphic_token_char!(c))
|
||||||
}
|
}
|
||||||
@@ -310,9 +309,7 @@ pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> b
|
|||||||
iter.all(|c| alpha_numeric_char!(c))
|
iter.all(|c| alpha_numeric_char!(c))
|
||||||
} else if graphic_token_char!(c) {
|
} else if graphic_token_char!(c) {
|
||||||
non_quoted_graphic_token(iter, c)
|
non_quoted_graphic_token(iter, c)
|
||||||
} else if semicolon_char!(c) {
|
} else if semicolon_char!(c) || cut_char!(c) {
|
||||||
iter.next().is_none()
|
|
||||||
} else if cut_char!(c) {
|
|
||||||
iter.next().is_none()
|
iter.next().is_none()
|
||||||
} else if c == '[' {
|
} else if c == '[' {
|
||||||
iter.next() == Some(']') && iter.next().is_none()
|
iter.next() == Some(']') && iter.next().is_none()
|
||||||
@@ -328,6 +325,7 @@ pub(super) fn non_quoted_token<Iter: Iterator<Item = char>>(mut iter: Iter) -> b
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::len_without_is_empty)]
|
||||||
pub trait HCValueOutputter {
|
pub trait HCValueOutputter {
|
||||||
type Output;
|
type Output;
|
||||||
|
|
||||||
@@ -370,7 +368,7 @@ impl HCValueOutputter for PrinterOutputter {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn begin_new_var(&mut self) {
|
fn begin_new_var(&mut self) {
|
||||||
if self.contents.len() != 0 {
|
if !self.contents.is_empty() {
|
||||||
self.contents += ", ";
|
self.contents += ", ";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -415,9 +413,9 @@ fn negated_op_needs_bracketing(
|
|||||||
op.is_negative_sign()
|
op.is_negative_sign()
|
||||||
&& iter.leftmost_leaf_has_property(op_dir, |addr| match Number::try_from(addr) {
|
&& iter.leftmost_leaf_has_property(op_dir, |addr| match Number::try_from(addr) {
|
||||||
Ok(Number::Fixnum(n)) => n.get_num() > 0,
|
Ok(Number::Fixnum(n)) => n.get_num() > 0,
|
||||||
Ok(Number::Float(f)) => f > OrderedFloat(0f64),
|
Ok(Number::Float(OrderedFloat(f))) => f > 0f64,
|
||||||
Ok(Number::Integer(n)) => &*n > &Integer::from(0),
|
Ok(Number::Integer(n)) => n.is_positive(),
|
||||||
Ok(Number::Rational(n)) => &*n > &Rational::from(0),
|
Ok(Number::Rational(n)) => n.is_positive(),
|
||||||
_ => false,
|
_ => false,
|
||||||
})
|
})
|
||||||
} else {
|
} else {
|
||||||
@@ -537,20 +535,10 @@ pub(crate) fn numbervar(offset: &Integer, addr: HeapCellValue) -> Option<String>
|
|||||||
}
|
}
|
||||||
|
|
||||||
match Number::try_from(addr) {
|
match Number::try_from(addr) {
|
||||||
Ok(Number::Fixnum(n)) => {
|
Ok(Number::Fixnum(n)) if n.get_num() >= 0 => {
|
||||||
if n.get_num() >= 0 {
|
Some(numbervar(offset + Integer::from(n.get_num())))
|
||||||
Some(numbervar(offset + Integer::from(n.get_num())))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Ok(Number::Integer(n)) => {
|
|
||||||
if &*n >= &Integer::from(0) {
|
|
||||||
Some(numbervar(Integer::from(offset + &*n)))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Ok(Number::Integer(n)) if !n.is_negative() => Some(numbervar(Integer::from(offset + &*n))),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -640,12 +628,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
match &*name.as_str() {
|
if let "|" = &*name.as_str() {
|
||||||
"|" => {
|
self.format_bar_separator_op(max_depth, name, spec);
|
||||||
self.format_bar_separator_op(max_depth, name, spec);
|
return;
|
||||||
return;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
};
|
||||||
|
|
||||||
if self.max_depth_exhausted(max_depth) {
|
if self.max_depth_exhausted(max_depth) {
|
||||||
@@ -657,22 +642,19 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
if is_xfy!(spec.get_spec()) {
|
if is_xfy!(spec.get_spec()) {
|
||||||
let left_directed_op = DirectedOp::Left(name, spec);
|
let left_directed_op = DirectedOp::Left(name, spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
self.state_stack
|
||||||
0,
|
.push(TokenOrRedirect::CompositeRedirect(0, left_directed_op));
|
||||||
left_directed_op,
|
|
||||||
));
|
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
||||||
self.state_stack.push(TokenOrRedirect::StackPop);
|
self.state_stack.push(TokenOrRedirect::StackPop);
|
||||||
} else { // is_yfx!
|
} else {
|
||||||
|
// is_yfx!
|
||||||
let right_directed_op = DirectedOp::Right(name, spec);
|
let right_directed_op = DirectedOp::Right(name, spec);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::StackPop);
|
self.state_stack.push(TokenOrRedirect::StackPop);
|
||||||
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
self.state_stack.push(TokenOrRedirect::Op(name, spec));
|
||||||
self.state_stack.push(TokenOrRedirect::CompositeRedirect(
|
self.state_stack
|
||||||
0,
|
.push(TokenOrRedirect::CompositeRedirect(0, right_directed_op));
|
||||||
right_directed_op,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let left_directed_op = DirectedOp::Left(name, spec);
|
let left_directed_op = DirectedOp::Left(name, spec);
|
||||||
@@ -783,7 +765,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let h = self.iter.stack_last().unwrap();
|
let h = self.iter.stack_last().unwrap();
|
||||||
|
|
||||||
let cell = self.iter.read_cell(h);
|
let cell = self.iter.read_cell(h);
|
||||||
let cell = heap_bound_store(&self.iter.heap, heap_bound_deref(&self.iter.heap, cell));
|
let cell = heap_bound_store(self.iter.heap, heap_bound_deref(self.iter.heap, cell));
|
||||||
|
|
||||||
// 7.10.4
|
// 7.10.4
|
||||||
if let Some(var) = numbervar(&self.numbervars_offset, cell) {
|
if let Some(var) = numbervar(&self.numbervars_offset, cell) {
|
||||||
@@ -802,20 +784,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
name: Atom,
|
name: Atom,
|
||||||
op_desc: Option<OpDesc>,
|
op_desc: Option<OpDesc>,
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if self.numbervars && is_numbered_var(name, arity) {
|
if self.numbervars && is_numbered_var(name, arity) && self.format_numbered_vars() {
|
||||||
if self.format_numbered_vars() {
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
let dot_atom = atom!(".");
|
let dot_atom = atom!(".");
|
||||||
|
|
||||||
if let Some(spec) = op_desc {
|
if let Some(spec) = op_desc {
|
||||||
if dot_atom == name && is_infix!(spec.get_spec()) {
|
if dot_atom == name && is_infix!(spec.get_spec()) && !self.ignore_ops {
|
||||||
if !self.ignore_ops {
|
self.push_list(max_depth);
|
||||||
self.push_list(max_depth);
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if !self.ignore_ops && spec.get_prec() > 0 {
|
if !self.ignore_ops && spec.get_prec() > 0 {
|
||||||
@@ -824,10 +802,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return match (name, arity) {
|
match (name, arity) {
|
||||||
(atom!("{}"), 1) if !self.ignore_ops => self.format_curly_braces(max_depth),
|
(atom!("{}"), 1) if !self.ignore_ops => self.format_curly_braces(max_depth),
|
||||||
_ => self.format_struct(max_depth, arity, name),
|
_ => self.format_struct(max_depth, arity, name),
|
||||||
};
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn offset_as_string(&mut self, h: IterStackLoc) -> Option<String> {
|
fn offset_as_string(&mut self, h: IterStackLoc) -> Option<String> {
|
||||||
@@ -866,7 +844,8 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
loop {
|
loop {
|
||||||
let is_cyclic = orig_cell.get_forwarding_bit();
|
let is_cyclic = orig_cell.get_forwarding_bit();
|
||||||
|
|
||||||
let cell = heap_bound_store(self.iter.heap, heap_bound_deref(self.iter.heap, orig_cell));
|
let cell =
|
||||||
|
heap_bound_store(self.iter.heap, heap_bound_deref(self.iter.heap, orig_cell));
|
||||||
let cell = unmark_cell_bits!(cell);
|
let cell = unmark_cell_bits!(cell);
|
||||||
|
|
||||||
match self.var_names.get(&cell).cloned() {
|
match self.var_names.get(&cell).cloned() {
|
||||||
@@ -933,7 +912,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let h = cell.get_value() as usize;
|
let h = cell.get_value() as usize;
|
||||||
self.iter.push_stack(IterStackLoc::iterable_loc(h, HeapOrStackTag::Heap));
|
self.iter.push_stack(IterStackLoc::iterable_loc(
|
||||||
|
h,
|
||||||
|
HeapOrStackTag::Heap,
|
||||||
|
));
|
||||||
|
|
||||||
if let Some(cell) = self.iter.next() {
|
if let Some(cell) = self.iter.next() {
|
||||||
orig_cell = cell;
|
orig_cell = cell;
|
||||||
@@ -951,13 +933,13 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
while let Some(_) = self.iter.pop_stack() {}
|
while self.iter.pop_stack().is_none() {}
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn print_impromptu_atom(&mut self, atom: Atom) {
|
fn print_impromptu_atom(&mut self, atom: Atom) {
|
||||||
let result = self.print_op_addendum(&*atom.as_str());
|
let result = self.print_op_addendum(&atom.as_str());
|
||||||
|
|
||||||
push_space_if_amb!(self, result.as_str(), {
|
push_space_if_amb!(self, result.as_str(), {
|
||||||
append_str!(self, &result);
|
append_str!(self, &result);
|
||||||
@@ -1145,8 +1127,6 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::Open);
|
self.state_stack.push(TokenOrRedirect::Open);
|
||||||
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
self.state_stack.push(TokenOrRedirect::Atom(rdiv_ct));
|
||||||
}
|
}
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -1242,7 +1222,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
let mut heap_pstr_iter = HeapPStrIter::new(self.iter.heap, focus.value() as usize);
|
let mut heap_pstr_iter = HeapPStrIter::new(self.iter.heap, focus.value() as usize);
|
||||||
|
|
||||||
if heap_pstr_iter.next().is_some() {
|
if heap_pstr_iter.next().is_some() {
|
||||||
while let Some(_) = heap_pstr_iter.next() {}
|
for _ in heap_pstr_iter.by_ref() {}
|
||||||
} else {
|
} else {
|
||||||
return self.push_list(max_depth);
|
return self.push_list(max_depth);
|
||||||
}
|
}
|
||||||
@@ -1258,11 +1238,9 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let at_cdr = self.outputter.ends_with("|");
|
let at_cdr = self.outputter.ends_with("|");
|
||||||
|
|
||||||
if self.double_quotes {
|
if self.double_quotes && !self.ignore_ops && end_cell.is_string_terminator(self.iter.heap) {
|
||||||
if !self.ignore_ops && end_cell.is_string_terminator(&self.iter.heap) {
|
self.remove_list_children(focus.value() as usize);
|
||||||
self.remove_list_children(focus.value() as usize);
|
return self.print_proper_string(focus.value() as usize, max_depth);
|
||||||
return self.print_proper_string(focus.value() as usize, max_depth);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.ignore_ops {
|
if self.ignore_ops {
|
||||||
@@ -1275,8 +1253,10 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
append_str!(self, "[]");
|
append_str!(self, "[]");
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
|
self.iter
|
||||||
|
.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
@@ -1287,7 +1267,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
read_heap_cell!(value,
|
read_heap_cell!(value,
|
||||||
(HeapCellValueTag::Lis) => {
|
(HeapCellValueTag::Lis) => {
|
||||||
return self.push_list(max_depth);
|
self.push_list(max_depth)
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
let switch = Rc::new(Cell::new((!at_cdr, 0)));
|
let switch = Rc::new(Cell::new((!at_cdr, 0)));
|
||||||
@@ -1386,13 +1366,16 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let switch = self.close_list(cell);
|
let switch = self.close_list(cell);
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth));
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator); // bar
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
||||||
|
|
||||||
self.open_list(switch);
|
self.open_list(switch);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::too_many_arguments)]
|
||||||
fn handle_op_as_struct(
|
fn handle_op_as_struct(
|
||||||
&mut self,
|
&mut self,
|
||||||
name: Atom,
|
name: Atom,
|
||||||
@@ -1448,7 +1431,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
for op in &[op, parent_op] {
|
for op in &[op, parent_op] {
|
||||||
if let Some(ref op) = &op {
|
if let Some(ref op) = &op {
|
||||||
if op.is_left()
|
if op.is_left()
|
||||||
&& (op.is_prefix() || requires_space(&*op.as_atom().as_str(), "("))
|
&& (op.is_prefix() || requires_space(&op.as_atom().as_str(), "("))
|
||||||
{
|
{
|
||||||
self.state_stack.push(TokenOrRedirect::Space);
|
self.state_stack.push(TokenOrRedirect::Space);
|
||||||
return;
|
return;
|
||||||
@@ -1463,7 +1446,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
fn print_tcp_listener(&mut self, tcp_listener: &TcpListener, max_depth: usize) {
|
fn print_tcp_listener(&mut self, tcp_listener: &TcpListener, max_depth: usize) {
|
||||||
let (ip, port) = if let Some(addr) = tcp_listener.local_addr().ok() {
|
let (ip, port) = if let Ok(addr) = tcp_listener.local_addr() {
|
||||||
(addr.ip(), addr.port())
|
(addr.ip(), addr.port())
|
||||||
} else {
|
} else {
|
||||||
let disconnected_atom = atom!("$disconnected_tcp_listener");
|
let disconnected_atom = atom!("$disconnected_tcp_listener");
|
||||||
@@ -1545,24 +1528,33 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn print_comma_separated_char_list(&mut self, char_list: CommaSeparatedCharList) {
|
fn print_comma_separated_char_list(&mut self, char_list: CommaSeparatedCharList) {
|
||||||
let CommaSeparatedCharList { pstr, offset, max_depth, end_cell, end_h } = char_list;
|
let CommaSeparatedCharList {
|
||||||
|
pstr,
|
||||||
|
offset,
|
||||||
|
max_depth,
|
||||||
|
end_cell,
|
||||||
|
end_h,
|
||||||
|
} = char_list;
|
||||||
let pstr_str = pstr.as_str_from(offset);
|
let pstr_str = pstr.as_str_from(offset);
|
||||||
|
|
||||||
if let Some(c) = pstr_str.chars().next() {
|
if let Some(c) = pstr_str.chars().next() {
|
||||||
let offset = offset + c.len_utf8();
|
let offset = offset + c.len_utf8();
|
||||||
|
|
||||||
if !self.max_depth_exhausted(max_depth) {
|
if !self.max_depth_exhausted(max_depth) {
|
||||||
self.state_stack.push(TokenOrRedirect::CommaSeparatedCharList(CommaSeparatedCharList {
|
self.state_stack
|
||||||
pstr,
|
.push(TokenOrRedirect::CommaSeparatedCharList(
|
||||||
offset,
|
CommaSeparatedCharList {
|
||||||
max_depth: max_depth.saturating_sub(1),
|
pstr,
|
||||||
end_cell,
|
offset,
|
||||||
end_h,
|
max_depth: max_depth.saturating_sub(1),
|
||||||
}));
|
end_cell,
|
||||||
|
end_h,
|
||||||
|
},
|
||||||
|
));
|
||||||
|
|
||||||
let max_depth_allows = self.max_depth == 0 || max_depth > 1;
|
let max_depth_allows = self.max_depth == 0 || max_depth > 1;
|
||||||
|
|
||||||
if max_depth_allows && pstr_str.chars().skip(1).next().is_some() {
|
if max_depth_allows && pstr_str.chars().nth(1).is_some() {
|
||||||
self.state_stack.push(TokenOrRedirect::Comma);
|
self.state_stack.push(TokenOrRedirect::Comma);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1576,10 +1568,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
} else if end_cell != empty_list_as_cell!() {
|
} else if end_cell != empty_list_as_cell!() {
|
||||||
if let Some(end_h) = end_h {
|
if let Some(end_h) = end_h {
|
||||||
self.iter.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
self.iter
|
||||||
|
.push_stack(IterStackLoc::iterable_loc(end_h, HeapOrStackTag::Heap));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.state_stack.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
self.state_stack
|
||||||
|
.push(TokenOrRedirect::FunctorRedirect(max_depth + 1));
|
||||||
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
self.state_stack.push(TokenOrRedirect::HeadTailSeparator);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1599,13 +1593,12 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
|
|
||||||
let print_struct = |printer: &mut Self, name: Atom, arity: usize| {
|
let print_struct = |printer: &mut Self, name: Atom, arity: usize| {
|
||||||
if name == atom!("[]") && arity == 0 {
|
if name == atom!("[]") && arity == 0 {
|
||||||
match printer.state_stack.last() {
|
if let Some(TokenOrRedirect::CloseList(_) | TokenOrRedirect::ChildCloseList) =
|
||||||
Some(TokenOrRedirect::CloseList(_) | TokenOrRedirect::ChildCloseList) => {
|
printer.state_stack.last()
|
||||||
if printer.at_cdr("") {
|
{
|
||||||
return;
|
if printer.at_cdr("") {
|
||||||
}
|
return;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
append_str!(printer, "[]");
|
append_str!(printer, "[]");
|
||||||
@@ -1642,7 +1635,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
result.push('(');
|
result.push('(');
|
||||||
}
|
}
|
||||||
|
|
||||||
result += &printer.print_op_addendum(&*name.as_str());
|
result += &printer.print_op_addendum(&name.as_str());
|
||||||
|
|
||||||
if op.is_some() {
|
if op.is_some() {
|
||||||
result.push(')');
|
result.push(')');
|
||||||
@@ -1652,14 +1645,14 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
append_str!(printer, &result);
|
append_str!(printer, &result);
|
||||||
});
|
});
|
||||||
} else {
|
} else {
|
||||||
push_space_if_amb!(printer, &*name.as_str(), {
|
push_space_if_amb!(printer, &name.as_str(), {
|
||||||
printer.print_impromptu_atom(name);
|
printer.print_impromptu_atom(name);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
if !addr.is_var()
|
if !addr.is_var()
|
||||||
&& !addr.is_compound(&self.iter.heap)
|
&& !addr.is_compound(self.iter.heap)
|
||||||
&& self.max_depth_exhausted(max_depth)
|
&& self.max_depth_exhausted(max_depth)
|
||||||
{
|
{
|
||||||
if !(addr == atom_as_cell!(atom!("[]")) && self.at_cdr("")) {
|
if !(addr == atom_as_cell!(atom!("[]")) && self.at_cdr("")) {
|
||||||
@@ -1772,7 +1765,7 @@ impl<'a, Outputter: HCValueOutputter> HCPrinter<'a, Outputter> {
|
|||||||
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
TokenOrRedirect::BarAsOp => append_str!(self, " | "),
|
||||||
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
TokenOrRedirect::Char(c) => print_char!(self, self.quoted, c),
|
||||||
TokenOrRedirect::Op(atom, op) => {
|
TokenOrRedirect::Op(atom, op) => {
|
||||||
self.print_op(&*atom.as_str());
|
self.print_op(&atom.as_str());
|
||||||
|
|
||||||
if is_prefix!(op.get_spec()) {
|
if is_prefix!(op.get_spec()) {
|
||||||
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
|
self.set_parent_of_first_op(Some(DirectedOp::Left(atom, op)));
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use std::sync::{Arc, Mutex, Condvar};
|
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
|
use std::sync::{Arc, Condvar, Mutex};
|
||||||
|
|
||||||
use warp::http;
|
use warp::http;
|
||||||
|
|
||||||
|
|||||||
126
src/indexing.rs
126
src/indexing.rs
@@ -665,7 +665,7 @@ pub(crate) fn merge_clause_index(
|
|||||||
pub(crate) fn remove_constant_indices(
|
pub(crate) fn remove_constant_indices(
|
||||||
constant: Literal,
|
constant: Literal,
|
||||||
overlapping_constants: &[Literal],
|
overlapping_constants: &[Literal],
|
||||||
indexing_code: &mut Vec<IndexingLine>,
|
indexing_code: &mut [IndexingLine],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) {
|
) {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
@@ -811,7 +811,7 @@ pub(crate) fn remove_constant_indices(
|
|||||||
pub(crate) fn remove_structure_index(
|
pub(crate) fn remove_structure_index(
|
||||||
name: Atom,
|
name: Atom,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
indexing_code: &mut Vec<IndexingLine>,
|
indexing_code: &mut [IndexingLine],
|
||||||
offset: usize,
|
offset: usize,
|
||||||
) {
|
) {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
@@ -843,10 +843,10 @@ pub(crate) fn remove_structure_index(
|
|||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(ref mut structures)) => {
|
||||||
structures_index = index;
|
structures_index = index;
|
||||||
|
|
||||||
match structures.get(&(name.clone(), arity)).cloned() {
|
match structures.get(&(name, arity)).cloned() {
|
||||||
Some(IndexingCodePtr::DynamicExternal(_))
|
Some(IndexingCodePtr::DynamicExternal(_))
|
||||||
| Some(IndexingCodePtr::External(_)) => {
|
| Some(IndexingCodePtr::External(_)) => {
|
||||||
structures.remove(&(name.clone(), arity));
|
structures.remove(&(name, arity));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
Some(IndexingCodePtr::Internal(o)) => {
|
Some(IndexingCodePtr::Internal(o)) => {
|
||||||
@@ -877,7 +877,7 @@ pub(crate) fn remove_structure_index(
|
|||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||||
ref mut structures,
|
ref mut structures,
|
||||||
)) => {
|
)) => {
|
||||||
structures.insert((name.clone(), arity), ext);
|
structures.insert((name, arity), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -908,7 +908,7 @@ pub(crate) fn remove_structure_index(
|
|||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
IndexingLine::Indexing(IndexingInstruction::SwitchOnStructure(
|
||||||
ref mut structures,
|
ref mut structures,
|
||||||
)) => {
|
)) => {
|
||||||
structures.insert((name.clone(), arity), ext);
|
structures.insert((name, arity), ext);
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
@@ -948,7 +948,7 @@ pub(crate) fn remove_structure_index(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: usize) {
|
pub(crate) fn remove_list_index(indexing_code: &mut [IndexingLine], offset: usize) {
|
||||||
let mut index = 0;
|
let mut index = 0;
|
||||||
|
|
||||||
match &mut indexing_code[index] {
|
match &mut indexing_code[index] {
|
||||||
@@ -1028,7 +1028,7 @@ pub(crate) fn remove_list_index(indexing_code: &mut Vec<IndexingLine>, offset: u
|
|||||||
|
|
||||||
pub(crate) fn remove_index(
|
pub(crate) fn remove_index(
|
||||||
opt_arg_index_key: &OptArgIndexKey,
|
opt_arg_index_key: &OptArgIndexKey,
|
||||||
indexing_code: &mut Vec<IndexingLine>,
|
indexing_code: &mut [IndexingLine],
|
||||||
clause_loc: usize,
|
clause_loc: usize,
|
||||||
) {
|
) {
|
||||||
match opt_arg_index_key {
|
match opt_arg_index_key {
|
||||||
@@ -1049,46 +1049,50 @@ pub(crate) fn remove_index(
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cap_choice_seq(prelude: &mut [IndexedChoiceInstruction]) {
|
fn cap_choice_seq(prelude: &mut [IndexedChoiceInstruction]) {
|
||||||
prelude.first_mut().map(|instr| {
|
if let Some(instr) = prelude.first_mut() {
|
||||||
*instr = IndexedChoiceInstruction::Try(instr.offset());
|
*instr = IndexedChoiceInstruction::Try(instr.offset());
|
||||||
});
|
}
|
||||||
|
|
||||||
cap_choice_seq_with_trust(prelude);
|
cap_choice_seq_with_trust(prelude);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn cap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
|
fn cap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
|
||||||
prelude.last_mut().map(|instr| match instr {
|
if let Some(instr) = prelude.last_mut() {
|
||||||
IndexedChoiceInstruction::Retry(i) => {
|
match instr {
|
||||||
*instr = IndexedChoiceInstruction::Trust(*i);
|
IndexedChoiceInstruction::Retry(i) => {
|
||||||
|
*instr = IndexedChoiceInstruction::Trust(*i);
|
||||||
|
}
|
||||||
|
IndexedChoiceInstruction::DefaultRetry(i) => {
|
||||||
|
*instr = IndexedChoiceInstruction::DefaultTrust(*i);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
IndexedChoiceInstruction::DefaultRetry(i) => {
|
}
|
||||||
*instr = IndexedChoiceInstruction::DefaultTrust(*i);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn uncap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
|
fn uncap_choice_seq_with_trust(prelude: &mut [IndexedChoiceInstruction]) {
|
||||||
prelude.last_mut().map(|instr| match instr {
|
if let Some(instr) = prelude.last_mut() {
|
||||||
IndexedChoiceInstruction::Trust(i) => {
|
match instr {
|
||||||
*instr = IndexedChoiceInstruction::Retry(*i);
|
IndexedChoiceInstruction::Trust(i) => {
|
||||||
|
*instr = IndexedChoiceInstruction::Retry(*i);
|
||||||
|
}
|
||||||
|
IndexedChoiceInstruction::DefaultTrust(i) => {
|
||||||
|
*instr = IndexedChoiceInstruction::DefaultRetry(*i);
|
||||||
|
}
|
||||||
|
_ => {}
|
||||||
}
|
}
|
||||||
IndexedChoiceInstruction::DefaultTrust(i) => {
|
}
|
||||||
*instr = IndexedChoiceInstruction::DefaultRetry(*i);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn uncap_choice_seq_with_try(prelude: &mut [IndexedChoiceInstruction]) {
|
fn uncap_choice_seq_with_try(prelude: &mut [IndexedChoiceInstruction]) {
|
||||||
prelude.first_mut().map(|instr| {
|
if let Some(instr) = prelude.first_mut() {
|
||||||
if let IndexedChoiceInstruction::Try(i) = instr {
|
if let IndexedChoiceInstruction::Try(i) = instr {
|
||||||
*instr = IndexedChoiceInstruction::Retry(*i);
|
*instr = IndexedChoiceInstruction::Retry(*i);
|
||||||
}
|
}
|
||||||
});
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn constant_key_alternatives(
|
pub(crate) fn constant_key_alternatives(
|
||||||
@@ -1105,7 +1109,7 @@ pub(crate) fn constant_key_alternatives(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
Literal::Char(c) => {
|
Literal::Char(c) => {
|
||||||
let atom = AtomTable::build_with(&atom_tbl, &c.to_string());
|
let atom = AtomTable::build_with(atom_tbl, &c.to_string());
|
||||||
constants.push(Literal::Atom(atom));
|
constants.push(Literal::Atom(atom));
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
@@ -1124,9 +1128,11 @@ pub(crate) fn constant_key_alternatives(
|
|||||||
Literal::Integer(ref n) => {
|
Literal::Integer(ref n) => {
|
||||||
let result = (&**n).try_into();
|
let result = (&**n).try_into();
|
||||||
if let Ok(value) = result {
|
if let Ok(value) = result {
|
||||||
Fixnum::build_with_checked(value).map(|n| {
|
Fixnum::build_with_checked(value)
|
||||||
constants.push(Literal::Fixnum(n));
|
.map(|n| {
|
||||||
}).unwrap();
|
constants.push(Literal::Fixnum(n));
|
||||||
|
})
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {}
|
_ => {}
|
||||||
@@ -1245,10 +1251,8 @@ impl Indexer for StaticCodeIndices {
|
|||||||
index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1));
|
index_locs.insert(key, IndexingCodePtr::Internal(prelude.len() + 1));
|
||||||
cap_choice_seq_with_trust(code.make_contiguous());
|
cap_choice_seq_with_trust(code.make_contiguous());
|
||||||
prelude.push_back(IndexingLine::from(code));
|
prelude.push_back(IndexingLine::from(code));
|
||||||
} else {
|
} else if let Some(i) = code.front() {
|
||||||
code.front().map(|i| {
|
index_locs.insert(key, IndexingCodePtr::External(i.offset()));
|
||||||
index_locs.insert(key, IndexingCodePtr::External(i.offset()));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1285,7 +1289,7 @@ impl Indexer for StaticCodeIndices {
|
|||||||
) -> IndexingCodePtr {
|
) -> IndexingCodePtr {
|
||||||
if lists.len() > 1 {
|
if lists.len() > 1 {
|
||||||
cap_choice_seq_with_trust(lists.make_contiguous());
|
cap_choice_seq_with_trust(lists.make_contiguous());
|
||||||
let lists = mem::replace(lists, VecDeque::new());
|
let lists = std::mem::take(lists);
|
||||||
prelude.push_back(IndexingLine::from(lists));
|
prelude.push_back(IndexingLine::from(lists));
|
||||||
|
|
||||||
IndexingCodePtr::Internal(1)
|
IndexingCodePtr::Internal(1)
|
||||||
@@ -1361,10 +1365,8 @@ impl Indexer for DynamicCodeIndices {
|
|||||||
prelude.push_back(IndexingLine::DynamicIndexedChoice(
|
prelude.push_back(IndexingLine::DynamicIndexedChoice(
|
||||||
code.into_iter().collect(),
|
code.into_iter().collect(),
|
||||||
));
|
));
|
||||||
} else {
|
} else if let Some(i) = code.front() {
|
||||||
code.front().map(|i| {
|
index_locs.insert(key, IndexingCodePtr::DynamicExternal(*i));
|
||||||
index_locs.insert(key, IndexingCodePtr::DynamicExternal(*i));
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1400,7 +1402,7 @@ impl Indexer for DynamicCodeIndices {
|
|||||||
prelude: &mut VecDeque<IndexingLine>,
|
prelude: &mut VecDeque<IndexingLine>,
|
||||||
) -> IndexingCodePtr {
|
) -> IndexingCodePtr {
|
||||||
if lists.len() > 1 {
|
if lists.len() > 1 {
|
||||||
let lists = mem::replace(lists, VecDeque::new());
|
let lists = std::mem::take(lists);
|
||||||
prelude.push_back(IndexingLine::DynamicIndexedChoice(
|
prelude.push_back(IndexingLine::DynamicIndexedChoice(
|
||||||
lists.into_iter().collect(),
|
lists.into_iter().collect(),
|
||||||
));
|
));
|
||||||
@@ -1458,11 +1460,7 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
index: usize,
|
index: usize,
|
||||||
) -> Vec<Literal> {
|
) -> Vec<Literal> {
|
||||||
let overlapping_constants = constant_key_alternatives(constant, atom_tbl);
|
let overlapping_constants = constant_key_alternatives(constant, atom_tbl);
|
||||||
let code = self
|
let code = self.indices.constants().entry(constant).or_default();
|
||||||
.indices
|
|
||||||
.constants()
|
|
||||||
.entry(constant)
|
|
||||||
.or_insert(VecDeque::new());
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
code.push_back(I::compute_index(
|
code.push_back(I::compute_index(
|
||||||
@@ -1472,11 +1470,7 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
));
|
));
|
||||||
|
|
||||||
for constant in &overlapping_constants {
|
for constant in &overlapping_constants {
|
||||||
let code = self
|
let code = self.indices.constants().entry(*constant).or_default();
|
||||||
.indices
|
|
||||||
.constants()
|
|
||||||
.entry(*constant)
|
|
||||||
.or_insert(VecDeque::new());
|
|
||||||
|
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
let index = I::compute_index(is_initial_index, index, self.non_counted_bt);
|
let index = I::compute_index(is_initial_index, index, self.non_counted_bt);
|
||||||
@@ -1488,11 +1482,7 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn index_structure(&mut self, name: Atom, arity: usize, index: usize) -> usize {
|
fn index_structure(&mut self, name: Atom, arity: usize, index: usize) -> usize {
|
||||||
let code = self
|
let code = self.indices.structures().entry((name, arity)).or_default();
|
||||||
.indices
|
|
||||||
.structures()
|
|
||||||
.entry((name.clone(), arity))
|
|
||||||
.or_insert(VecDeque::new());
|
|
||||||
|
|
||||||
let code_len = code.len();
|
let code_len = code.len();
|
||||||
let is_initial_index = code.is_empty();
|
let is_initial_index = code.is_empty();
|
||||||
@@ -1523,7 +1513,7 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
}
|
}
|
||||||
&Term::Clause(_, name, ref terms) => {
|
&Term::Clause(_, name, ref terms) => {
|
||||||
clause_index_info.opt_arg_index_key =
|
clause_index_info.opt_arg_index_key =
|
||||||
OptArgIndexKey::Structure(self.optimal_index, 0, name.clone(), terms.len());
|
OptArgIndexKey::Structure(self.optimal_index, 0, name, terms.len());
|
||||||
|
|
||||||
self.index_structure(name, terms.len(), index);
|
self.index_structure(name, terms.len(), index);
|
||||||
}
|
}
|
||||||
@@ -1575,20 +1565,14 @@ impl<I: Indexer> CodeOffsets<I> {
|
|||||||
&mut prelude,
|
&mut prelude,
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut str_loc {
|
if let IndexingCodePtr::Internal(ref mut i) = &mut str_loc {
|
||||||
IndexingCodePtr::Internal(ref mut i) => {
|
*i += emitted_switch_on_constant as usize; // con_loc.is_internal() as usize;
|
||||||
*i += emitted_switch_on_constant as usize; // con_loc.is_internal() as usize;
|
}
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
match &mut lst_loc {
|
if let IndexingCodePtr::Internal(ref mut i) = &mut lst_loc {
|
||||||
IndexingCodePtr::Internal(ref mut i) => {
|
*i += emitted_switch_on_constant as usize; // con_loc.is_internal() as usize;
|
||||||
*i += emitted_switch_on_constant as usize; // con_loc.is_internal() as usize;
|
*i += emitted_switch_on_structure as usize; // str_loc.is_internal() as usize;
|
||||||
*i += emitted_switch_on_structure as usize; // str_loc.is_internal() as usize;
|
}
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
};
|
|
||||||
|
|
||||||
let var_offset = 1 + skip_stub_try_me_else as usize;
|
let var_offset = 1 + skip_stub_try_me_else as usize;
|
||||||
|
|
||||||
|
|||||||
@@ -8,6 +8,7 @@ use std::collections::VecDeque;
|
|||||||
use std::iter::*;
|
use std::iter::*;
|
||||||
use std::vec::Vec;
|
use std::vec::Vec;
|
||||||
|
|
||||||
|
#[allow(clippy::borrowed_box)]
|
||||||
#[derive(Debug, Clone)]
|
#[derive(Debug, Clone)]
|
||||||
pub(crate) enum TermRef<'a> {
|
pub(crate) enum TermRef<'a> {
|
||||||
AnonVar(Level),
|
AnonVar(Level),
|
||||||
@@ -35,6 +36,7 @@ impl<'a> TermRef<'a> {
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
|
#[allow(clippy::borrowed_box)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) enum TermIterState<'a> {
|
pub(crate) enum TermIterState<'a> {
|
||||||
AnonVar(Level),
|
AnonVar(Level),
|
||||||
@@ -113,11 +115,11 @@ impl<'a> QueryIterator<'a> {
|
|||||||
|
|
||||||
fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) {
|
fn extend_state(&mut self, lvl: Level, term: &'a QueryTerm) {
|
||||||
match term {
|
match term {
|
||||||
&QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => {
|
QueryTerm::Clause(ref cell, ClauseType::CallN(_), ref terms, _) => {
|
||||||
self.state_stack
|
self.state_stack
|
||||||
.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms));
|
.push(TermIterState::Clause(lvl, 1, cell, atom!("$call"), terms));
|
||||||
}
|
}
|
||||||
&QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
|
QueryTerm::Clause(ref cell, ref ct, ref terms, _) => {
|
||||||
self.state_stack
|
self.state_stack
|
||||||
.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms));
|
.push(TermIterState::Clause(lvl, 0, cell, ct.name(), terms));
|
||||||
}
|
}
|
||||||
@@ -214,7 +216,7 @@ impl<'a> FactIterator<'a> {
|
|||||||
.push_back(TermIterState::subterm_to_state(lvl, term));
|
.push_back(TermIterState::subterm_to_state(lvl, term));
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn from_rule_head_clause(terms: &'a Vec<Term>) -> Self {
|
pub(crate) fn from_rule_head_clause(terms: &'a [Term]) -> Self {
|
||||||
let state_queue = terms
|
let state_queue = terms
|
||||||
.iter()
|
.iter()
|
||||||
.map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt))
|
.map(|bt| TermIterState::subterm_to_state(Level::Shallow, bt))
|
||||||
@@ -312,14 +314,14 @@ impl<'a> Iterator for FactIterator<'a> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn post_order_iter<'a>(term: &'a Term) -> QueryIterator<'a> {
|
pub(crate) fn post_order_iter(term: &'_ Term) -> QueryIterator {
|
||||||
QueryIterator::from_term(term)
|
QueryIterator::from_term(term)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn breadth_first_iter<'a>(
|
pub(crate) fn breadth_first_iter(
|
||||||
term: &'a Term,
|
term: &'_ Term,
|
||||||
iterable_root: RootIterationPolicy,
|
iterable_root: RootIterationPolicy,
|
||||||
) -> FactIterator<'a> {
|
) -> FactIterator {
|
||||||
FactIterator::new(term, iterable_root)
|
FactIterator::new(term, iterable_root)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -343,7 +345,7 @@ pub(crate) struct ClauseIterator<'a> {
|
|||||||
remaining_chunks_on_stack: usize,
|
remaining_chunks_on_stack: usize,
|
||||||
}
|
}
|
||||||
|
|
||||||
fn state_from_chunked_terms<'a>(chunk_vec: &'a VecDeque<ChunkedTerms>) -> ClauseIteratorState<'a> {
|
fn state_from_chunked_terms(chunk_vec: &'_ VecDeque<ChunkedTerms>) -> ClauseIteratorState {
|
||||||
if chunk_vec.len() == 1 {
|
if chunk_vec.len() == 1 {
|
||||||
if let Some(ChunkedTerms::Branch(ref branches)) = chunk_vec.front() {
|
if let Some(ChunkedTerms::Branch(ref branches)) = chunk_vec.front() {
|
||||||
return ClauseIteratorState::RemainingBranches(branches, 0);
|
return ClauseIteratorState::RemainingBranches(branches, 0);
|
||||||
@@ -422,7 +424,7 @@ impl<'a> Iterator for ClauseIterator<'a> {
|
|||||||
if focus < branches.len() =>
|
if focus < branches.len() =>
|
||||||
{
|
{
|
||||||
self.state_stack
|
self.state_stack
|
||||||
.push(ClauseIteratorState::RemainingBranches(&branches, focus + 1));
|
.push(ClauseIteratorState::RemainingBranches(branches, focus + 1));
|
||||||
let state = state_from_chunked_terms(&branches[focus]);
|
let state = state_from_chunked_terms(&branches[focus]);
|
||||||
|
|
||||||
if let ClauseIteratorState::RemainingChunks(..) = &state {
|
if let ClauseIteratorState::RemainingChunks(..) = &state {
|
||||||
|
|||||||
@@ -3,7 +3,8 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate static_assertions;
|
extern crate static_assertions;
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
#[macro_use] extern crate maplit;
|
#[macro_use]
|
||||||
|
extern crate maplit;
|
||||||
|
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
@@ -50,6 +51,7 @@ use wasm_bindgen::prelude::*;
|
|||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn eval_code(s: &str) -> String {
|
pub fn eval_code(s: &str) -> String {
|
||||||
use machine::mock_wam::*;
|
use machine::mock_wam::*;
|
||||||
|
use web_sys::console;
|
||||||
|
|
||||||
let mut wam = Machine::with_test_streams();
|
let mut wam = Machine::with_test_streams();
|
||||||
let bytes = wam.test_load_string(s);
|
let bytes = wam.test_load_string(s);
|
||||||
|
|||||||
@@ -14,3 +14,9 @@ impl MachineArgs {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for MachineArgs {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use dashu::base::{Abs, Gcd, Signed, UnsignedAbs};
|
use dashu::base::{Abs, Gcd, Signed, UnsignedAbs};
|
||||||
use dashu::integer::IBig;
|
|
||||||
use dashu::integer::fast_div::ConstDivisor;
|
use dashu::integer::fast_div::ConstDivisor;
|
||||||
|
use dashu::integer::IBig;
|
||||||
use divrem::*;
|
use divrem::*;
|
||||||
use num_order::NumOrd;
|
use num_order::NumOrd;
|
||||||
|
|
||||||
@@ -84,18 +84,18 @@ fn numerical_type_error(
|
|||||||
|
|
||||||
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
||||||
if n1 == 0 {
|
if n1 == 0 {
|
||||||
return n2.checked_abs().map(|n| n as isize);
|
return n2.checked_abs();
|
||||||
}
|
}
|
||||||
|
|
||||||
if n2 == 0 {
|
if n2 == 0 {
|
||||||
return n1.checked_abs().map(|n| n as isize);
|
return n1.checked_abs();
|
||||||
}
|
}
|
||||||
|
|
||||||
let n1 = n1.checked_abs();
|
let n1 = n1.checked_abs();
|
||||||
let n2 = n2.checked_abs();
|
let n2 = n2.checked_abs();
|
||||||
|
|
||||||
let mut n1 = if let Some(n1) = n1 { n1 } else { return None };
|
let mut n1 = n1?;
|
||||||
let mut n2 = if let Some(n2) = n2 { n2 } else { return None };
|
let mut n2 = n2?;
|
||||||
|
|
||||||
let mut shift = 0;
|
let mut shift = 0;
|
||||||
|
|
||||||
@@ -115,9 +115,7 @@ fn isize_gcd(n1: isize, n2: isize) -> Option<isize> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if n1 > n2 {
|
if n1 > n2 {
|
||||||
let t = n2;
|
std::mem::swap(&mut n2, &mut n1);
|
||||||
n2 = n1;
|
|
||||||
n1 = t;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
n2 -= n1;
|
n2 -= n1;
|
||||||
@@ -350,22 +348,18 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe
|
|||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
let n1_i = n1.get_num();
|
let n1_i = n1.get_num();
|
||||||
|
|
||||||
if !(n1_i == 1 || n1_i == 0 || n1_i == -1) && &*n2 < &Integer::from(0) {
|
if !(n1_i == 1 || n1_i == 0 || n1_i == -1) && n2.is_zero() {
|
||||||
let n = Number::Fixnum(n1);
|
let n = Number::Fixnum(n1);
|
||||||
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
||||||
} else {
|
} else {
|
||||||
let n1 = Integer::from(n1_i);
|
let n1 = Integer::from(n1_i);
|
||||||
Ok(Number::arena_from(binary_pow(n1, &*n2), arena))
|
Ok(Number::arena_from(binary_pow(n1, &n2), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
let n2_i = n2.get_num();
|
let n2_i = n2.get_num();
|
||||||
|
|
||||||
if !(&*n1 == &Integer::from(1)
|
if !(*n1 == Integer::from(1) || n1.is_zero() || *n1 == Integer::from(-1)) && n2_i < 0 {
|
||||||
|| &*n1 == &Integer::from(0)
|
|
||||||
|| &*n1 == &Integer::from(-1))
|
|
||||||
&& n2_i < 0
|
|
||||||
{
|
|
||||||
let n = Number::Integer(n1);
|
let n = Number::Integer(n1);
|
||||||
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
||||||
} else {
|
} else {
|
||||||
@@ -374,15 +368,13 @@ pub(crate) fn int_pow(n1: Number, n2: Number, arena: &mut Arena) -> Result<Numbe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
if !(&*n1 == &Integer::from(1)
|
if !(*n1 == Integer::from(1) || n1.is_zero() || *n1 == Integer::from(-1))
|
||||||
|| &*n1 == &Integer::from(0)
|
&& n2.is_zero()
|
||||||
|| &*n1 == &Integer::from(-1))
|
|
||||||
&& &*n2 < &Integer::from(0)
|
|
||||||
{
|
{
|
||||||
let n = Number::Integer(n1);
|
let n = Number::Integer(n1);
|
||||||
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
Err(numerical_type_error(ValidType::Float, n, stub_gen))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::arena_from(binary_pow((*n1).clone(), &*n2), arena))
|
Ok(Number::arena_from(binary_pow((*n1).clone(), &n2), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(n1, Number::Integer(n2)) => {
|
(n1, Number::Integer(n2)) => {
|
||||||
@@ -455,14 +447,14 @@ pub(crate) fn max(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
if (&*n2).num_gt(&n1.get_num()) {
|
if (*n2).num_gt(&n1.get_num()) {
|
||||||
Ok(Number::Integer(n2))
|
Ok(Number::Integer(n2))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::Fixnum(n1))
|
Ok(Number::Fixnum(n1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
if (&*n1).num_gt(&n2.get_num()) {
|
if (*n1).num_gt(&n2.get_num()) {
|
||||||
Ok(Number::Integer(n1))
|
Ok(Number::Integer(n1))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::Fixnum(n2))
|
Ok(Number::Fixnum(n2))
|
||||||
@@ -499,14 +491,14 @@ pub(crate) fn min(n1: Number, n2: Number) -> Result<Number, MachineStubGen> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
if (&*n2).num_lt(&n1.get_num()) {
|
if (*n2).num_lt(&n1.get_num()) {
|
||||||
Ok(Number::Integer(n2))
|
Ok(Number::Integer(n2))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::Fixnum(n1))
|
Ok(Number::Fixnum(n1))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
if (&*n1).num_lt(&n2.get_num()) {
|
if (*n1).num_lt(&n2.get_num()) {
|
||||||
Ok(Number::Integer(n1))
|
Ok(Number::Integer(n1))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::Fixnum(n2))
|
Ok(Number::Fixnum(n2))
|
||||||
@@ -583,15 +575,13 @@ pub(crate) fn idiv(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number,
|
|||||||
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
(Number::Fixnum(n1), Number::Fixnum(n2)) => {
|
||||||
if n2.get_num() == 0 {
|
if n2.get_num() == 0 {
|
||||||
Err(zero_divisor_eval_error(stub_gen))
|
Err(zero_divisor_eval_error(stub_gen))
|
||||||
|
} else if let Some(result) = n1.get_num().checked_div(n2.get_num()) {
|
||||||
|
Ok(Number::arena_from(result, arena))
|
||||||
} else {
|
} else {
|
||||||
if let Some(result) = n1.get_num().checked_div(n2.get_num()) {
|
let n1 = Integer::from(n1.get_num());
|
||||||
Ok(Number::arena_from(result, arena))
|
let n2 = Integer::from(n2.get_num());
|
||||||
} else {
|
|
||||||
let n1 = Integer::from(n1.get_num());
|
|
||||||
let n2 = Integer::from(n2.get_num());
|
|
||||||
|
|
||||||
Ok(Number::arena_from(n1 / n2, arena))
|
Ok(Number::arena_from(n1 / n2, arena))
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
@@ -656,9 +646,9 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
let n1 = Integer::from(n1_i);
|
let n1 = Integer::from(n1_i);
|
||||||
|
|
||||||
if let Ok(n2) = usize::try_from(n2_i) {
|
if let Ok(n2) = usize::try_from(n2_i) {
|
||||||
return Ok(Number::arena_from(n1 >> n2, arena));
|
Ok(Number::arena_from(n1 >> n2, arena))
|
||||||
} else {
|
} else {
|
||||||
return Ok(Number::arena_from(n1 >> usize::max_value(), arena));
|
Ok(Number::arena_from(n1 >> usize::max_value(), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
@@ -667,12 +657,8 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
let result: Result<usize, _> = (&*n2).try_into();
|
let result: Result<usize, _> = (&*n2).try_into();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(n2) => {
|
Ok(n2) => Ok(Number::arena_from(n1 >> n2, arena)),
|
||||||
Ok(Number::arena_from(n1 >> n2, arena))
|
Err(_) => Ok(Number::arena_from(n1 >> usize::max_value(), arena)),
|
||||||
}
|
|
||||||
Err(_) => {
|
|
||||||
Ok(Number::arena_from(n1 >> usize::max_value(), arena))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
|
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
|
||||||
@@ -686,14 +672,13 @@ pub(crate) fn shr(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
let result: Result<usize, _> = (&*n2).try_into();
|
let result: Result<usize, _> = (&*n2).try_into();
|
||||||
|
|
||||||
match result {
|
match result {
|
||||||
Ok(n2) => {
|
Ok(n2) => Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena)),
|
||||||
Ok(Number::arena_from(Integer::from(&*n1 >> n2), arena))
|
Err(_) => Ok(Number::arena_from(
|
||||||
}
|
Integer::from(&*n1 >> usize::max_value()),
|
||||||
Err(_) => {
|
arena,
|
||||||
Ok(Number::arena_from(Integer::from(&*n1 >> usize::max_value()), arena))
|
)),
|
||||||
}
|
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
||||||
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
||||||
(n1, _) => Err(numerical_type_error(ValidType::Integer, n1, stub_gen)),
|
(n1, _) => Err(numerical_type_error(ValidType::Integer, n1, stub_gen)),
|
||||||
@@ -718,9 +703,9 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
let n1 = Integer::from(n1_i);
|
let n1 = Integer::from(n1_i);
|
||||||
|
|
||||||
if let Ok(n2) = usize::try_from(n2_i) {
|
if let Ok(n2) = usize::try_from(n2_i) {
|
||||||
return Ok(Number::arena_from(n1 << n2, arena));
|
Ok(Number::arena_from(n1 << n2, arena))
|
||||||
} else {
|
} else {
|
||||||
return Ok(Number::arena_from(n1 << usize::max_value(), arena));
|
Ok(Number::arena_from(n1 << usize::max_value(), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
(Number::Fixnum(n1), Number::Integer(n2)) => {
|
||||||
@@ -730,10 +715,8 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
Ok(n2) => {
|
Ok(n2) => {
|
||||||
let n1: u64 = n1.try_into().unwrap();
|
let n1: u64 = n1.try_into().unwrap();
|
||||||
Ok(Number::arena_from(n1 << n2, arena))
|
Ok(Number::arena_from(n1 << n2, arena))
|
||||||
},
|
}
|
||||||
_ => {
|
_ => Ok(Number::arena_from(n1 << usize::max_value(), arena)),
|
||||||
Ok(Number::arena_from(n1 << usize::max_value(), arena))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
|
(Number::Integer(n1), Number::Fixnum(n2)) => match usize::try_from(n2.get_num()) {
|
||||||
@@ -747,10 +730,11 @@ pub(crate) fn shl(n1: Number, n2: Number, arena: &mut Arena) -> Result<Number, M
|
|||||||
Ok(n2) => {
|
Ok(n2) => {
|
||||||
let n1: u64 = (&*n1).try_into().unwrap();
|
let n1: u64 = (&*n1).try_into().unwrap();
|
||||||
Ok(Number::arena_from(Integer::from(n1 << n2), arena))
|
Ok(Number::arena_from(Integer::from(n1 << n2), arena))
|
||||||
},
|
}
|
||||||
_ => {
|
_ => Ok(Number::arena_from(
|
||||||
Ok(Number::arena_from(Integer::from(&*n1 << usize::max_value()),arena))
|
Integer::from(&*n1 << usize::max_value()),
|
||||||
}
|
arena,
|
||||||
|
)),
|
||||||
},
|
},
|
||||||
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
(Number::Integer(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
||||||
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
(Number::Fixnum(_), n2) => Err(numerical_type_error(ValidType::Integer, n2, stub_gen)),
|
||||||
@@ -882,7 +866,7 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
|
|||||||
Err(zero_divisor_eval_error(stub_gen))
|
Err(zero_divisor_eval_error(stub_gen))
|
||||||
} else {
|
} else {
|
||||||
let n1 = Integer::from(n1.get_num());
|
let n1 = Integer::from(n1.get_num());
|
||||||
Ok(Number::arena_from(ibig_rem_floor(&n1, &*n2), arena))
|
Ok(Number::arena_from(ibig_rem_floor(&n1, &n2), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
(Number::Integer(n1), Number::Fixnum(n2)) => {
|
||||||
@@ -892,14 +876,14 @@ pub(crate) fn modulus(x: Number, y: Number, arena: &mut Arena) -> Result<Number,
|
|||||||
Err(zero_divisor_eval_error(stub_gen))
|
Err(zero_divisor_eval_error(stub_gen))
|
||||||
} else {
|
} else {
|
||||||
let n2 = Integer::from(n2_i);
|
let n2 = Integer::from(n2_i);
|
||||||
Ok(Number::arena_from(ibig_rem_floor(&*n1, &n2), arena))
|
Ok(Number::arena_from(ibig_rem_floor(&n1, &n2), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(n1), Number::Integer(n2)) => {
|
(Number::Integer(n1), Number::Integer(n2)) => {
|
||||||
if n2.is_zero() {
|
if n2.is_zero() {
|
||||||
Err(zero_divisor_eval_error(stub_gen))
|
Err(zero_divisor_eval_error(stub_gen))
|
||||||
} else {
|
} else {
|
||||||
Ok(Number::arena_from(ibig_rem_floor(&*n1, &*n2), arena))
|
Ok(Number::arena_from(ibig_rem_floor(&n1, &n2), arena))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
(Number::Integer(_), n2) | (Number::Fixnum(_), n2) => {
|
||||||
@@ -1145,7 +1129,7 @@ impl MachineState {
|
|||||||
&mut self.interms[i - 1],
|
&mut self.interms[i - 1],
|
||||||
Number::Fixnum(Fixnum::build_with(0)),
|
Number::Fixnum(Fixnum::build_with(0)),
|
||||||
)),
|
)),
|
||||||
&ArithmeticTerm::Number(n) => Ok(n),
|
ArithmeticTerm::Number(n) => Ok(*n),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1167,8 +1151,8 @@ impl MachineState {
|
|||||||
value: HeapCellValue,
|
value: HeapCellValue,
|
||||||
) -> Result<Number, MachineStub> {
|
) -> Result<Number, MachineStub> {
|
||||||
let stub_gen = || functor_stub(atom!("is"), 2);
|
let stub_gen = || functor_stub(atom!("is"), 2);
|
||||||
let mut iter = stackful_post_order_iter::<NonListElider>
|
let mut iter =
|
||||||
(&mut self.heap, &mut self.stack, value);
|
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, value);
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
while let Some(value) = iter.next() {
|
||||||
if value.get_forwarding_bit() {
|
if value.get_forwarding_bit() {
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ impl MachineState {
|
|||||||
let mut seen_set = IndexSet::new();
|
let mut seen_set = IndexSet::new();
|
||||||
let mut seen_vars = vec![];
|
let mut seen_vars = vec![];
|
||||||
|
|
||||||
let mut iter = stackful_preorder_iter::<NonListElider>
|
let mut iter =
|
||||||
(&mut self.heap, &mut self.stack, cell);
|
stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, cell);
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
while let Some(value) = iter.next() {
|
||||||
read_heap_cell!(value,
|
read_heap_cell!(value,
|
||||||
|
|||||||
@@ -282,28 +282,25 @@ fn merge_indexed_subsequences(
|
|||||||
.unwrap(),
|
.unwrap(),
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut code[inner_try_me_else_loc] {
|
if let Instruction::TryMeElse(ref mut o) = &mut code[inner_try_me_else_loc] {
|
||||||
Instruction::TryMeElse(ref mut o) => {
|
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
||||||
retraction_info.push_record(RetractionRecord::ModifiedTryMeElse(
|
inner_try_me_else_loc,
|
||||||
inner_try_me_else_loc,
|
*o,
|
||||||
*o,
|
));
|
||||||
));
|
|
||||||
|
|
||||||
match *o {
|
match *o {
|
||||||
0 => {
|
0 => {
|
||||||
code[inner_try_me_else_loc] = Instruction::TrustMe(0);
|
code[inner_try_me_else_loc] = Instruction::TrustMe(0);
|
||||||
}
|
|
||||||
o => match &code[inner_try_me_else_loc + o] {
|
|
||||||
Instruction::RevJmpBy(0) => {
|
|
||||||
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
code[inner_try_me_else_loc] = Instruction::RetryMeElse(o);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
o => match &code[inner_try_me_else_loc + o] {
|
||||||
|
Instruction::RevJmpBy(0) => {
|
||||||
|
code[inner_try_me_else_loc] = Instruction::TrustMe(o);
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
code[inner_try_me_else_loc] = Instruction::RetryMeElse(o);
|
||||||
|
}
|
||||||
|
},
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
thread_choice_instr_at_to(
|
thread_choice_instr_at_to(
|
||||||
@@ -333,8 +330,8 @@ fn merge_indexed_subsequences(
|
|||||||
retraction_info,
|
retraction_info,
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
None => match &mut code[outer_threaded_choice_instr_loc] {
|
None => {
|
||||||
Instruction::TryMeElse(ref mut o) => {
|
if let Instruction::TryMeElse(ref mut o) = &mut code[outer_threaded_choice_instr_loc] {
|
||||||
retraction_info
|
retraction_info
|
||||||
.push_record(RetractionRecord::ModifiedTryMeElse(inner_trust_me_loc, *o));
|
.push_record(RetractionRecord::ModifiedTryMeElse(inner_trust_me_loc, *o));
|
||||||
|
|
||||||
@@ -342,8 +339,7 @@ fn merge_indexed_subsequences(
|
|||||||
|
|
||||||
return Some(IndexPtr::index(outer_threaded_choice_instr_loc + 1));
|
return Some(IndexPtr::index(outer_threaded_choice_instr_loc + 1));
|
||||||
}
|
}
|
||||||
_ => {}
|
}
|
||||||
},
|
|
||||||
}
|
}
|
||||||
|
|
||||||
None
|
None
|
||||||
@@ -919,7 +915,7 @@ fn prepend_compiled_clause(
|
|||||||
retraction_info,
|
retraction_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
code.extend(prepend_queue.into_iter());
|
code.extend(prepend_queue);
|
||||||
|
|
||||||
if skeleton.core.is_dynamic {
|
if skeleton.core.is_dynamic {
|
||||||
clause_loc
|
clause_loc
|
||||||
@@ -975,7 +971,7 @@ fn prepend_compiled_clause(
|
|||||||
|
|
||||||
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
||||||
|
|
||||||
code.extend(prepend_queue.into_iter());
|
code.extend(prepend_queue);
|
||||||
|
|
||||||
clause_loc // + (outer_thread_choice_offset == 0 as usize)
|
clause_loc // + (outer_thread_choice_offset == 0 as usize)
|
||||||
}
|
}
|
||||||
@@ -1004,7 +1000,7 @@ fn prepend_compiled_clause(
|
|||||||
|
|
||||||
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
||||||
|
|
||||||
code.extend(prepend_queue.into_iter());
|
code.extend(prepend_queue);
|
||||||
|
|
||||||
// skeleton.clauses[0].opt_arg_index_key += clause_loc;
|
// skeleton.clauses[0].opt_arg_index_key += clause_loc;
|
||||||
skeleton.clauses[0].clause_start = clause_loc;
|
skeleton.clauses[0].clause_start = clause_loc;
|
||||||
@@ -1029,7 +1025,7 @@ fn prepend_compiled_clause(
|
|||||||
|
|
||||||
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
internalize_choice_instr_at(code, old_clause_start, retraction_info);
|
||||||
|
|
||||||
code.extend(prepend_queue.into_iter());
|
code.extend(prepend_queue);
|
||||||
|
|
||||||
// skeleton.clauses[0].opt_arg_index_key += clause_loc;
|
// skeleton.clauses[0].opt_arg_index_key += clause_loc;
|
||||||
skeleton.clauses[0].clause_start = clause_loc;
|
skeleton.clauses[0].clause_start = clause_loc;
|
||||||
@@ -1134,21 +1130,18 @@ fn append_compiled_clause(
|
|||||||
skeleton.clauses[target_pos].opt_arg_index_key += clause_loc;
|
skeleton.clauses[target_pos].opt_arg_index_key += clause_loc;
|
||||||
code.extend(clause_code.drain(1..));
|
code.extend(clause_code.drain(1..));
|
||||||
|
|
||||||
match skeleton.clauses[target_pos]
|
if let Some(index_loc) = skeleton.clauses[target_pos]
|
||||||
.opt_arg_index_key
|
.opt_arg_index_key
|
||||||
.switch_on_term_loc()
|
.switch_on_term_loc()
|
||||||
{
|
{
|
||||||
Some(index_loc) => {
|
// point to the inner-threaded TryMeElse(0) if target_pos is
|
||||||
// point to the inner-threaded TryMeElse(0) if target_pos is
|
// indexed, and make switch_on_term point one line after it in
|
||||||
// indexed, and make switch_on_term point one line after it in
|
// its variable offset.
|
||||||
// its variable offset.
|
skeleton.clauses[target_pos].clause_start += 2;
|
||||||
skeleton.clauses[target_pos].clause_start += 2;
|
|
||||||
|
|
||||||
if !skeleton.core.is_dynamic {
|
if !skeleton.core.is_dynamic {
|
||||||
set_switch_var_offset(code, index_loc, 2, retraction_info);
|
set_switch_var_offset(code, index_loc, 2, retraction_info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match skeleton.clauses[lower_bound]
|
match skeleton.clauses[lower_bound]
|
||||||
@@ -1302,11 +1295,8 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
clause_clause_locs.push_back(clause_index_info.clause_start);
|
clause_clause_locs.push_back(clause_index_info.clause_start);
|
||||||
}
|
}
|
||||||
|
|
||||||
match &mut code[0] {
|
if let Instruction::TryMeElse(0) = &mut code[0] {
|
||||||
Instruction::TryMeElse(0) => {
|
code_ptr += 1;
|
||||||
code_ptr += 1;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match self
|
match self
|
||||||
@@ -1317,7 +1307,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
Some(skeleton) => {
|
Some(skeleton) => {
|
||||||
let skeleton_clause_len = skeleton.clauses.len();
|
let skeleton_clause_len = skeleton.clauses.len();
|
||||||
|
|
||||||
skeleton.clauses.extend(cg.skeleton.clauses.into_iter());
|
skeleton.clauses.extend(cg.skeleton.clauses);
|
||||||
skeleton
|
skeleton
|
||||||
.core
|
.core
|
||||||
.clause_clause_locs
|
.clause_clause_locs
|
||||||
@@ -1371,7 +1361,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
index_ptr,
|
index_ptr,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.wam_prelude.code.extend(code.into_iter());
|
self.wam_prelude.code.extend(code);
|
||||||
Ok(code_index)
|
Ok(code_index)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1563,7 +1553,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||||
|
|
||||||
let result = append_compiled_clause(
|
let result = append_compiled_clause(
|
||||||
&mut self.wam_prelude.code,
|
self.wam_prelude.code,
|
||||||
clause_code,
|
clause_code,
|
||||||
skeleton,
|
skeleton,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
@@ -1603,7 +1593,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
let global_clock = LS::machine_st(&mut self.payload).global_clock;
|
||||||
|
|
||||||
let new_code_ptr = prepend_compiled_clause(
|
let new_code_ptr = prepend_compiled_clause(
|
||||||
&mut self.wam_prelude.code,
|
self.wam_prelude.code,
|
||||||
compilation_target,
|
compilation_target,
|
||||||
key,
|
key,
|
||||||
clause_code,
|
clause_code,
|
||||||
@@ -1646,7 +1636,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
.switch_on_term_loc()
|
.switch_on_term_loc()
|
||||||
{
|
{
|
||||||
Some(index_loc) => find_inner_choice_instr(
|
Some(index_loc) => find_inner_choice_instr(
|
||||||
&self.wam_prelude.code,
|
self.wam_prelude.code,
|
||||||
skeleton.clauses[target_pos].clause_start,
|
skeleton.clauses[target_pos].clause_start,
|
||||||
index_loc,
|
index_loc,
|
||||||
),
|
),
|
||||||
@@ -1687,115 +1677,109 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
if target_pos == 0 || (lower_bound + 1 == target_pos && lower_bound_is_unindexed) {
|
if target_pos == 0 || (lower_bound + 1 == target_pos && lower_bound_is_unindexed) {
|
||||||
// the clause preceding target_pos, if there is one, is of
|
// the clause preceding target_pos, if there is one, is of
|
||||||
// key type OptArgIndexKey::None.
|
// key type OptArgIndexKey::None.
|
||||||
match skeleton.clauses[target_pos]
|
if let Some(index_loc) = skeleton.clauses[target_pos]
|
||||||
.opt_arg_index_key
|
.opt_arg_index_key
|
||||||
.switch_on_term_loc()
|
.switch_on_term_loc()
|
||||||
{
|
{
|
||||||
Some(index_loc) => {
|
let inner_clause_start = find_inner_choice_instr(
|
||||||
let inner_clause_start = find_inner_choice_instr(
|
code,
|
||||||
code,
|
skeleton.clauses[target_pos].clause_start,
|
||||||
skeleton.clauses[target_pos].clause_start,
|
index_loc,
|
||||||
index_loc,
|
);
|
||||||
);
|
|
||||||
|
|
||||||
remove_index_from_subsequence(
|
remove_index_from_subsequence(
|
||||||
code,
|
code,
|
||||||
&skeleton.clauses[target_pos].opt_arg_index_key,
|
&skeleton.clauses[target_pos].opt_arg_index_key,
|
||||||
inner_clause_start,
|
inner_clause_start,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
match derelictize_try_me_else(
|
match derelictize_try_me_else(
|
||||||
code,
|
code,
|
||||||
inner_clause_start,
|
inner_clause_start,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
) {
|
) {
|
||||||
Some(offset) => {
|
Some(offset) => {
|
||||||
let instr_loc = find_inner_choice_instr(
|
let instr_loc =
|
||||||
code,
|
find_inner_choice_instr(code, inner_clause_start + offset, index_loc);
|
||||||
inner_clause_start + offset,
|
|
||||||
index_loc,
|
|
||||||
);
|
|
||||||
|
|
||||||
let clause_loc = blunt_leading_choice_instr(
|
let clause_loc = blunt_leading_choice_instr(
|
||||||
code,
|
code,
|
||||||
instr_loc,
|
instr_loc,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
set_switch_var_offset(
|
set_switch_var_offset(
|
||||||
code,
|
code,
|
||||||
index_loc,
|
index_loc,
|
||||||
clause_loc - index_loc,
|
clause_loc - index_loc,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.payload.retraction_info.push_record(
|
self.payload.retraction_info.push_record(
|
||||||
RetractionRecord::SkeletonClauseStartReplaced(
|
RetractionRecord::SkeletonClauseStartReplaced(
|
||||||
payload_compilation_target,
|
|
||||||
key,
|
|
||||||
target_pos + 1,
|
|
||||||
skeleton.clauses[target_pos + 1].clause_start,
|
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
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 index_ptr_opt = if update_code_index {
|
|
||||||
Some(IndexPtr::index(clause_loc))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
|
|
||||||
return finalize_retract(
|
|
||||||
key,
|
|
||||||
payload_compilation_target,
|
payload_compilation_target,
|
||||||
skeleton,
|
|
||||||
code_index,
|
|
||||||
target_pos,
|
|
||||||
index_ptr_opt,
|
|
||||||
&mut self.payload.retraction_info,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
let index_ptr_opt = if target_pos > 0 {
|
|
||||||
let preceding_choice_instr_loc =
|
|
||||||
skeleton.clauses[target_pos - 1].clause_start;
|
|
||||||
|
|
||||||
remove_non_leading_clause(
|
|
||||||
code,
|
|
||||||
preceding_choice_instr_loc,
|
|
||||||
skeleton.clauses[target_pos].clause_start - 2,
|
|
||||||
&mut self.payload.retraction_info,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
remove_leading_unindexed_clause(
|
|
||||||
code,
|
|
||||||
skeleton.clauses[target_pos].clause_start - 2,
|
|
||||||
&mut self.payload.retraction_info,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
return finalize_retract(
|
|
||||||
key,
|
key,
|
||||||
payload_compilation_target,
|
target_pos + 1,
|
||||||
skeleton,
|
skeleton.clauses[target_pos + 1].clause_start,
|
||||||
code_index,
|
),
|
||||||
target_pos,
|
);
|
||||||
index_ptr_opt,
|
|
||||||
|
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 index_ptr_opt = if update_code_index {
|
||||||
|
Some(IndexPtr::index(clause_loc))
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
};
|
||||||
|
|
||||||
|
return finalize_retract(
|
||||||
|
key,
|
||||||
|
payload_compilation_target,
|
||||||
|
skeleton,
|
||||||
|
code_index,
|
||||||
|
target_pos,
|
||||||
|
index_ptr_opt,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
None => {
|
||||||
|
let index_ptr_opt = if target_pos > 0 {
|
||||||
|
let preceding_choice_instr_loc =
|
||||||
|
skeleton.clauses[target_pos - 1].clause_start;
|
||||||
|
|
||||||
|
remove_non_leading_clause(
|
||||||
|
code,
|
||||||
|
preceding_choice_instr_loc,
|
||||||
|
skeleton.clauses[target_pos].clause_start - 2,
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
)
|
||||||
}
|
} else {
|
||||||
|
remove_leading_unindexed_clause(
|
||||||
|
code,
|
||||||
|
skeleton.clauses[target_pos].clause_start - 2,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
)
|
||||||
|
};
|
||||||
|
|
||||||
|
return finalize_retract(
|
||||||
|
key,
|
||||||
|
payload_compilation_target,
|
||||||
|
skeleton,
|
||||||
|
code_index,
|
||||||
|
target_pos,
|
||||||
|
index_ptr_opt,
|
||||||
|
&mut self.payload.retraction_info,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1824,16 +1808,13 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
Instruction::RevJmpBy(target_indexing_loc - later_indexing_loc),
|
Instruction::RevJmpBy(target_indexing_loc - later_indexing_loc),
|
||||||
);
|
);
|
||||||
|
|
||||||
match target_indexing_line {
|
if let Instruction::IndexingCode(indexing_code) = target_indexing_line {
|
||||||
Instruction::IndexingCode(indexing_code) => {
|
self.payload.retraction_info.push_record(
|
||||||
self.payload.retraction_info.push_record(
|
RetractionRecord::ReplacedIndexingLine(
|
||||||
RetractionRecord::ReplacedIndexingLine(
|
target_indexing_loc,
|
||||||
target_indexing_loc,
|
indexing_code,
|
||||||
indexing_code,
|
),
|
||||||
),
|
);
|
||||||
);
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = merge_indexed_subsequences(
|
result = merge_indexed_subsequences(
|
||||||
@@ -1977,16 +1958,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
);
|
);
|
||||||
|
|
||||||
match &mut code[preceding_choice_instr_loc] {
|
if let Instruction::TryMeElse(0) =
|
||||||
Instruction::TryMeElse(0) => {
|
&mut code[preceding_choice_instr_loc]
|
||||||
set_switch_var_offset(
|
{
|
||||||
code,
|
set_switch_var_offset(
|
||||||
index_loc,
|
code,
|
||||||
preceding_choice_instr_loc + 1 - index_loc,
|
index_loc,
|
||||||
&mut self.payload.retraction_info,
|
preceding_choice_instr_loc + 1 - index_loc,
|
||||||
);
|
&mut self.payload.retraction_info,
|
||||||
}
|
);
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2068,16 +2048,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
{
|
{
|
||||||
Some(skeleton) if append_or_prepend.is_append() => {
|
Some(skeleton) if append_or_prepend.is_append() => {
|
||||||
let tail_num = skeleton.core.clause_clause_locs.len() - num_clause_predicates;
|
let tail_num = skeleton.core.clause_clause_locs.len() - num_clause_predicates;
|
||||||
skeleton.core.clause_clause_locs.make_contiguous()[tail_num..]
|
skeleton.core.clause_clause_locs.make_contiguous()[tail_num..].to_vec()
|
||||||
.iter()
|
|
||||||
.cloned()
|
|
||||||
.collect()
|
|
||||||
}
|
}
|
||||||
Some(skeleton) => skeleton.core.clause_clause_locs.make_contiguous()
|
Some(skeleton) => skeleton.core.clause_clause_locs.make_contiguous()
|
||||||
[0..num_clause_predicates]
|
[0..num_clause_predicates]
|
||||||
.iter()
|
.to_vec(),
|
||||||
.cloned()
|
|
||||||
.collect(),
|
|
||||||
None => {
|
None => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -2205,46 +2180,47 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
)?;
|
)?;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if is_cross_module_clause {
|
if is_cross_module_clause && !local_predicate_info.is_extensible {
|
||||||
if !local_predicate_info.is_extensible {
|
if predicate_info.is_multifile {
|
||||||
if predicate_info.is_multifile {
|
println!(
|
||||||
println!(
|
"Warning: overwriting multifile predicate {}:{}/{} because \
|
||||||
"Warning: overwriting multifile predicate {}:{}/{} because \
|
it was not locally declared multifile.",
|
||||||
it was not locally declared multifile.",
|
self.payload.predicates.compilation_target,
|
||||||
self.payload.predicates.compilation_target,
|
key.0.as_str(),
|
||||||
key.0.as_str(),
|
key.1
|
||||||
key.1
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
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,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.retract_local_clauses_by_locs(
|
||||||
|
clause_clause_compilation_target,
|
||||||
|
(atom!("$clause"), 2),
|
||||||
|
(0..skeleton.clauses.len()).map(Some).collect(),
|
||||||
|
false, // the builtin M:'$clause'/2 is never dynamic.
|
||||||
);
|
);
|
||||||
|
|
||||||
|
predicate_info.is_dynamic = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(skeleton) = self.wam_prelude.indices.remove_predicate_skeleton(
|
self.payload
|
||||||
&self.payload.predicates.compilation_target,
|
.retraction_info
|
||||||
&key,
|
.push_record(RetractionRecord::RemovedSkeleton(
|
||||||
) {
|
compilation_target,
|
||||||
let compilation_target = self.payload.predicates.compilation_target;
|
key,
|
||||||
|
skeleton,
|
||||||
if predicate_info.is_dynamic {
|
));
|
||||||
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,
|
|
||||||
(atom!("$clause"), 2),
|
|
||||||
(0..skeleton.clauses.len()).map(Some).collect(),
|
|
||||||
false, // the builtin M:'$clause'/2 is never dynamic.
|
|
||||||
);
|
|
||||||
|
|
||||||
predicate_info.is_dynamic = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
self.payload.retraction_info.push_record(
|
|
||||||
RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2262,20 +2238,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let code_index = self.compile(key, predicates, settings)?;
|
let code_index = self.compile(key, predicates, settings)?;
|
||||||
|
|
||||||
if let Some(filename) = self.listing_src_file_name() {
|
if let Some(filename) = self.listing_src_file_name() {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&filename) {
|
if let Some(ref mut module) = self.wam_prelude.indices.modules.get_mut(&filename) {
|
||||||
Some(ref mut module) => {
|
let index_ptr = code_index.get();
|
||||||
let index_ptr = code_index.get();
|
let code_index = *module.code_dir.entry(key).or_insert(code_index);
|
||||||
let code_index = module.code_dir.entry(key).or_insert(code_index).clone();
|
|
||||||
|
|
||||||
set_code_index(
|
set_code_index(
|
||||||
&mut self.payload.retraction_info,
|
&mut self.payload.retraction_info,
|
||||||
&CompilationTarget::Module(filename),
|
&CompilationTarget::Module(filename),
|
||||||
key,
|
key,
|
||||||
code_index,
|
code_index,
|
||||||
index_ptr,
|
index_ptr,
|
||||||
);
|
);
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -2344,7 +2317,7 @@ impl Machine {
|
|||||||
};
|
};
|
||||||
|
|
||||||
let StandaloneCompileResult { clause_code, .. } = compile()?;
|
let StandaloneCompileResult { clause_code, .. } = compile()?;
|
||||||
self.code.extend(clause_code.into_iter());
|
self.code.extend(clause_code);
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -174,7 +174,7 @@ impl<T: CopierTarget> CopyTermState<T> {
|
|||||||
|
|
||||||
fn copy_attr_var_lists(&mut self) {
|
fn copy_attr_var_lists(&mut self) {
|
||||||
while !self.attr_var_list_locs.is_empty() {
|
while !self.attr_var_list_locs.is_empty() {
|
||||||
let iter = mem::replace(&mut self.attr_var_list_locs, vec![]);
|
let iter = std::mem::take(&mut self.attr_var_list_locs);
|
||||||
|
|
||||||
for (threshold, list_loc) in iter {
|
for (threshold, list_loc) in iter {
|
||||||
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
|
self.target[threshold] = list_loc_as_cell!(self.target.threshold());
|
||||||
|
|||||||
@@ -73,7 +73,7 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
fn traverse_subterm(&mut self, h: usize, arity: usize) -> Option<usize> {
|
fn traverse_subterm(&mut self, h: usize, arity: usize) -> Option<usize> {
|
||||||
let mut last_cell_loc = h + arity - 1;
|
let mut last_cell_loc = h + arity - 1;
|
||||||
|
|
||||||
for idx in (h .. h + arity).rev() {
|
for idx in (h..h + arity).rev() {
|
||||||
if self.heap[idx].get_forwarding_bit() {
|
if self.heap[idx].get_forwarding_bit() {
|
||||||
if self.cycle_detection_active() {
|
if self.cycle_detection_active() {
|
||||||
self.cycle_found = true;
|
self.cycle_found = true;
|
||||||
@@ -93,8 +93,8 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn continue_forwarding(&self) -> bool {
|
fn continue_forwarding(&self) -> bool {
|
||||||
self.heap[self.current].get_mark_bit() != self.mark_phase ||
|
self.heap[self.current].get_mark_bit() != self.mark_phase
|
||||||
self.heap[self.current].get_forwarding_bit()
|
|| self.heap[self.current].get_forwarding_bit()
|
||||||
}
|
}
|
||||||
|
|
||||||
fn forward(&mut self) -> Option<HeapCellValue> {
|
fn forward(&mut self) -> Option<HeapCellValue> {
|
||||||
@@ -150,7 +150,7 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if self.cycle_detection_active() {
|
if self.cycle_detection_active() {
|
||||||
for idx in (h + 1 .. last_cell_loc).rev() {
|
for idx in (h + 1..last_cell_loc).rev() {
|
||||||
if self.heap[idx].get_forwarding_bit() {
|
if self.heap[idx].get_forwarding_bit() {
|
||||||
self.cycle_found = true;
|
self.cycle_found = true;
|
||||||
return None;
|
return None;
|
||||||
@@ -176,7 +176,7 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
};
|
};
|
||||||
|
|
||||||
if self.cycle_detection_active() {
|
if self.cycle_detection_active() {
|
||||||
for idx in (self.next as usize .. last_cell_loc).rev() {
|
for idx in (self.next as usize..last_cell_loc).rev() {
|
||||||
if self.heap[idx].get_forwarding_bit() {
|
if self.heap[idx].get_forwarding_bit() {
|
||||||
self.cycle_found = true;
|
self.cycle_found = true;
|
||||||
return None;
|
return None;
|
||||||
@@ -309,19 +309,19 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
HeapCellValueTag::Str => {
|
HeapCellValueTag::Str => {
|
||||||
let mut new_str_back_link = self.current;
|
let mut new_str_back_link = self.current;
|
||||||
|
|
||||||
for idx in (0 .. self.current).rev() {
|
for idx in (0..self.current).rev() {
|
||||||
if self.heap[idx].get_tag() == HeapCellValueTag::Atom {
|
if self.heap[idx].get_tag() == HeapCellValueTag::Atom
|
||||||
if cell_as_atom_cell!(self.heap[idx]).get_arity() > 0 {
|
&& cell_as_atom_cell!(self.heap[idx]).get_arity() > 0
|
||||||
new_str_back_link = idx;
|
{
|
||||||
break;
|
new_str_back_link = idx;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.heap[idx].get_mark_bit() != self.mark_phase {
|
if self.heap[idx].get_mark_bit() != self.mark_phase
|
||||||
if !self.heap[idx].get_forwarding_bit() {
|
&& !self.heap[idx].get_forwarding_bit()
|
||||||
new_str_back_link = idx;
|
{
|
||||||
break;
|
new_str_back_link = idx;
|
||||||
}
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -402,7 +402,7 @@ impl<'a, const STOP_AT_CYCLES: bool> CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
|||||||
self.next = self.heap[self.start].get_value();
|
self.next = self.heap[self.start].get_value();
|
||||||
self.current = self.start;
|
self.current = self.start;
|
||||||
|
|
||||||
while let Some(_) = self.forward() {}
|
while self.forward().is_some() {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -415,7 +415,6 @@ impl<'a, const STOP_AT_CYCLES: bool> Iterator for CycleDetectingIter<'a, STOP_AT
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
impl<'a, const STOP_AT_CYCLES: bool> Drop for CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
impl<'a, const STOP_AT_CYCLES: bool> Drop for CycleDetectingIter<'a, STOP_AT_CYCLES> {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
self.invert_marker();
|
self.invert_marker();
|
||||||
|
|||||||
@@ -226,7 +226,7 @@ fn merge_branch_seq(branches: impl Iterator<Item = BranchInfo>) -> BranchInfo {
|
|||||||
|
|
||||||
for mut branch in branches {
|
for mut branch in branches {
|
||||||
branch_info.branch_num = branch.branch_num;
|
branch_info.branch_num = branch.branch_num;
|
||||||
branch_info.chunks.extend(branch.chunks.drain(..));
|
branch_info.chunks.append(&mut branch.chunks);
|
||||||
}
|
}
|
||||||
|
|
||||||
branch_info.branch_num.delta = branch_info.branch_num.delta * Integer::from(2);
|
branch_info.branch_num.delta = branch_info.branch_num.delta * Integer::from(2);
|
||||||
@@ -298,7 +298,7 @@ impl VariableClassifier {
|
|||||||
|
|
||||||
fn merge_branches(&mut self) {
|
fn merge_branches(&mut self) {
|
||||||
for branches in self.branch_map.values_mut() {
|
for branches in self.branch_map.values_mut() {
|
||||||
let mut old_branches = std::mem::replace(branches, vec![]);
|
let mut old_branches = std::mem::take(branches);
|
||||||
|
|
||||||
while let Some(last_branch_num) = old_branches.last().map(|bi| &bi.branch_num) {
|
while let Some(last_branch_num) = old_branches.last().map(|bi| &bi.branch_num) {
|
||||||
let mut old_branches_len = old_branches.len();
|
let mut old_branches_len = old_branches.len();
|
||||||
@@ -361,10 +361,7 @@ impl VariableClassifier {
|
|||||||
.current_chunk_type
|
.current_chunk_type
|
||||||
.to_gen_context(self.current_chunk_num);
|
.to_gen_context(self.current_chunk_num);
|
||||||
|
|
||||||
let branch_info_v = self
|
let branch_info_v = self.branch_map.entry(var_info.var_ptr.clone()).or_default();
|
||||||
.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() {
|
let needs_new_branch = if let Some(last_bi) = branch_info_v.last() {
|
||||||
!self.root_set.contains(&last_bi.branch_num)
|
!self.root_set.contains(&last_bi.branch_num)
|
||||||
@@ -420,56 +417,49 @@ impl VariableClassifier {
|
|||||||
arity: term.arity(),
|
arity: term.arity(),
|
||||||
};
|
};
|
||||||
|
|
||||||
match term {
|
if let Term::Clause(_, _, terms) = term {
|
||||||
Term::Clause(_, _, terms) => {
|
for term in terms.iter() {
|
||||||
for term in terms.into_iter() {
|
for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) {
|
||||||
for term_ref in breadth_first_iter(term, RootIterationPolicy::Iterated) {
|
if let TermRef::Var(lvl, _, var_ptr) = term_ref {
|
||||||
if let TermRef::Var(lvl, _, var_ptr) = term_ref {
|
// a body term, so we need the child level here.
|
||||||
// a body term, so we need the child level here.
|
let lvl = lvl.child_level();
|
||||||
let lvl = lvl.child_level();
|
|
||||||
|
|
||||||
// the body of the if let here is an inlined
|
// the body of the if let here is an inlined
|
||||||
// "probe_head_var". note the difference between it
|
// "probe_head_var". note the difference between it
|
||||||
// and "probe_body_var".
|
// and "probe_body_var".
|
||||||
let branch_info_v = self
|
let branch_info_v = self.branch_map.entry(var_ptr.clone()).or_default();
|
||||||
.branch_map
|
|
||||||
.entry(var_ptr.clone())
|
|
||||||
.or_insert_with(|| vec![]);
|
|
||||||
|
|
||||||
let needs_new_branch = branch_info_v.is_empty();
|
let needs_new_branch = branch_info_v.is_empty();
|
||||||
|
|
||||||
if needs_new_branch {
|
if needs_new_branch {
|
||||||
branch_info_v
|
branch_info_v.push(BranchInfo::new(self.current_branch_num.clone()));
|
||||||
.push(BranchInfo::new(self.current_branch_num.clone()));
|
|
||||||
}
|
|
||||||
|
|
||||||
let branch_info = branch_info_v.last_mut().unwrap();
|
|
||||||
let needs_new_chunk = branch_info.chunks.is_empty();
|
|
||||||
|
|
||||||
if needs_new_chunk {
|
|
||||||
branch_info.chunks.push(ChunkInfo {
|
|
||||||
chunk_num: self.current_chunk_num,
|
|
||||||
term_loc: GenContext::Head,
|
|
||||||
vars: vec![],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
let chunk_info = branch_info.chunks.last_mut().unwrap();
|
|
||||||
let var_info = VarInfo {
|
|
||||||
var_ptr,
|
|
||||||
classify_info,
|
|
||||||
chunk_type: self.current_chunk_type,
|
|
||||||
lvl,
|
|
||||||
};
|
|
||||||
|
|
||||||
chunk_info.vars.push(var_info);
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
classify_info.arg_c += 1;
|
let branch_info = branch_info_v.last_mut().unwrap();
|
||||||
|
let needs_new_chunk = branch_info.chunks.is_empty();
|
||||||
|
|
||||||
|
if needs_new_chunk {
|
||||||
|
branch_info.chunks.push(ChunkInfo {
|
||||||
|
chunk_num: self.current_chunk_num,
|
||||||
|
term_loc: GenContext::Head,
|
||||||
|
vars: vec![],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
let chunk_info = branch_info.chunks.last_mut().unwrap();
|
||||||
|
let var_info = VarInfo {
|
||||||
|
var_ptr,
|
||||||
|
classify_info,
|
||||||
|
chunk_type: self.current_chunk_type,
|
||||||
|
lvl,
|
||||||
|
};
|
||||||
|
|
||||||
|
chunk_info.vars.push(var_info);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
classify_info.arg_c += 1;
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@@ -538,7 +528,10 @@ impl VariableClassifier {
|
|||||||
build_stack.push_chunk_term(if is_global {
|
build_stack.push_chunk_term(if is_global {
|
||||||
QueryTerm::GlobalCut(var_num)
|
QueryTerm::GlobalCut(var_num)
|
||||||
} else {
|
} else {
|
||||||
QueryTerm::LocalCut { var_num, cut_prev: false }
|
QueryTerm::LocalCut {
|
||||||
|
var_num,
|
||||||
|
cut_prev: false,
|
||||||
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
TraversalState::CutPrev(var_num) => {
|
TraversalState::CutPrev(var_num) => {
|
||||||
@@ -548,7 +541,10 @@ impl VariableClassifier {
|
|||||||
|
|
||||||
self.probe_in_situ_var(var_num);
|
self.probe_in_situ_var(var_num);
|
||||||
|
|
||||||
build_stack.push_chunk_term(QueryTerm::LocalCut { var_num, cut_prev: true });
|
build_stack.push_chunk_term(QueryTerm::LocalCut {
|
||||||
|
var_num,
|
||||||
|
cut_prev: true,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
TraversalState::Fail => {
|
TraversalState::Fail => {
|
||||||
build_stack.push_chunk_term(QueryTerm::Fail);
|
build_stack.push_chunk_term(QueryTerm::Fail);
|
||||||
@@ -705,7 +701,9 @@ impl VariableClassifier {
|
|||||||
state_stack.push(TraversalState::BuildDisjunct(build_stack_len));
|
state_stack.push(TraversalState::BuildDisjunct(build_stack_len));
|
||||||
state_stack.push(TraversalState::Fail);
|
state_stack.push(TraversalState::Fail);
|
||||||
state_stack.push(TraversalState::CutPrev(self.var_num));
|
state_stack.push(TraversalState::CutPrev(self.var_num));
|
||||||
state_stack.push(TraversalState::ResetGlobalCutVarOverride(self.global_cut_var_num_override));
|
state_stack.push(TraversalState::ResetGlobalCutVarOverride(
|
||||||
|
self.global_cut_var_num_override,
|
||||||
|
));
|
||||||
state_stack.push(TraversalState::Term(not_term));
|
state_stack.push(TraversalState::Term(not_term));
|
||||||
state_stack.push(TraversalState::OverrideGlobalCutVar(self.var_num));
|
state_stack.push(TraversalState::OverrideGlobalCutVar(self.var_num));
|
||||||
state_stack.push(TraversalState::GetCutPoint {
|
state_stack.push(TraversalState::GetCutPoint {
|
||||||
|
|||||||
@@ -313,8 +313,8 @@ impl MachineState {
|
|||||||
impl Machine {
|
impl Machine {
|
||||||
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
|
pub(super) fn find_living_dynamic_else(&self, mut p: usize) -> Option<(usize, usize)> {
|
||||||
loop {
|
loop {
|
||||||
match &self.code[p] {
|
match self.code[p] {
|
||||||
&Instruction::DynamicElse(birth, death, NextOrFail::Next(i)) => {
|
Instruction::DynamicElse(birth, death, NextOrFail::Next(i)) => {
|
||||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||||
return Some((p, i));
|
return Some((p, i));
|
||||||
} else if i > 0 {
|
} else if i > 0 {
|
||||||
@@ -323,14 +323,14 @@ impl Machine {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DynamicElse(birth, death, NextOrFail::Fail(_)) => {
|
Instruction::DynamicElse(birth, death, NextOrFail::Fail(_)) => {
|
||||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||||
return Some((p, 0));
|
return Some((p, 0));
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DynamicInternalElse(birth, death, NextOrFail::Next(i)) => {
|
Instruction::DynamicInternalElse(birth, death, NextOrFail::Next(i)) => {
|
||||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||||
return Some((p, i));
|
return Some((p, i));
|
||||||
} else if i > 0 {
|
} else if i > 0 {
|
||||||
@@ -339,14 +339,14 @@ impl Machine {
|
|||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DynamicInternalElse(birth, death, NextOrFail::Fail(_)) => {
|
Instruction::DynamicInternalElse(birth, death, NextOrFail::Fail(_)) => {
|
||||||
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
if birth < self.machine_st.cc && Death::Finite(self.machine_st.cc) <= death {
|
||||||
return Some((p, 0));
|
return Some((p, 0));
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::RevJmpBy(i) => {
|
Instruction::RevJmpBy(i) => {
|
||||||
p -= i;
|
p -= i;
|
||||||
}
|
}
|
||||||
_ => {
|
_ => {
|
||||||
@@ -395,25 +395,14 @@ impl Machine {
|
|||||||
fn execute_switch_on_term(&mut self) {
|
fn execute_switch_on_term(&mut self) {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn dynamic_external_of_clause_is_valid(machine: &mut Machine, p: usize) -> bool {
|
fn dynamic_external_of_clause_is_valid(machine: &mut Machine, p: usize) -> bool {
|
||||||
match &machine.code[p] {
|
if let Instruction::DynamicInternalElse(..) = machine.code[p] {
|
||||||
Instruction::DynamicInternalElse(..) => {
|
machine.machine_st.dynamic_mode = FirstOrNext::First;
|
||||||
machine.machine_st.dynamic_mode = FirstOrNext::First;
|
return true;
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
match &machine.code[p - 1] {
|
if let Instruction::DynamicInternalElse(birth, death, _) = machine.code[p - 1] {
|
||||||
&Instruction::DynamicInternalElse(birth, death, _) => {
|
return birth < machine.machine_st.cc
|
||||||
if birth < machine.machine_st.cc
|
&& Death::Finite(machine.machine_st.cc) <= death;
|
||||||
&& Death::Finite(machine.machine_st.cc) <= death
|
|
||||||
{
|
|
||||||
return true;
|
|
||||||
} else {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
true
|
true
|
||||||
@@ -1896,7 +1885,7 @@ impl Machine {
|
|||||||
self.machine_st.backtrack();
|
self.machine_st.backtrack();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::CallNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1910,7 +1899,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1924,7 +1913,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberEqual(ref at_1, ref at_2) => {
|
Instruction::CallNumberEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1938,7 +1927,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1952,7 +1941,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberNotEqual(ref at_1, ref at_2) => {
|
Instruction::CallNumberNotEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1966,7 +1955,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberNotEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1980,7 +1969,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::CallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -1994,7 +1983,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2008,7 +1997,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => {
|
Instruction::CallNumberGreaterThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2022,7 +2011,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberGreaterThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2036,7 +2025,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::CallNumberLessThan(ref at_1, ref at_2) => {
|
Instruction::CallNumberLessThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2050,7 +2039,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => {
|
Instruction::ExecuteNumberLessThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2064,7 +2053,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2077,7 +2066,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberLessThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2090,7 +2079,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberNotEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2103,7 +2092,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberNotEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2116,7 +2105,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2129,7 +2118,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2142,7 +2131,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2155,7 +2144,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberGreaterThanOrEqual(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2168,7 +2157,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberGreaterThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2181,7 +2170,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberGreaterThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2194,7 +2183,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => {
|
Instruction::DefaultCallNumberLessThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2207,7 +2196,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => {
|
Instruction::DefaultExecuteNumberLessThan(ref at_1, ref at_2) => {
|
||||||
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
let n1 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_1));
|
||||||
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
let n2 = try_or_throw!(self.machine_st, self.machine_st.get_number(at_2));
|
||||||
|
|
||||||
@@ -2955,7 +2944,7 @@ impl Machine {
|
|||||||
|
|
||||||
self.machine_st.p += 1;
|
self.machine_st.p += 1;
|
||||||
}
|
}
|
||||||
&Instruction::IndexingCode(ref indexing_lines) => {
|
Instruction::IndexingCode(ref indexing_lines) => {
|
||||||
match &indexing_lines[self.machine_st.oip as usize] {
|
match &indexing_lines[self.machine_st.oip as usize] {
|
||||||
IndexingLine::Indexing(_) => {
|
IndexingLine::Indexing(_) => {
|
||||||
self.execute_switch_on_term();
|
self.execute_switch_on_term();
|
||||||
@@ -2965,22 +2954,22 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
IndexingLine::IndexedChoice(ref indexed_choice) => {
|
IndexingLine::IndexedChoice(ref indexed_choice) => {
|
||||||
match &indexed_choice[self.machine_st.iip as usize] {
|
match indexed_choice[self.machine_st.iip as usize] {
|
||||||
&IndexedChoiceInstruction::Try(offset) => {
|
IndexedChoiceInstruction::Try(offset) => {
|
||||||
self.indexed_try(offset);
|
self.indexed_try(offset);
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Retry(l) => {
|
IndexedChoiceInstruction::Retry(l) => {
|
||||||
self.retry(l);
|
self.retry(l);
|
||||||
increment_call_count!(self.machine_st);
|
increment_call_count!(self.machine_st);
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::DefaultRetry(l) => {
|
IndexedChoiceInstruction::DefaultRetry(l) => {
|
||||||
self.retry(l);
|
self.retry(l);
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::Trust(l) => {
|
IndexedChoiceInstruction::Trust(l) => {
|
||||||
self.trust(l);
|
self.trust(l);
|
||||||
increment_call_count!(self.machine_st);
|
increment_call_count!(self.machine_st);
|
||||||
}
|
}
|
||||||
&IndexedChoiceInstruction::DefaultTrust(l) => {
|
IndexedChoiceInstruction::DefaultTrust(l) => {
|
||||||
self.trust(l);
|
self.trust(l);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -5089,16 +5078,13 @@ impl Machine {
|
|||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match skeleton.target_pos_of_clause_clause_loc(l) {
|
if let Some(n) = skeleton.target_pos_of_clause_clause_loc(l) {
|
||||||
Some(n) => {
|
let r = self
|
||||||
let r = self
|
.machine_st
|
||||||
.machine_st
|
.store(self.machine_st.deref(self.machine_st.registers[5]));
|
||||||
.store(self.machine_st.deref(self.machine_st.registers[5]));
|
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_fixnum(Fixnum::build_with(n as i64), r);
|
.unify_fixnum(Fixnum::build_with(n as i64), r);
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.call_at_index(2, p);
|
self.machine_st.call_at_index(2, p);
|
||||||
@@ -5135,16 +5121,13 @@ impl Machine {
|
|||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
match skeleton.target_pos_of_clause_clause_loc(l) {
|
if let Some(n) = skeleton.target_pos_of_clause_clause_loc(l) {
|
||||||
Some(n) => {
|
let r = self
|
||||||
let r = self
|
.machine_st
|
||||||
.machine_st
|
.store(self.machine_st.deref(self.machine_st.registers[5]));
|
||||||
.store(self.machine_st.deref(self.machine_st.registers[5]));
|
|
||||||
|
|
||||||
self.machine_st
|
self.machine_st
|
||||||
.unify_fixnum(Fixnum::build_with(n as i64), r);
|
.unify_fixnum(Fixnum::build_with(n as i64), r);
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.machine_st.execute_at_index(2, p);
|
self.machine_st.execute_at_index(2, p);
|
||||||
@@ -5226,7 +5209,7 @@ impl Machine {
|
|||||||
// So we only have access to a runtime handle in here and can't shut it down.
|
// So we only have access to a runtime handle in here and can't shut it down.
|
||||||
// Since I'm not aware of the consequences of deactivating this new code which came in while PR 1880
|
// Since I'm not aware of the consequences of deactivating this new code which came in while PR 1880
|
||||||
// was not merged, I'm only deactivating it for now.
|
// was not merged, I'm only deactivating it for now.
|
||||||
|
|
||||||
//#[cfg(not(target_arch = "wasm32"))]
|
//#[cfg(not(target_arch = "wasm32"))]
|
||||||
//let runtime = tokio::runtime::Runtime::new().unwrap();
|
//let runtime = tokio::runtime::Runtime::new().unwrap();
|
||||||
//#[cfg(target_arch = "wasm32")]
|
//#[cfg(target_arch = "wasm32")]
|
||||||
|
|||||||
@@ -9,14 +9,22 @@ pub(crate) trait UnmarkPolicy {
|
|||||||
fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue>
|
fn forward_attr_var(iter: &mut StacklessPreOrderHeapIter<Self>) -> Option<HeapCellValue>
|
||||||
where
|
where
|
||||||
Self: Sized;
|
Self: Sized;
|
||||||
fn invert_marker(iter: &mut StacklessPreOrderHeapIter<Self>) where Self: Sized;
|
fn invert_marker(iter: &mut StacklessPreOrderHeapIter<Self>)
|
||||||
|
where
|
||||||
|
Self: Sized;
|
||||||
fn mark_phase(&self) -> bool;
|
fn mark_phase(&self) -> bool;
|
||||||
#[inline]
|
#[inline]
|
||||||
fn report_var_link(iter: &StacklessPreOrderHeapIter<Self>) -> bool where Self: Sized {
|
fn report_var_link(iter: &StacklessPreOrderHeapIter<Self>) -> bool
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
iter.heap[iter.next as usize].get_mark_bit() == iter.iter_state.mark_phase()
|
iter.heap[iter.next as usize].get_mark_bit() == iter.iter_state.mark_phase()
|
||||||
}
|
}
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn record_focus(_iter: &mut StacklessPreOrderHeapIter<Self>) where Self: Sized {
|
fn record_focus(_iter: &mut StacklessPreOrderHeapIter<Self>)
|
||||||
|
where
|
||||||
|
Self: Sized,
|
||||||
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -34,7 +42,7 @@ fn invert_marker<UMP: UnmarkPolicy>(iter: &mut StacklessPreOrderHeapIter<UMP>) {
|
|||||||
iter.next = iter.heap[iter.start].get_value();
|
iter.next = iter.heap[iter.start].get_value();
|
||||||
iter.current = iter.start;
|
iter.current = iter.start;
|
||||||
|
|
||||||
while let Some(_) = iter.forward() {}
|
while iter.forward().is_some() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl UnmarkPolicy for IteratorUMP {
|
impl UnmarkPolicy for IteratorUMP {
|
||||||
@@ -139,7 +147,7 @@ impl<'a> StacklessPreOrderHeapIter<'a, IteratorUMP> {
|
|||||||
start,
|
start,
|
||||||
current: start,
|
current: start,
|
||||||
next,
|
next,
|
||||||
iter_state: IteratorUMP { mark_phase: true,},
|
iter_state: IteratorUMP { mark_phase: true },
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -189,11 +197,9 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.next < self.heap.len() as u64 {
|
if self.next < self.heap.len() as u64 && UMP::report_var_link(self) {
|
||||||
if UMP::report_var_link(self) {
|
let tag = HeapCellValueTag::AttrVar;
|
||||||
let tag = HeapCellValueTag::AttrVar;
|
return Some(HeapCellValue::build_with(tag, next as u64));
|
||||||
return Some(HeapCellValue::build_with(tag, next as u64));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Var => {
|
HeapCellValueTag::Var => {
|
||||||
@@ -203,11 +209,9 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
return Some(cell);
|
return Some(cell);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.next < self.heap.len() as u64 {
|
if self.next < self.heap.len() as u64 && UMP::report_var_link(self) {
|
||||||
if UMP::report_var_link(self) {
|
let tag = HeapCellValueTag::Var;
|
||||||
let tag = HeapCellValueTag::Var;
|
return Some(HeapCellValue::build_with(tag, next as u64));
|
||||||
return Some(HeapCellValue::build_with(tag, next as u64));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Str => {
|
HeapCellValueTag::Str => {
|
||||||
@@ -311,10 +315,8 @@ impl<'a, UMP: UnmarkPolicy> StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
return Some(self.backward_and_return());
|
return Some(self.backward_and_return());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else if self.backward() {
|
||||||
if self.backward() {
|
return None;
|
||||||
return None;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -358,7 +360,7 @@ impl<'a, UMP: UnmarkPolicy> Iterator for StacklessPreOrderHeapIter<'a, UMP> {
|
|||||||
|
|
||||||
pub fn mark_cells(heap: &mut Heap, start: usize) {
|
pub fn mark_cells(heap: &mut Heap, start: usize) {
|
||||||
let mut iter = StacklessPreOrderHeapIter::<MarkerUMP>::new(heap, start);
|
let mut iter = StacklessPreOrderHeapIter::<MarkerUMP>::new(heap, start);
|
||||||
while let Some(_) = iter.forward() {}
|
while iter.forward().is_some() {}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
@@ -665,14 +667,18 @@ mod tests {
|
|||||||
|
|
||||||
wam.machine_st.heap.push(pstr_loc_as_cell!(1));
|
wam.machine_st.heap.push(pstr_loc_as_cell!(1));
|
||||||
|
|
||||||
let pstr_var_cell = put_partial_string(&mut wam.machine_st.heap, "abc ", &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];
|
let pstr_cell = wam.machine_st.heap[pstr_var_cell.get_value() as usize];
|
||||||
|
|
||||||
mark_cells(&mut wam.machine_st.heap, 0);
|
mark_cells(&mut wam.machine_st.heap, 0);
|
||||||
|
|
||||||
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[0]), pstr_loc_as_cell!(1));
|
assert_eq!(
|
||||||
|
unmark_cell_bits!(wam.machine_st.heap[0]),
|
||||||
|
pstr_loc_as_cell!(1)
|
||||||
|
);
|
||||||
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
unmark_cell_bits!(wam.machine_st.heap[2]),
|
unmark_cell_bits!(wam.machine_st.heap[2]),
|
||||||
@@ -720,7 +726,7 @@ mod tests {
|
|||||||
|
|
||||||
mark_cells(&mut wam.machine_st.heap, 7);
|
mark_cells(&mut wam.machine_st.heap, 7);
|
||||||
|
|
||||||
all_cells_marked_and_unforwarded(&wam.machine_st.heap[1 ..]);
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap[1..]);
|
||||||
|
|
||||||
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
assert_eq!(unmark_cell_bits!(wam.machine_st.heap[1]), pstr_cell);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
@@ -1536,10 +1542,10 @@ mod tests {
|
|||||||
|
|
||||||
mark_cells(&mut wam.machine_st.heap, 0);
|
mark_cells(&mut wam.machine_st.heap, 0);
|
||||||
|
|
||||||
all_cells_marked_and_unforwarded(&mut wam.machine_st.heap[0..24]);
|
all_cells_marked_and_unforwarded(&wam.machine_st.heap[0..24]);
|
||||||
|
|
||||||
for cell in &wam.machine_st.heap[24..] {
|
for cell in &wam.machine_st.heap[24..] {
|
||||||
assert_eq!(cell.get_mark_bit(), false);
|
assert!(!cell.get_mark_bit());
|
||||||
}
|
}
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
|
|||||||
@@ -169,7 +169,7 @@ pub(crate) fn allocate_pstr(heap: &mut Heap, mut src: &str, atom_tbl: &AtomTable
|
|||||||
let orig_h = heap.len();
|
let orig_h = heap.len();
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
if src == "" {
|
if src.is_empty() {
|
||||||
return if orig_h == heap.len() {
|
return if orig_h == heap.len() {
|
||||||
None
|
None
|
||||||
} else {
|
} else {
|
||||||
@@ -199,7 +199,7 @@ pub(crate) fn allocate_pstr(heap: &mut Heap, mut src: &str, atom_tbl: &AtomTable
|
|||||||
|
|
||||||
heap.push(string_as_pstr_cell!(pstr));
|
heap.push(string_as_pstr_cell!(pstr));
|
||||||
|
|
||||||
if rest_src != "" {
|
if !rest_src.is_empty() {
|
||||||
heap.push(pstr_loc_as_cell!(h + 2));
|
heap.push(pstr_loc_as_cell!(h + 2));
|
||||||
src = rest_src;
|
src = rest_src;
|
||||||
} else {
|
} else {
|
||||||
@@ -249,7 +249,7 @@ pub(crate) fn to_local_code_ptr(heap: &Heap, addr: HeapCellValue) -> Option<usiz
|
|||||||
Ok(Number::Integer(n)) => {
|
Ok(Number::Integer(n)) => {
|
||||||
let value: usize = (&*n).try_into().unwrap();
|
let value: usize = (&*n).try_into().unwrap();
|
||||||
Some(value)
|
Some(value)
|
||||||
},
|
}
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -3,18 +3,17 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
use crate::atom_table;
|
use crate::atom_table;
|
||||||
use crate::heap_print::{HCPrinter, HCValueOutputter, PrinterOutputter};
|
use crate::heap_print::{HCPrinter, HCValueOutputter, PrinterOutputter};
|
||||||
use crate::machine::{BREAK_FROM_DISPATCH_LOOP_LOC, LIB_QUERY_SUCCESS};
|
use crate::machine::machine_indices::VarKey;
|
||||||
use crate::machine::mock_wam::CompositeOpDir;
|
use crate::machine::mock_wam::CompositeOpDir;
|
||||||
|
use crate::machine::{BREAK_FROM_DISPATCH_LOOP_LOC, LIB_QUERY_SUCCESS};
|
||||||
|
use crate::parser::ast::{Var, VarPtr};
|
||||||
use crate::parser::parser::{Parser, Tokens};
|
use crate::parser::parser::{Parser, Tokens};
|
||||||
use crate::read::write_term_to_heap;
|
use crate::read::write_term_to_heap;
|
||||||
use crate::machine::machine_indices::VarKey;
|
|
||||||
use crate::parser::ast::{Var, VarPtr};
|
|
||||||
use indexmap::IndexMap;
|
use indexmap::IndexMap;
|
||||||
|
|
||||||
use super::{
|
use super::{
|
||||||
Machine, MachineConfig, QueryResult, QueryResolutionLine,
|
streams::Stream, Atom, AtomCell, HeapCellValue, HeapCellValueTag, Machine, MachineConfig,
|
||||||
Atom, AtomCell, HeapCellValue, HeapCellValueTag, Value, QueryResolution,
|
QueryResolution, QueryResolutionLine, QueryResult, Value,
|
||||||
streams::Stream
|
|
||||||
};
|
};
|
||||||
|
|
||||||
impl Machine {
|
impl Machine {
|
||||||
@@ -30,7 +29,10 @@ impl Machine {
|
|||||||
pub fn consult_module_string(&mut self, module_name: &str, program: String) {
|
pub fn consult_module_string(&mut self, module_name: &str, program: String) {
|
||||||
let stream = Stream::from_owned_string(program, &mut self.machine_st.arena);
|
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[1] = stream_as_cell!(stream);
|
||||||
self.machine_st.registers[2] = atom_as_cell!(&atom_table::AtomTable::build_with(&self.machine_st.atom_tbl, 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));
|
self.run_module_predicate(atom!("loader"), (atom!("consult_stream"), 2));
|
||||||
}
|
}
|
||||||
@@ -62,21 +64,33 @@ impl Machine {
|
|||||||
// Parse the query so we can analyze and then call the term
|
// Parse the query so we can analyze and then call the term
|
||||||
let mut parser = Parser::new(
|
let mut parser = Parser::new(
|
||||||
Stream::from_owned_string(query, &mut self.machine_st.arena),
|
Stream::from_owned_string(query, &mut self.machine_st.arena),
|
||||||
&mut self.machine_st
|
&mut self.machine_st,
|
||||||
);
|
);
|
||||||
let op_dir = CompositeOpDir::new(&self.indices.op_dir, None);
|
let op_dir = CompositeOpDir::new(&self.indices.op_dir, None);
|
||||||
let term = parser.read_term(&op_dir, Tokens::Default).expect("Failed to parse query");
|
let term = parser
|
||||||
|
.read_term(&op_dir, Tokens::Default)
|
||||||
|
.expect("Failed to parse query");
|
||||||
|
|
||||||
// Write parsed term to heap
|
// Write parsed term to heap
|
||||||
let term_write_result = write_term_to_heap(&term, &mut self.machine_st.heap, &mut self.machine_st.atom_tbl).expect("couldn't write term to heap");
|
let term_write_result =
|
||||||
|
write_term_to_heap(&term, &mut self.machine_st.heap, &self.machine_st.atom_tbl)
|
||||||
|
.expect("couldn't write term to heap");
|
||||||
|
|
||||||
// Write term to heap
|
// Write term to heap
|
||||||
self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc];
|
self.machine_st.registers[1] = self.machine_st.heap[term_write_result.heap_loc];
|
||||||
|
|
||||||
self.machine_st.cp = LIB_QUERY_SUCCESS; // BREAK_FROM_DISPATCH_LOOP_LOC;
|
self.machine_st.cp = LIB_QUERY_SUCCESS; // BREAK_FROM_DISPATCH_LOOP_LOC;
|
||||||
self.machine_st.p = self.indices.code_dir.get(&(atom!("call"), 1)).expect("couldn't get code index").local().unwrap();
|
self.machine_st.p = self
|
||||||
|
.indices
|
||||||
|
.code_dir
|
||||||
|
.get(&(atom!("call"), 1))
|
||||||
|
.expect("couldn't get code index")
|
||||||
|
.local()
|
||||||
|
.unwrap();
|
||||||
|
|
||||||
let var_names: IndexMap<_, _> = term_write_result.var_dict.iter()
|
let var_names: IndexMap<_, _> = term_write_result
|
||||||
|
.var_dict
|
||||||
|
.iter()
|
||||||
.map(|(var_key, cell)| match var_key {
|
.map(|(var_key, cell)| match var_key {
|
||||||
// NOTE: not the intention behind Var::InSitu here but
|
// NOTE: not the intention behind Var::InSitu here but
|
||||||
// we can hijack it to store anonymous variables
|
// we can hijack it to store anonymous variables
|
||||||
@@ -99,27 +113,29 @@ impl Machine {
|
|||||||
//println!("stub_b: {}", stub_b);
|
//println!("stub_b: {}", stub_b);
|
||||||
//println!("fail: {}", self.machine_st.fail);
|
//println!("fail: {}", self.machine_st.fail);
|
||||||
|
|
||||||
if self.machine_st.ball.stub.len() != 0 {
|
if !self.machine_st.ball.stub.is_empty() {
|
||||||
// NOTE: this means an exception was thrown, at which
|
// NOTE: this means an exception was thrown, at which
|
||||||
// point we backtracked to the stub choice point.
|
// point we backtracked to the stub choice point.
|
||||||
// this should halt the search for solutions as it
|
// this should halt the search for solutions as it
|
||||||
// does in the Scryer top-level. the exception term is
|
// does in the Scryer top-level. the exception term is
|
||||||
// contained in self.machine_st.ball.
|
// contained in self.machine_st.ball.
|
||||||
let error_string = self.machine_st.ball.stub
|
let error_string = self
|
||||||
|
.machine_st
|
||||||
|
.ball
|
||||||
|
.stub
|
||||||
.iter()
|
.iter()
|
||||||
.filter(|h| match h.get_tag() {
|
.filter(|h| {
|
||||||
HeapCellValueTag::Atom => true,
|
matches!(
|
||||||
HeapCellValueTag::Fixnum => true,
|
h.get_tag(),
|
||||||
_ => false,
|
HeapCellValueTag::Atom | HeapCellValueTag::Fixnum
|
||||||
|
)
|
||||||
})
|
})
|
||||||
.map(|h| match h.get_tag() {
|
.map(|h| match h.get_tag() {
|
||||||
HeapCellValueTag::Atom => {
|
HeapCellValueTag::Atom => {
|
||||||
let (name, _) = cell_as_atom_cell!(h).get_name_and_arity();
|
let (name, _) = cell_as_atom_cell!(h).get_name_and_arity();
|
||||||
name.as_str().to_string()
|
name.as_str().to_string()
|
||||||
}
|
}
|
||||||
HeapCellValueTag::Fixnum => {
|
HeapCellValueTag::Fixnum => h.get_value().clone().to_string(),
|
||||||
h.get_value().clone().to_string()
|
|
||||||
},
|
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
})
|
})
|
||||||
.collect::<Vec<String>>()
|
.collect::<Vec<String>>()
|
||||||
@@ -154,7 +170,7 @@ impl Machine {
|
|||||||
let mut bindings: BTreeMap<String, Value> = BTreeMap::new();
|
let mut bindings: BTreeMap<String, Value> = BTreeMap::new();
|
||||||
|
|
||||||
for (var_key, term_to_be_printed) in &term_write_result.var_dict {
|
for (var_key, term_to_be_printed) in &term_write_result.var_dict {
|
||||||
if var_key.to_string().starts_with("_") {
|
if var_key.to_string().starts_with('_') {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let mut printer = HCPrinter::new(
|
let mut printer = HCPrinter::new(
|
||||||
@@ -210,7 +226,7 @@ mod tests {
|
|||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use crate::machine::{QueryMatch, Value, QueryResolution};
|
use crate::machine::{QueryMatch, QueryResolution, Value};
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn programatic_query() {
|
fn programatic_query() {
|
||||||
@@ -258,7 +274,9 @@ mod tests {
|
|||||||
let output = machine.run_query(query);
|
let output = machine.run_query(query);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
output,
|
output,
|
||||||
Err(String::from("error existence_error procedure / triple 3 / triple 3"))
|
Err(String::from(
|
||||||
|
"error existence_error procedure / triple 3 / triple 3"
|
||||||
|
))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -278,26 +296,30 @@ mod tests {
|
|||||||
constructor(xyz, '[{action: "addLink", source: "this", predicate: "recipe://title", target: "literal://string:Meta%20Muffins"}]').
|
constructor(xyz, '[{action: "addLink", source: "this", predicate: "recipe://title", target: "literal://string:Meta%20Muffins"}]').
|
||||||
"#.to_string());
|
"#.to_string());
|
||||||
|
|
||||||
let result = machine.run_query(String::from("subject_class(\"Todo\", C), constructor(C, Actions)."));
|
let result = machine.run_query(String::from(
|
||||||
|
"subject_class(\"Todo\", C), constructor(C, Actions).",
|
||||||
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
Ok(QueryResolution::Matches(vec![
|
Ok(QueryResolution::Matches(vec![QueryMatch::from(
|
||||||
QueryMatch::from(btreemap! {
|
btreemap! {
|
||||||
"C" => Value::from("c"),
|
"C" => Value::from("c"),
|
||||||
"Actions" => Value::from("[{action: \"addLink\", source: \"this\", predicate: \"todo://state\", target: \"todo://ready\"}]"),
|
"Actions" => Value::from("[{action: \"addLink\", source: \"this\", predicate: \"todo://state\", target: \"todo://ready\"}]"),
|
||||||
}),
|
}
|
||||||
]))
|
),]))
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = machine.run_query(String::from("subject_class(\"Recipe\", C), constructor(C, Actions)."));
|
let result = machine.run_query(String::from(
|
||||||
|
"subject_class(\"Recipe\", C), constructor(C, Actions).",
|
||||||
|
));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
Ok(QueryResolution::Matches(vec![
|
Ok(QueryResolution::Matches(vec![QueryMatch::from(
|
||||||
QueryMatch::from(btreemap! {
|
btreemap! {
|
||||||
"C" => Value::from("xyz"),
|
"C" => Value::from("xyz"),
|
||||||
"Actions" => Value::from("[{action: \"addLink\", source: \"this\", predicate: \"recipe://title\", target: \"literal://string:Meta%20Muffins\"}]"),
|
"Actions" => Value::from("[{action: \"addLink\", source: \"this\", predicate: \"recipe://title\", target: \"literal://string:Meta%20Muffins\"}]"),
|
||||||
}),
|
}
|
||||||
]))
|
),]))
|
||||||
);
|
);
|
||||||
|
|
||||||
let result = machine.run_query(String::from("subject_class(Class, _)."));
|
let result = machine.run_query(String::from("subject_class(Class, _)."));
|
||||||
@@ -319,15 +341,17 @@ mod tests {
|
|||||||
let mut machine = Machine::new_lib();
|
let mut machine = Machine::new_lib();
|
||||||
machine.load_module_string(
|
machine.load_module_string(
|
||||||
"facts",
|
"facts",
|
||||||
r#"
|
r#"
|
||||||
list([1,2,3]).
|
list([1,2,3]).
|
||||||
"#.to_string());
|
"#
|
||||||
|
.to_string(),
|
||||||
|
);
|
||||||
|
|
||||||
let result = machine.run_query(String::from("list(X)."));
|
let result = machine.run_query(String::from("list(X)."));
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
result,
|
result,
|
||||||
Ok(QueryResolution::Matches(vec![
|
Ok(QueryResolution::Matches(vec![QueryMatch::from(
|
||||||
QueryMatch::from(btreemap! {
|
btreemap! {
|
||||||
"X" => Value::List(
|
"X" => Value::List(
|
||||||
Vec::from([
|
Vec::from([
|
||||||
Value::Float(OrderedFloat::from(1.0)),
|
Value::Float(OrderedFloat::from(1.0)),
|
||||||
@@ -335,12 +359,11 @@ mod tests {
|
|||||||
Value::Float(OrderedFloat::from(3.0))
|
Value::Float(OrderedFloat::from(3.0))
|
||||||
])
|
])
|
||||||
)
|
)
|
||||||
}),
|
}
|
||||||
]))
|
),]))
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn consult() {
|
fn consult() {
|
||||||
let mut machine = Machine::new_lib();
|
let mut machine = Machine::new_lib();
|
||||||
@@ -397,7 +420,6 @@ mod tests {
|
|||||||
machine.run_query(String::from(r#"triple("a","new","b")."#)),
|
machine.run_query(String::from(r#"triple("a","new","b")."#)),
|
||||||
Ok(QueryResolution::True)
|
Ok(QueryResolution::True)
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[ignore = "fails on windows"]
|
#[ignore = "fails on windows"]
|
||||||
@@ -462,12 +484,13 @@ mod tests {
|
|||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
let query = String::from(r#"findall([Predicate, Target], triple(_,Predicate,Target), Result)."#);
|
let query =
|
||||||
|
String::from(r#"findall([Predicate, Target], triple(_,Predicate,Target), Result)."#);
|
||||||
let output = machine.run_query(query);
|
let output = machine.run_query(query);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
output,
|
output,
|
||||||
Ok(QueryResolution::Matches(vec![
|
Ok(QueryResolution::Matches(vec![QueryMatch::from(
|
||||||
QueryMatch::from(btreemap! {
|
btreemap! {
|
||||||
"Predicate" => Value::from("Predicate"),
|
"Predicate" => Value::from("Predicate"),
|
||||||
"Result" => Value::List(
|
"Result" => Value::List(
|
||||||
Vec::from([
|
Vec::from([
|
||||||
@@ -476,9 +499,8 @@ mod tests {
|
|||||||
])
|
])
|
||||||
),
|
),
|
||||||
"Target" => Value::from("Target"),
|
"Target" => Value::from("Target"),
|
||||||
}),
|
}
|
||||||
]))
|
),]))
|
||||||
);
|
);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -137,10 +137,9 @@ pub(super) fn import_module_exports<'a, LS: LoadState<'a>>(
|
|||||||
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
if let Some(src_code_index) = imported_module.code_dir.get(&key).cloned() {
|
||||||
let arena = &mut LS::machine_st(payload).arena;
|
let arena = &mut LS::machine_st(payload).arena;
|
||||||
|
|
||||||
let target_code_index = code_dir
|
let target_code_index = *code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::default(arena))
|
.or_insert_with(|| CodeIndex::default(arena));
|
||||||
.clone();
|
|
||||||
|
|
||||||
set_code_index(
|
set_code_index(
|
||||||
&mut payload.retraction_info,
|
&mut payload.retraction_info,
|
||||||
@@ -189,16 +188,15 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
|
|||||||
let key = (*name, *arity);
|
let key = (*name, *arity);
|
||||||
|
|
||||||
if let Some(meta_specs) = imported_module.meta_predicates.get(&key) {
|
if let Some(meta_specs) = imported_module.meta_predicates.get(&key) {
|
||||||
meta_predicates.insert(key.clone(), meta_specs.clone());
|
meta_predicates.insert(key, meta_specs.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||||
let arena = &mut LS::machine_st(payload).arena;
|
let arena = &mut LS::machine_st(payload).arena;
|
||||||
|
|
||||||
let target_code_index = code_dir
|
let target_code_index = *code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::default(arena))
|
.or_insert_with(|| CodeIndex::default(arena));
|
||||||
.clone();
|
|
||||||
|
|
||||||
set_code_index(
|
set_code_index(
|
||||||
&mut payload.retraction_info,
|
&mut payload.retraction_info,
|
||||||
@@ -209,7 +207,7 @@ fn import_module_exports_into_module<'a, LS: LoadState<'a>>(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Err(SessionError::ModuleDoesNotContainExport(
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
imported_module.module_decl.name.clone(),
|
imported_module.module_decl.name,
|
||||||
(*name, *arity),
|
(*name, *arity),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -243,18 +241,17 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
|
|||||||
wam_prelude
|
wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.meta_predicates
|
.meta_predicates
|
||||||
.insert(key.clone(), meta_specs.clone());
|
.insert(key, meta_specs.clone());
|
||||||
}
|
}
|
||||||
|
|
||||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||||
let arena = &mut LS::machine_st(payload).arena;
|
let arena = &mut LS::machine_st(payload).arena;
|
||||||
|
|
||||||
let target_code_index = wam_prelude
|
let target_code_index = *wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.code_dir
|
.code_dir
|
||||||
.entry(key.clone())
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||||
.clone();
|
|
||||||
|
|
||||||
set_code_index(
|
set_code_index(
|
||||||
&mut payload.retraction_info,
|
&mut payload.retraction_info,
|
||||||
@@ -265,7 +262,7 @@ fn import_qualified_module_exports<'a, LS: LoadState<'a>>(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Err(SessionError::ModuleDoesNotContainExport(
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
imported_module.module_decl.name.clone(),
|
imported_module.module_decl.name,
|
||||||
(*name, *arity),
|
(*name, *arity),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -311,10 +308,9 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
|
|||||||
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
if let Some(src_code_index) = imported_module.code_dir.get(&key) {
|
||||||
let arena = &mut LS::machine_st(payload).arena;
|
let arena = &mut LS::machine_st(payload).arena;
|
||||||
|
|
||||||
let target_code_index = code_dir
|
let target_code_index = *code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||||
.clone();
|
|
||||||
|
|
||||||
set_code_index(
|
set_code_index(
|
||||||
&mut payload.retraction_info,
|
&mut payload.retraction_info,
|
||||||
@@ -325,7 +321,7 @@ fn import_qualified_module_exports_into_module<'a, LS: LoadState<'a>>(
|
|||||||
);
|
);
|
||||||
} else {
|
} else {
|
||||||
return Err(SessionError::ModuleDoesNotContainExport(
|
return Err(SessionError::ModuleDoesNotContainExport(
|
||||||
imported_module.module_decl.name.clone(),
|
imported_module.module_decl.name,
|
||||||
(*name, *arity),
|
(*name, *arity),
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
@@ -423,7 +419,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
payload_compilation_target,
|
payload_compilation_target,
|
||||||
clause_clause_compilation_target,
|
clause_clause_compilation_target,
|
||||||
key,
|
key,
|
||||||
mem::replace(&mut skeleton.clause_clause_locs, VecDeque::new()),
|
std::mem::take(&mut skeleton.clause_clause_locs),
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
|
|
||||||
@@ -436,7 +432,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
self.retract_local_clauses_impl(clause_clause_compilation_target, key, &clause_locs);
|
self.retract_local_clauses_impl(clause_clause_compilation_target, key, clause_locs);
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn try_term_to_tl(
|
pub(super) fn try_term_to_tl(
|
||||||
@@ -600,30 +596,22 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> CodeIndex {
|
) -> CodeIndex {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
Some(ref mut module) => module
|
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
|
||||||
.code_dir
|
CodeIndex::new(
|
||||||
.entry(key)
|
IndexPtr::undefined(),
|
||||||
.or_insert_with(|| {
|
&mut LS::machine_st(&mut self.payload).arena,
|
||||||
CodeIndex::new(
|
)
|
||||||
IndexPtr::undefined(),
|
}),
|
||||||
&mut LS::machine_st(&mut self.payload).arena,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.clone(),
|
|
||||||
None => {
|
None => {
|
||||||
self.add_dynamically_generated_module(module_name);
|
self.add_dynamically_generated_module(module_name);
|
||||||
|
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
Some(ref mut module) => module
|
Some(ref mut module) => *module.code_dir.entry(key).or_insert_with(|| {
|
||||||
.code_dir
|
CodeIndex::new(
|
||||||
.entry(key)
|
IndexPtr::undefined(),
|
||||||
.or_insert_with(|| {
|
&mut LS::machine_st(&mut self.payload).arena,
|
||||||
CodeIndex::new(
|
)
|
||||||
IndexPtr::undefined(),
|
}),
|
||||||
&mut LS::machine_st(&mut self.payload).arena,
|
|
||||||
)
|
|
||||||
})
|
|
||||||
.clone(),
|
|
||||||
None => {
|
None => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -640,13 +628,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
||||||
|
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => self
|
CompilationTarget::User => *self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.code_dir
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena)),
|
||||||
.clone(),
|
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
self.get_or_insert_local_code_index(module_name, key)
|
self.get_or_insert_local_code_index(module_name, key)
|
||||||
}
|
}
|
||||||
@@ -661,13 +648,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
let arena = &mut LS::machine_st(&mut self.payload).arena;
|
||||||
|
|
||||||
if module_name == atom!("user") {
|
if module_name == atom!("user") {
|
||||||
return self
|
return *self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.code_dir
|
.code_dir
|
||||||
.entry(key)
|
.entry(key)
|
||||||
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena))
|
.or_insert_with(|| CodeIndex::new(IndexPtr::undefined(), arena));
|
||||||
.clone();
|
|
||||||
} else {
|
} else {
|
||||||
self.get_or_insert_local_code_index(module_name, key)
|
self.get_or_insert_local_code_index(module_name, key)
|
||||||
}
|
}
|
||||||
@@ -694,7 +680,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
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.clone(), skeleton);
|
module.extensible_predicates.insert(key, skeleton);
|
||||||
|
|
||||||
let record = RetractionRecord::AddedExtensiblePredicate(
|
let record = RetractionRecord::AddedExtensiblePredicate(
|
||||||
CompilationTarget::Module(module_name),
|
CompilationTarget::Module(module_name),
|
||||||
@@ -747,11 +733,10 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
match payload_compilation_target {
|
match payload_compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
if let Some(filename) = listing_src_file_name {
|
if let Some(filename) = listing_src_file_name {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&filename) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&filename)
|
||||||
op_decl.insert_into_op_dir(&mut module.op_dir);
|
{
|
||||||
}
|
op_decl.insert_into_op_dir(&mut module.op_dir);
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -855,48 +840,43 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
_ => {
|
_ => match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
Some(ref mut module) => match module.meta_predicates.insert(key, meta_specs) {
|
||||||
Some(ref mut module) => {
|
Some(old_meta_specs) => {
|
||||||
match module.meta_predicates.insert(key.clone(), meta_specs) {
|
|
||||||
Some(old_meta_specs) => {
|
|
||||||
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),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
None => {
|
|
||||||
self.add_dynamically_generated_module(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(
|
self.payload.retraction_info.push_record(
|
||||||
RetractionRecord::AddedMetaPredicate(module_name.clone(), key),
|
RetractionRecord::ReplacedMetaPredicate(
|
||||||
|
module_name,
|
||||||
|
key.0,
|
||||||
|
old_meta_specs,
|
||||||
|
),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
None => {
|
||||||
|
self.payload
|
||||||
|
.retraction_info
|
||||||
|
.push_record(RetractionRecord::AddedMetaPredicate(module_name, key));
|
||||||
|
}
|
||||||
|
},
|
||||||
|
None => {
|
||||||
|
self.add_dynamically_generated_module(module_name);
|
||||||
|
|
||||||
|
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
|
module.meta_predicates.insert(key, meta_specs);
|
||||||
|
} else {
|
||||||
|
unreachable!()
|
||||||
|
}
|
||||||
|
|
||||||
|
self.payload
|
||||||
|
.retraction_info
|
||||||
|
.push_record(RetractionRecord::AddedMetaPredicate(module_name, key));
|
||||||
}
|
}
|
||||||
}
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(super) fn add_dynamically_generated_module(&mut self, module_name: Atom) {
|
pub(super) fn add_dynamically_generated_module(&mut self, module_name: Atom) {
|
||||||
let module_decl = ModuleDecl {
|
let module_decl = ModuleDecl {
|
||||||
name: module_name.clone(),
|
name: module_name,
|
||||||
exports: vec![],
|
exports: vec![],
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -912,12 +892,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
|
|
||||||
self.payload
|
self.payload
|
||||||
.retraction_info
|
.retraction_info
|
||||||
.push_record(RetractionRecord::AddedModule(module_name.clone()));
|
.push_record(RetractionRecord::AddedModule(module_name));
|
||||||
|
|
||||||
self.wam_prelude
|
self.wam_prelude.indices.modules.insert(module_name, module);
|
||||||
.indices
|
|
||||||
.modules
|
|
||||||
.insert(module_name.clone(), module);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn import_builtins_in_module(
|
fn import_builtins_in_module(
|
||||||
@@ -956,51 +933,48 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
self.remove_module_exports(module_name);
|
self.remove_module_exports(module_name);
|
||||||
self.remove_replaced_in_situ_module(module_name);
|
self.remove_replaced_in_situ_module(module_name);
|
||||||
|
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(module) = self.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
Some(module) => {
|
let old_module_decl = mem::replace(&mut module.module_decl, module_decl.clone());
|
||||||
let old_module_decl = mem::replace(&mut module.module_decl, module_decl.clone());
|
|
||||||
|
|
||||||
let local_extensible_predicates = mem::replace(
|
let local_extensible_predicates = mem::replace(
|
||||||
&mut module.local_extensible_predicates,
|
&mut module.local_extensible_predicates,
|
||||||
LocalExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
LocalExtensiblePredicates::with_hasher(FxBuildHasher::default()),
|
||||||
|
);
|
||||||
|
|
||||||
|
for ((compilation_target, key), skeleton) in local_extensible_predicates.iter() {
|
||||||
|
self.retract_local_clauses_impl(
|
||||||
|
*compilation_target,
|
||||||
|
*key,
|
||||||
|
&skeleton.clause_clause_locs,
|
||||||
);
|
);
|
||||||
|
|
||||||
for ((compilation_target, key), skeleton) in local_extensible_predicates.iter() {
|
let is_dynamic = self
|
||||||
self.retract_local_clauses_impl(
|
.wam_prelude
|
||||||
*compilation_target,
|
.indices
|
||||||
*key,
|
.get_predicate_skeleton(compilation_target, key)
|
||||||
|
.map(|skeleton| skeleton.core.is_dynamic)
|
||||||
|
.unwrap_or(false);
|
||||||
|
|
||||||
|
if is_dynamic {
|
||||||
|
let clause_clause_compilation_target = match compilation_target {
|
||||||
|
CompilationTarget::User => CompilationTarget::Module(atom!("builtins")),
|
||||||
|
module => *module,
|
||||||
|
};
|
||||||
|
|
||||||
|
self.retract_local_clause_clauses(
|
||||||
|
clause_clause_compilation_target,
|
||||||
&skeleton.clause_clause_locs,
|
&skeleton.clause_clause_locs,
|
||||||
);
|
);
|
||||||
|
|
||||||
let is_dynamic = self
|
|
||||||
.wam_prelude
|
|
||||||
.indices
|
|
||||||
.get_predicate_skeleton(compilation_target, key)
|
|
||||||
.map(|skeleton| skeleton.core.is_dynamic)
|
|
||||||
.unwrap_or(false);
|
|
||||||
|
|
||||||
if is_dynamic {
|
|
||||||
let clause_clause_compilation_target = match compilation_target {
|
|
||||||
CompilationTarget::User => CompilationTarget::Module(atom!("builtins")),
|
|
||||||
module => module.clone(),
|
|
||||||
};
|
|
||||||
|
|
||||||
self.retract_local_clause_clauses(
|
|
||||||
clause_clause_compilation_target,
|
|
||||||
&skeleton.clause_clause_locs,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
self.payload
|
|
||||||
.retraction_info
|
|
||||||
.push_record(RetractionRecord::ReplacedModule(
|
|
||||||
old_module_decl,
|
|
||||||
listing_src.clone(),
|
|
||||||
local_extensible_predicates,
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
|
self.payload
|
||||||
|
.retraction_info
|
||||||
|
.push_record(RetractionRecord::ReplacedModule(
|
||||||
|
old_module_decl,
|
||||||
|
listing_src.clone(),
|
||||||
|
local_extensible_predicates,
|
||||||
|
));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1180,11 +1154,11 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
}
|
}
|
||||||
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
|
ModuleSource::Library(library) => match LIBRARIES.borrow().get(&*library.as_str()) {
|
||||||
Some(code) => {
|
Some(code) => {
|
||||||
if let Some(ref module) = self.wam_prelude.indices.modules.get(&library) {
|
if let Some(module) = self.wam_prelude.indices.modules.get(&library) {
|
||||||
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
if let ListingSource::DynamicallyGenerated = &module.listing_src {
|
||||||
(
|
(
|
||||||
Stream::from_static_string(
|
Stream::from_static_string(
|
||||||
*code,
|
code,
|
||||||
&mut LS::machine_st(&mut self.payload).arena,
|
&mut LS::machine_st(&mut self.payload).arena,
|
||||||
),
|
),
|
||||||
ListingSource::User,
|
ListingSource::User,
|
||||||
@@ -1195,7 +1169,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
Stream::from_static_string(
|
Stream::from_static_string(
|
||||||
*code,
|
code,
|
||||||
&mut LS::machine_st(&mut self.payload).arena,
|
&mut LS::machine_st(&mut self.payload).arena,
|
||||||
),
|
),
|
||||||
ListingSource::User,
|
ListingSource::User,
|
||||||
@@ -1266,7 +1240,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
} else {
|
} else {
|
||||||
(
|
(
|
||||||
Stream::from_static_string(
|
Stream::from_static_string(
|
||||||
*code,
|
code,
|
||||||
&mut LS::machine_st(&mut self.payload).arena,
|
&mut LS::machine_st(&mut self.payload).arena,
|
||||||
),
|
),
|
||||||
ListingSource::User,
|
ListingSource::User,
|
||||||
|
|||||||
@@ -19,7 +19,6 @@ use std::cell::Cell;
|
|||||||
use std::collections::VecDeque;
|
use std::collections::VecDeque;
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::mem;
|
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@@ -136,7 +135,7 @@ impl RetractionInfo {
|
|||||||
|
|
||||||
Self {
|
Self {
|
||||||
orig_code_extent,
|
orig_code_extent,
|
||||||
records: mem::replace(&mut self.records, vec![]),
|
records: std::mem::take(&mut self.records),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -207,8 +206,8 @@ impl PredicateQueue {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn take(&mut self) -> Self {
|
pub(super) fn take(&mut self) -> Self {
|
||||||
Self {
|
Self {
|
||||||
predicates: mem::replace(&mut self.predicates, vec![]),
|
predicates: std::mem::take(&mut self.predicates),
|
||||||
compilation_target: self.compilation_target.clone(),
|
compilation_target: self.compilation_target,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -404,7 +403,7 @@ impl<'a> LoadState<'a> for BootstrappingLoadState<'a> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState {
|
fn machine_st(loader: &mut Self::LoaderFieldType) -> &mut MachineState {
|
||||||
&mut loader.term_stream.parser.lexer.machine_st
|
loader.term_stream.parser.lexer.machine_st
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -467,7 +466,7 @@ impl<'a> LoadState<'a> for InlineLoadState<'a> {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn machine_st(load_state: &mut Self::LoaderFieldType) -> &mut MachineState {
|
fn machine_st(load_state: &mut Self::LoaderFieldType) -> &mut MachineState {
|
||||||
&mut load_state.machine_st
|
load_state.machine_st
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
@@ -639,22 +638,19 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
RetractionRecord::AddedDiscontiguousPredicate(compilation_target, key) => {
|
RetractionRecord::AddedDiscontiguousPredicate(compilation_target, key) => {
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
self.wam_prelude
|
if let Some(skeleton) =
|
||||||
.indices
|
self.wam_prelude.indices.extensible_predicates.get_mut(&key)
|
||||||
.extensible_predicates
|
{
|
||||||
.get_mut(&key)
|
skeleton.core.is_discontiguous = false;
|
||||||
.map(|skeleton| {
|
}
|
||||||
skeleton.core.is_discontiguous = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
module.extensible_predicates.get_mut(&key).map(|skeleton| {
|
{
|
||||||
skeleton.core.is_discontiguous = false;
|
if let Some(skeleton) = module.extensible_predicates.get_mut(&key) {
|
||||||
});
|
skeleton.core.is_discontiguous = false;
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -662,23 +658,20 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
RetractionRecord::AddedDynamicPredicate(compilation_target, key) => {
|
RetractionRecord::AddedDynamicPredicate(compilation_target, key) => {
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
self.wam_prelude
|
if let Some(skeleton) =
|
||||||
.indices
|
self.wam_prelude.indices.extensible_predicates.get_mut(&key)
|
||||||
.extensible_predicates
|
{
|
||||||
.get_mut(&key)
|
skeleton.core.is_dynamic = false;
|
||||||
.map(|skeleton| {
|
}
|
||||||
skeleton.core.is_dynamic = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
module.extensible_predicates.get_mut(&key).map(|skeleton| {
|
{
|
||||||
skeleton.core.is_dynamic = false;
|
if let Some(skeleton) = module.extensible_predicates.get_mut(&key) {
|
||||||
skeleton.core.retracted_dynamic_clauses = None;
|
skeleton.core.is_dynamic = false;
|
||||||
});
|
skeleton.core.retracted_dynamic_clauses = None;
|
||||||
}
|
};
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -686,60 +679,52 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
RetractionRecord::AddedMultifilePredicate(compilation_target, key) => {
|
RetractionRecord::AddedMultifilePredicate(compilation_target, key) => {
|
||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => {
|
CompilationTarget::User => {
|
||||||
self.wam_prelude
|
if let Some(skeleton) =
|
||||||
.indices
|
self.wam_prelude.indices.extensible_predicates.get_mut(&key)
|
||||||
.extensible_predicates
|
{
|
||||||
.get_mut(&key)
|
skeleton.core.is_multifile = false;
|
||||||
.map(|skeleton| {
|
}
|
||||||
skeleton.core.is_multifile = false;
|
|
||||||
});
|
|
||||||
}
|
}
|
||||||
CompilationTarget::Module(module_name) => {
|
CompilationTarget::Module(module_name) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
module.extensible_predicates.get_mut(&key).map(|skeleton| {
|
{
|
||||||
skeleton.core.is_multifile = false;
|
if let Some(skeleton) = module.extensible_predicates.get_mut(&key) {
|
||||||
});
|
skeleton.core.is_multifile = false;
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::AddedModuleOp(module_name, mut op_decl) => {
|
RetractionRecord::AddedModuleOp(module_name, mut op_decl) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
op_decl.remove(&mut module.op_dir);
|
{
|
||||||
}
|
op_decl.remove(&mut module.op_dir);
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::ReplacedModuleOp(module_name, mut op_decl, op_desc) => {
|
RetractionRecord::ReplacedModuleOp(module_name, mut op_decl, op_desc) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
op_decl.op_desc = op_desc;
|
{
|
||||||
op_decl.insert_into_op_dir(&mut module.op_dir);
|
op_decl.op_desc = op_desc;
|
||||||
}
|
op_decl.insert_into_op_dir(&mut module.op_dir);
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::AddedModulePredicate(module_name, key) => {
|
RetractionRecord::AddedModulePredicate(module_name, key) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
module.code_dir.remove(&key);
|
{
|
||||||
}
|
module.code_dir.remove(&key);
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::ReplacedModulePredicate(module_name, key, old_code_idx) => {
|
RetractionRecord::ReplacedModulePredicate(module_name, key, old_code_idx) => {
|
||||||
match self.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(ref mut module) =
|
||||||
Some(ref mut module) => {
|
self.wam_prelude.indices.modules.get_mut(&module_name)
|
||||||
module
|
{
|
||||||
.code_dir
|
if let Some(code_idx) = module.code_dir.get_mut(&key) {
|
||||||
.get_mut(&key)
|
code_idx.set(old_code_idx)
|
||||||
.map(|code_idx| code_idx.set(old_code_idx));
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::AddedExtensiblePredicate(compilation_target, key) => {
|
RetractionRecord::AddedExtensiblePredicate(compilation_target, key) => {
|
||||||
@@ -758,11 +743,9 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
self.wam_prelude.indices.code_dir.remove(&key);
|
self.wam_prelude.indices.code_dir.remove(&key);
|
||||||
}
|
}
|
||||||
RetractionRecord::ReplacedUserPredicate(key, old_code_idx) => {
|
RetractionRecord::ReplacedUserPredicate(key, old_code_idx) => {
|
||||||
self.wam_prelude
|
if let Some(code_idx) = self.wam_prelude.indices.code_dir.get_mut(&key) {
|
||||||
.indices
|
code_idx.set(old_code_idx)
|
||||||
.code_dir
|
}
|
||||||
.get_mut(&key)
|
|
||||||
.map(|code_idx| code_idx.set(old_code_idx));
|
|
||||||
}
|
}
|
||||||
RetractionRecord::AddedIndex(index_key, clause_loc) => {
|
RetractionRecord::AddedIndex(index_key, clause_loc) => {
|
||||||
if let Some(index_loc) = index_key.switch_on_term_loc() {
|
if let Some(index_loc) = index_key.switch_on_term_loc() {
|
||||||
@@ -832,20 +815,17 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
RetractionRecord::ReplacedSwitchOnTermVarIndex(index_loc, old_v) => {
|
RetractionRecord::ReplacedSwitchOnTermVarIndex(index_loc, old_v) => {
|
||||||
match self.wam_prelude.code[index_loc] {
|
if let Instruction::IndexingCode(ref mut indexing_code) =
|
||||||
Instruction::IndexingCode(ref mut indexing_code) => {
|
self.wam_prelude.code[index_loc]
|
||||||
match &mut indexing_code[0] {
|
{
|
||||||
IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
if let IndexingLine::Indexing(IndexingInstruction::SwitchOnTerm(
|
||||||
_,
|
_,
|
||||||
ref mut v,
|
ref mut v,
|
||||||
..,
|
..,
|
||||||
)) => {
|
)) = &mut indexing_code[0]
|
||||||
*v = old_v;
|
{
|
||||||
}
|
*v = old_v;
|
||||||
_ => {}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::ModifiedTryMeElse(instr_loc, o) => {
|
RetractionRecord::ModifiedTryMeElse(instr_loc, o) => {
|
||||||
@@ -858,30 +838,24 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
self.wam_prelude.code[instr_loc] = Instruction::RevJmpBy(o);
|
self.wam_prelude.code[instr_loc] = Instruction::RevJmpBy(o);
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonClausePopBack(compilation_target, key) => {
|
RetractionRecord::SkeletonClausePopBack(compilation_target, key) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
{
|
{
|
||||||
Some(skeleton) => {
|
skeleton.clauses.pop_back();
|
||||||
skeleton.clauses.pop_back();
|
skeleton.core.clause_clause_locs.pop_back();
|
||||||
skeleton.core.clause_clause_locs.pop_back();
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonClausePopFront(compilation_target, key) => {
|
RetractionRecord::SkeletonClausePopFront(compilation_target, key) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
{
|
{
|
||||||
Some(skeleton) => {
|
skeleton.clauses.pop_front();
|
||||||
skeleton.clauses.pop_front();
|
skeleton.core.clause_clause_locs.pop_front();
|
||||||
skeleton.core.clause_clause_locs.pop_front();
|
skeleton.core.clause_assert_margin -= 1;
|
||||||
skeleton.core.clause_assert_margin -= 1;
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonLocalClauseClausePopFront(
|
RetractionRecord::SkeletonLocalClauseClausePopFront(
|
||||||
@@ -891,16 +865,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
) => {
|
) => {
|
||||||
let listing_src_file_name = self.listing_src_file_name();
|
let listing_src_file_name = self.listing_src_file_name();
|
||||||
|
|
||||||
match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
if let Some(skeleton) =
|
||||||
src_compilation_target,
|
self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
||||||
local_compilation_target,
|
src_compilation_target,
|
||||||
listing_src_file_name,
|
local_compilation_target,
|
||||||
key,
|
listing_src_file_name,
|
||||||
) {
|
key,
|
||||||
Some(skeleton) => {
|
)
|
||||||
skeleton.clause_clause_locs.pop_front();
|
{
|
||||||
}
|
skeleton.clause_clause_locs.pop_front();
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonLocalClauseClausePopBack(
|
RetractionRecord::SkeletonLocalClauseClausePopBack(
|
||||||
@@ -910,16 +883,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
) => {
|
) => {
|
||||||
let listing_src_file_name = self.listing_src_file_name();
|
let listing_src_file_name = self.listing_src_file_name();
|
||||||
|
|
||||||
match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
if let Some(skeleton) =
|
||||||
src_compilation_target,
|
self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
||||||
local_compilation_target,
|
src_compilation_target,
|
||||||
listing_src_file_name,
|
local_compilation_target,
|
||||||
key,
|
listing_src_file_name,
|
||||||
) {
|
key,
|
||||||
Some(skeleton) => {
|
)
|
||||||
skeleton.clause_clause_locs.pop_back();
|
{
|
||||||
}
|
skeleton.clause_clause_locs.pop_back();
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonLocalClauseTruncateBack(
|
RetractionRecord::SkeletonLocalClauseTruncateBack(
|
||||||
@@ -930,29 +902,25 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
) => {
|
) => {
|
||||||
let listing_src_file_name = self.listing_src_file_name();
|
let listing_src_file_name = self.listing_src_file_name();
|
||||||
|
|
||||||
match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
if let Some(skeleton) =
|
||||||
src_compilation_target,
|
self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
||||||
local_compilation_target,
|
src_compilation_target,
|
||||||
listing_src_file_name,
|
local_compilation_target,
|
||||||
key,
|
listing_src_file_name,
|
||||||
) {
|
key,
|
||||||
Some(skeleton) => {
|
)
|
||||||
skeleton.clause_clause_locs.truncate(len);
|
{
|
||||||
}
|
skeleton.clause_clause_locs.truncate(len);
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonClauseTruncateBack(compilation_target, key, len) => {
|
RetractionRecord::SkeletonClauseTruncateBack(compilation_target, key, len) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
{
|
{
|
||||||
Some(skeleton) => {
|
skeleton.clauses.truncate(len);
|
||||||
skeleton.clauses.truncate(len);
|
skeleton.core.clause_clause_locs.truncate(len);
|
||||||
skeleton.core.clause_clause_locs.truncate(len);
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::SkeletonClauseStartReplaced(
|
RetractionRecord::SkeletonClauseStartReplaced(
|
||||||
@@ -961,15 +929,12 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
target_pos,
|
target_pos,
|
||||||
clause_start,
|
clause_start,
|
||||||
) => {
|
) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
{
|
{
|
||||||
Some(skeleton) => {
|
skeleton.clauses[target_pos].clause_start = clause_start;
|
||||||
skeleton.clauses[target_pos].clause_start = clause_start;
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::RemovedDynamicSkeletonClause(
|
RetractionRecord::RemovedDynamicSkeletonClause(
|
||||||
@@ -978,26 +943,22 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
target_pos,
|
target_pos,
|
||||||
clause_clause_loc,
|
clause_clause_loc,
|
||||||
) => {
|
) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.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();
|
||||||
{
|
|
||||||
let clause_index_info = removed_clauses.pop().unwrap();
|
|
||||||
|
|
||||||
skeleton
|
skeleton
|
||||||
.core
|
.core
|
||||||
.clause_clause_locs
|
.clause_clause_locs
|
||||||
.insert(target_pos, clause_clause_loc);
|
.insert(target_pos, clause_clause_loc);
|
||||||
|
|
||||||
skeleton.clauses.insert(target_pos, clause_index_info);
|
skeleton.clauses.insert(target_pos, clause_index_info);
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::RemovedSkeletonClause(
|
RetractionRecord::RemovedSkeletonClause(
|
||||||
@@ -1007,19 +968,16 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
clause_index_info,
|
clause_index_info,
|
||||||
clause_clause_loc,
|
clause_clause_loc,
|
||||||
) => {
|
) => {
|
||||||
match self
|
if let Some(skeleton) = self
|
||||||
.wam_prelude
|
.wam_prelude
|
||||||
.indices
|
.indices
|
||||||
.get_predicate_skeleton_mut(&compilation_target, &key)
|
.get_predicate_skeleton_mut(&compilation_target, &key)
|
||||||
{
|
{
|
||||||
Some(skeleton) => {
|
skeleton
|
||||||
skeleton
|
.core
|
||||||
.core
|
.clause_clause_locs
|
||||||
.clause_clause_locs
|
.insert(target_pos, clause_clause_loc);
|
||||||
.insert(target_pos, clause_clause_loc);
|
skeleton.clauses.insert(target_pos, clause_index_info);
|
||||||
skeleton.clauses.insert(target_pos, clause_index_info);
|
|
||||||
}
|
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::ReplacedIndexingLine(index_loc, indexing_code) => {
|
RetractionRecord::ReplacedIndexingLine(index_loc, indexing_code) => {
|
||||||
@@ -1033,14 +991,15 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
) => {
|
) => {
|
||||||
let listing_src_file_name = self.listing_src_file_name();
|
let listing_src_file_name = self.listing_src_file_name();
|
||||||
|
|
||||||
match self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
if let Some(skeleton) =
|
||||||
compilation_target,
|
self.wam_prelude.indices.get_local_predicate_skeleton_mut(
|
||||||
local_compilation_target,
|
compilation_target,
|
||||||
listing_src_file_name,
|
local_compilation_target,
|
||||||
key,
|
listing_src_file_name,
|
||||||
) {
|
key,
|
||||||
Some(skeleton) => skeleton.clause_clause_locs = clause_locs,
|
)
|
||||||
None => {}
|
{
|
||||||
|
skeleton.clause_clause_locs = clause_locs
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton) => {
|
RetractionRecord::RemovedSkeleton(compilation_target, key, skeleton) => {
|
||||||
@@ -1091,7 +1050,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
|
|
||||||
let export_list = machine_st.read_term_from_heap(cell);
|
let export_list = machine_st.read_term_from_heap(cell);
|
||||||
let atom_tbl = &mut LS::machine_st(&mut self.payload).atom_tbl;
|
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())
|
Ok(export_list.into_iter().collect())
|
||||||
}
|
}
|
||||||
@@ -1363,7 +1322,7 @@ impl<'a, LS: LoadState<'a>> Loader<'a, LS> {
|
|||||||
*key,
|
*key,
|
||||||
) {
|
) {
|
||||||
Some(skeleton) if !skeleton.clause_clause_locs.is_empty() => {
|
Some(skeleton) if !skeleton.clause_clause_locs.is_empty() => {
|
||||||
mem::replace(&mut skeleton.clause_clause_locs, VecDeque::new())
|
std::mem::take(&mut skeleton.clause_clause_locs)
|
||||||
}
|
}
|
||||||
_ => return,
|
_ => return,
|
||||||
};
|
};
|
||||||
@@ -1400,9 +1359,7 @@ impl<'a> MachinePreludeView<'a> {
|
|||||||
CompilationTarget::User => CompositeOpDir::new(&self.indices.op_dir, None),
|
CompilationTarget::User => CompositeOpDir::new(&self.indices.op_dir, None),
|
||||||
CompilationTarget::Module(ref module_name) => {
|
CompilationTarget::Module(ref module_name) => {
|
||||||
match self.indices.modules.get(module_name) {
|
match self.indices.modules.get(module_name) {
|
||||||
Some(ref module) => {
|
Some(module) => CompositeOpDir::new(&self.indices.op_dir, Some(&module.op_dir)),
|
||||||
CompositeOpDir::new(&self.indices.op_dir, Some(&module.op_dir))
|
|
||||||
}
|
|
||||||
None => {
|
None => {
|
||||||
unreachable!()
|
unreachable!()
|
||||||
}
|
}
|
||||||
@@ -1413,13 +1370,10 @@ impl<'a> MachinePreludeView<'a> {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl MachineState {
|
impl MachineState {
|
||||||
pub(super) fn read_term_from_heap(
|
pub(super) fn read_term_from_heap(&mut self, term_addr: HeapCellValue) -> Term {
|
||||||
&mut self,
|
|
||||||
term_addr: HeapCellValue,
|
|
||||||
) -> Term {
|
|
||||||
let mut term_stack = vec![];
|
let mut term_stack = vec![];
|
||||||
let mut iter = stackful_post_order_iter::<NonListElider>
|
let mut iter =
|
||||||
(&mut self.heap, &mut self.stack, term_addr);
|
stackful_post_order_iter::<NonListElider>(&mut self.heap, &mut self.stack, term_addr);
|
||||||
|
|
||||||
while let Some(addr) = iter.next() {
|
while let Some(addr) = iter.next() {
|
||||||
let addr = unmark_cell_bits!(addr);
|
let addr = unmark_cell_bits!(addr);
|
||||||
@@ -1652,10 +1606,10 @@ impl Machine {
|
|||||||
|
|
||||||
let arity = self.deref_register(3);
|
let arity = self.deref_register(3);
|
||||||
let arity = match Number::try_from(arity) {
|
let arity = match Number::try_from(arity) {
|
||||||
Ok(Number::Integer(n)) if &*n >= &Integer::ZERO && &*n <= &Integer::from(MAX_ARITY) => {
|
Ok(Number::Integer(n)) if *n >= Integer::ZERO && *n <= Integer::from(MAX_ARITY) => {
|
||||||
let value: usize = (&*n).try_into().unwrap();
|
let value: usize = (&*n).try_into().unwrap();
|
||||||
Ok(value)
|
Ok(value)
|
||||||
},
|
}
|
||||||
Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => {
|
Ok(Number::Fixnum(n)) if n.get_num() >= 0 && n.get_num() <= MAX_ARITY as i64 => {
|
||||||
Ok(usize::try_from(n.get_num()).unwrap())
|
Ok(usize::try_from(n.get_num()).unwrap())
|
||||||
}
|
}
|
||||||
@@ -1770,14 +1724,11 @@ impl Machine {
|
|||||||
&ListingSource::DynamicallyGenerated,
|
&ListingSource::DynamicallyGenerated,
|
||||||
);
|
);
|
||||||
|
|
||||||
match loader.wam_prelude.indices.modules.get_mut(&module_name) {
|
if let Some(module) = loader.wam_prelude.indices.modules.get_mut(&module_name) {
|
||||||
Some(module) => {
|
for (key, value) in module.op_dir.drain(0..) {
|
||||||
for (key, value) in module.op_dir.drain(0..) {
|
let mut op_decl = OpDecl::new(value, key.0);
|
||||||
let mut op_decl = OpDecl::new(value, key.0);
|
op_decl.remove(&mut loader.wam_prelude.indices.op_dir);
|
||||||
op_decl.remove(&mut loader.wam_prelude.indices.op_dir);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
None => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1789,10 +1740,10 @@ impl Machine {
|
|||||||
self.restore_load_state_payload(result)
|
self.restore_load_state_payload(result)
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn loader_from_heap_evacuable<'a>(
|
pub(crate) fn loader_from_heap_evacuable(
|
||||||
&'a mut self,
|
&mut self,
|
||||||
r: RegType,
|
r: RegType,
|
||||||
) -> Loader<'a, LiveLoadAndMachineState<'a>> {
|
) -> Loader<'_, LiveLoadAndMachineState<'_>> {
|
||||||
let mut load_state = cell_as_load_state_payload!(self
|
let mut load_state = cell_as_load_state_payload!(self
|
||||||
.machine_st
|
.machine_st
|
||||||
.store(self.machine_st.deref(self.machine_st[r])));
|
.store(self.machine_st.deref(self.machine_st[r])));
|
||||||
@@ -1868,7 +1819,7 @@ impl Machine {
|
|||||||
let path = cell_as_atom!(self.deref_register(2));
|
let path = cell_as_atom!(self.deref_register(2));
|
||||||
|
|
||||||
self.load_contexts
|
self.load_contexts
|
||||||
.push(LoadContext::new(&*path.as_str(), stream));
|
.push(LoadContext::new(&path.as_str(), stream));
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2021,8 +1972,8 @@ impl Machine {
|
|||||||
|
|
||||||
loader.payload.compilation_target = compilation_target;
|
loader.payload.compilation_target = compilation_target;
|
||||||
|
|
||||||
let head = LiveLoadAndMachineState::machine_st(&mut loader.payload)
|
let head =
|
||||||
.read_term_from_heap(head);
|
LiveLoadAndMachineState::machine_st(&mut loader.payload).read_term_from_heap(head);
|
||||||
|
|
||||||
let name = if let Some(name) = head.name() {
|
let name = if let Some(name) = head.name() {
|
||||||
name
|
name
|
||||||
@@ -2218,7 +2169,7 @@ impl Machine {
|
|||||||
Ok(Number::Integer(n)) => {
|
Ok(Number::Integer(n)) => {
|
||||||
let value: usize = (&*n).try_into().unwrap();
|
let value: usize = (&*n).try_into().unwrap();
|
||||||
value
|
value
|
||||||
},
|
}
|
||||||
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
|
Ok(Number::Fixnum(n)) => usize::try_from(n.get_num()).unwrap(),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
};
|
};
|
||||||
@@ -2520,7 +2471,7 @@ pub(super) fn load_module(
|
|||||||
|
|
||||||
import_module_exports::<LiveLoadAndMachineState>(
|
import_module_exports::<LiveLoadAndMachineState>(
|
||||||
&mut payload,
|
&mut payload,
|
||||||
&compilation_target,
|
compilation_target,
|
||||||
module,
|
module,
|
||||||
code_dir,
|
code_dir,
|
||||||
op_dir,
|
op_dir,
|
||||||
|
|||||||
@@ -80,7 +80,7 @@ impl ValidType {
|
|||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub(crate) enum ResourceError {
|
pub(crate) enum ResourceError {
|
||||||
FiniteMemory(HeapCellValue),
|
FiniteMemory(HeapCellValue),
|
||||||
OutOfFiles
|
OutOfFiles,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) trait TypeError {
|
pub(crate) trait TypeError {
|
||||||
@@ -170,7 +170,11 @@ impl PermissionError for Atom {
|
|||||||
) -> MachineError {
|
) -> MachineError {
|
||||||
let stub = functor!(
|
let stub = functor!(
|
||||||
atom!("permission_error"),
|
atom!("permission_error"),
|
||||||
[atom(perm.as_atom()), atom(index_atom), cell(atom_as_cell!(self))]
|
[
|
||||||
|
atom(perm.as_atom()),
|
||||||
|
atom(index_atom),
|
||||||
|
cell(atom_as_cell!(self))
|
||||||
|
]
|
||||||
);
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
@@ -319,10 +323,7 @@ impl MachineState {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
ResourceError::OutOfFiles => {
|
ResourceError::OutOfFiles => {
|
||||||
functor!(
|
functor!(atom!("resource_error"), [atom(atom!("file_descriptors"))])
|
||||||
atom!("resource_error"),
|
|
||||||
[atom(atom!("file_descriptors"))]
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -355,13 +356,21 @@ impl MachineState {
|
|||||||
from: ErrorProvenance::Received,
|
from: ErrorProvenance::Received,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
ExistenceError::QualifiedProcedure { module_name, name, arity } => {
|
ExistenceError::QualifiedProcedure {
|
||||||
|
module_name,
|
||||||
|
name,
|
||||||
|
arity,
|
||||||
|
} => {
|
||||||
let h = self.heap.len();
|
let h = self.heap.len();
|
||||||
|
|
||||||
let ind_stub = functor!(atom!("/"), [atom(name), fixnum(arity)]);
|
let ind_stub = functor!(atom!("/"), [atom(name), fixnum(arity)]);
|
||||||
let res_stub = functor!(atom!(":"), [atom(module_name), str(h + 3, 0)], [ind_stub]);
|
let res_stub = functor!(atom!(":"), [atom(module_name), str(h + 3, 0)], [ind_stub]);
|
||||||
|
|
||||||
let stub = functor!(atom!("existence_error"), [atom(atom!("procedure")), str(h, 0)], [res_stub]);
|
let stub = functor!(
|
||||||
|
atom!("existence_error"),
|
||||||
|
[atom(atom!("procedure")), str(h, 0)],
|
||||||
|
[res_stub]
|
||||||
|
);
|
||||||
|
|
||||||
MachineError {
|
MachineError {
|
||||||
stub,
|
stub,
|
||||||
@@ -472,21 +481,15 @@ impl MachineState {
|
|||||||
|
|
||||||
pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
|
pub(super) fn session_error(&mut self, err: SessionError) -> MachineError {
|
||||||
match err {
|
match err {
|
||||||
SessionError::CannotOverwriteBuiltIn(key) => {
|
SessionError::CannotOverwriteBuiltIn(key) => self.permission_error(
|
||||||
self.permission_error(
|
Permission::Modify,
|
||||||
Permission::Modify,
|
atom!("static_procedure"),
|
||||||
atom!("static_procedure"),
|
functor_stub(key.0, key.1)
|
||||||
functor_stub(key.0, key.1)
|
.into_iter()
|
||||||
.into_iter()
|
.collect::<MachineStub>(),
|
||||||
.collect::<MachineStub>(),
|
),
|
||||||
)
|
|
||||||
}
|
|
||||||
SessionError::CannotOverwriteBuiltInModule(module) => {
|
SessionError::CannotOverwriteBuiltInModule(module) => {
|
||||||
self.permission_error(
|
self.permission_error(Permission::Modify, atom!("static_module"), module)
|
||||||
Permission::Modify,
|
|
||||||
atom!("static_module"),
|
|
||||||
module,
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
SessionError::ExistenceError(err) => self.existence_error(err),
|
SessionError::ExistenceError(err) => self.existence_error(err),
|
||||||
SessionError::ModuleDoesNotContainExport(..) => {
|
SessionError::ModuleDoesNotContainExport(..) => {
|
||||||
@@ -641,7 +644,7 @@ impl MachineState {
|
|||||||
self.ball.boundary = 0;
|
self.ball.boundary = 0;
|
||||||
self.ball.stub.truncate(0);
|
self.ball.stub.truncate(0);
|
||||||
|
|
||||||
self.heap.extend(err.into_iter());
|
self.heap.extend(err);
|
||||||
|
|
||||||
self.registers[1] = if err_len == 1 {
|
self.registers[1] = if err_len == 1 {
|
||||||
heap_loc_as_cell!(h)
|
heap_loc_as_cell!(h)
|
||||||
@@ -705,58 +708,58 @@ impl From<ParserError> for CompilationError {
|
|||||||
impl CompilationError {
|
impl CompilationError {
|
||||||
pub(crate) fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
pub(crate) fn line_and_col_num(&self) -> Option<(usize, usize)> {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::ParserError(ref err) => err.line_and_col_num(),
|
CompilationError::ParserError(err) => err.line_and_col_num(),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn as_functor(&self) -> MachineStub {
|
pub(crate) fn as_functor(&self) -> MachineStub {
|
||||||
match self {
|
match self {
|
||||||
&CompilationError::Arithmetic(..) => {
|
CompilationError::Arithmetic(..) => {
|
||||||
functor!(atom!("arithmetic_error"))
|
functor!(atom!("arithmetic_error"))
|
||||||
}
|
}
|
||||||
&CompilationError::CannotParseCyclicTerm => {
|
CompilationError::CannotParseCyclicTerm => {
|
||||||
functor!(atom!("cannot_parse_cyclic_term"))
|
functor!(atom!("cannot_parse_cyclic_term"))
|
||||||
}
|
}
|
||||||
&CompilationError::ExceededMaxArity => {
|
CompilationError::ExceededMaxArity => {
|
||||||
functor!(atom!("exceeded_max_arity"))
|
functor!(atom!("exceeded_max_arity"))
|
||||||
}
|
}
|
||||||
&CompilationError::ExpectedRel => {
|
CompilationError::ExpectedRel => {
|
||||||
functor!(atom!("expected_relation"))
|
functor!(atom!("expected_relation"))
|
||||||
}
|
}
|
||||||
&CompilationError::InadmissibleFact => {
|
CompilationError::InadmissibleFact => {
|
||||||
// TODO: type_error(callable, _).
|
// TODO: type_error(callable, _).
|
||||||
functor!(atom!("inadmissible_fact"))
|
functor!(atom!("inadmissible_fact"))
|
||||||
}
|
}
|
||||||
&CompilationError::InadmissibleQueryTerm => {
|
CompilationError::InadmissibleQueryTerm => {
|
||||||
// TODO: type_error(callable, _).
|
// TODO: type_error(callable, _).
|
||||||
functor!(atom!("inadmissible_query_term"))
|
functor!(atom!("inadmissible_query_term"))
|
||||||
}
|
}
|
||||||
&CompilationError::InconsistentEntry => {
|
CompilationError::InconsistentEntry => {
|
||||||
functor!(atom!("inconsistent_entry"))
|
functor!(atom!("inconsistent_entry"))
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidMetaPredicateDecl => {
|
CompilationError::InvalidMetaPredicateDecl => {
|
||||||
functor!(atom!("invalid_meta_predicate_decl"))
|
functor!(atom!("invalid_meta_predicate_decl"))
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidModuleDecl => {
|
CompilationError::InvalidModuleDecl => {
|
||||||
functor!(atom!("invalid_module_declaration"))
|
functor!(atom!("invalid_module_declaration"))
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidModuleExport => {
|
CompilationError::InvalidModuleExport => {
|
||||||
functor!(atom!("invalid_module_export"))
|
functor!(atom!("invalid_module_export"))
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidModuleResolution(ref module_name) => {
|
CompilationError::InvalidModuleResolution(ref module_name) => {
|
||||||
functor!(atom!("no_such_module"), [atom(module_name)])
|
functor!(atom!("no_such_module"), [atom(module_name)])
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidRuleHead => {
|
CompilationError::InvalidRuleHead => {
|
||||||
functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _).
|
functor!(atom!("invalid_head_of_rule")) // TODO: type_error(callable, _).
|
||||||
}
|
}
|
||||||
&CompilationError::InvalidUseModuleDecl => {
|
CompilationError::InvalidUseModuleDecl => {
|
||||||
functor!(atom!("invalid_use_module_declaration"))
|
functor!(atom!("invalid_use_module_declaration"))
|
||||||
}
|
}
|
||||||
&CompilationError::ParserError(ref err) => {
|
CompilationError::ParserError(ref err) => {
|
||||||
functor!(err.as_atom())
|
functor!(err.as_atom())
|
||||||
}
|
}
|
||||||
&CompilationError::UnreadableTerm => {
|
CompilationError::UnreadableTerm => {
|
||||||
functor!(atom!("unreadable_term"))
|
functor!(atom!("unreadable_term"))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -986,7 +989,11 @@ pub enum ExistenceError {
|
|||||||
Module(Atom),
|
Module(Atom),
|
||||||
ModuleSource(ModuleSource),
|
ModuleSource(ModuleSource),
|
||||||
Procedure(Atom, usize),
|
Procedure(Atom, usize),
|
||||||
QualifiedProcedure { module_name: Atom, name: Atom, arity: usize },
|
QualifiedProcedure {
|
||||||
|
module_name: Atom,
|
||||||
|
name: Atom,
|
||||||
|
arity: usize,
|
||||||
|
},
|
||||||
SourceSink(HeapCellValue),
|
SourceSink(HeapCellValue),
|
||||||
Stream(HeapCellValue),
|
Stream(HeapCellValue),
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -118,18 +118,12 @@ impl IndexPtr {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn is_undefined(&self) -> bool {
|
pub(crate) fn is_undefined(&self) -> bool {
|
||||||
match self.tag() {
|
matches!(self.tag(), IndexPtrTag::Undefined)
|
||||||
IndexPtrTag::Undefined => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn is_dynamic_undefined(&self) -> bool {
|
pub(crate) fn is_dynamic_undefined(&self) -> bool {
|
||||||
match self.tag() {
|
matches!(self.tag(), IndexPtrTag::DynamicUndefined)
|
||||||
IndexPtrTag::DynamicUndefined => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -231,6 +225,7 @@ pub enum VarKey {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl VarKey {
|
impl VarKey {
|
||||||
|
#[allow(clippy::inherent_to_string)]
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn to_string(&self) -> String {
|
pub(crate) fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
@@ -241,11 +236,7 @@ impl VarKey {
|
|||||||
|
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub(crate) fn is_anon(&self) -> bool {
|
pub(crate) fn is_anon(&self) -> bool {
|
||||||
if let VarKey::AnonVar(_) = self {
|
matches!(self, VarKey::AnonVar(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -429,9 +420,9 @@ impl IndexStore {
|
|||||||
match compilation_target {
|
match compilation_target {
|
||||||
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
CompilationTarget::User => self.meta_predicates.get(&(name, arity)),
|
||||||
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
CompilationTarget::Module(ref module_name) => match self.modules.get(module_name) {
|
||||||
Some(ref module) => module
|
Some(module) => module
|
||||||
.meta_predicates
|
.meta_predicates
|
||||||
.get(&(name.clone(), arity))
|
.get(&(name, arity))
|
||||||
.or_else(|| self.meta_predicates.get(&(name, arity))),
|
.or_else(|| self.meta_predicates.get(&(name, arity))),
|
||||||
None => self.meta_predicates.get(&(name, arity)),
|
None => self.meta_predicates.get(&(name, arity)),
|
||||||
},
|
},
|
||||||
@@ -446,7 +437,7 @@ impl IndexStore {
|
|||||||
.map(|skeleton| skeleton.core.is_dynamic)
|
.map(|skeleton| skeleton.core.is_dynamic)
|
||||||
.unwrap_or(false),
|
.unwrap_or(false),
|
||||||
_ => match self.modules.get(&module_name) {
|
_ => match self.modules.get(&module_name) {
|
||||||
Some(ref module) => module
|
Some(module) => module
|
||||||
.extensible_predicates
|
.extensible_predicates
|
||||||
.get(&key)
|
.get(&key)
|
||||||
.map(|skeleton| skeleton.core.is_dynamic)
|
.map(|skeleton| skeleton.core.is_dynamic)
|
||||||
|
|||||||
@@ -413,7 +413,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn increment_call_count(&mut self) -> bool {
|
pub(crate) fn increment_call_count(&mut self) -> bool {
|
||||||
if self.cwil.inference_limit_exceeded || self.ball.stub.len() > 0 {
|
if self.cwil.inference_limit_exceeded || !self.ball.stub.is_empty() {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -590,7 +590,9 @@ impl MachineState {
|
|||||||
|
|
||||||
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
|
let mut singleton_var_set: IndexMap<Ref, bool> = IndexMap::new();
|
||||||
|
|
||||||
for cell in stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, heap_loc) {
|
for cell in
|
||||||
|
stackful_preorder_iter::<NonListElider>(&mut self.heap, &mut self.stack, heap_loc)
|
||||||
|
{
|
||||||
let cell = unmark_cell_bits!(cell);
|
let cell = unmark_cell_bits!(cell);
|
||||||
|
|
||||||
if let Some(var) = cell.as_var() {
|
if let Some(var) = cell.as_var() {
|
||||||
@@ -644,10 +646,8 @@ impl MachineState {
|
|||||||
) -> Result<OnEOF, MachineStub> {
|
) -> Result<OnEOF, MachineStub> {
|
||||||
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 stream.options().eof_action() == EOFAction::Reset && !self.fail {
|
||||||
if self.fail == false {
|
return Ok(OnEOF::Continue);
|
||||||
return Ok(OnEOF::Continue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(OnEOF::Return)
|
Ok(OnEOF::Return)
|
||||||
@@ -674,10 +674,10 @@ impl MachineState {
|
|||||||
|
|
||||||
if let Stream::Byte(_) = stream {
|
if let Stream::Byte(_) = stream {
|
||||||
return self.read_term(
|
return self.read_term(
|
||||||
stream,
|
stream,
|
||||||
indices,
|
indices,
|
||||||
MachineState::read_term_from_user_input_eof_handler
|
MachineState::read_term_from_user_input_eof_handler,
|
||||||
)
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
unreachable!("Stream must be a Stream::Readline(_)")
|
unreachable!("Stream must be a Stream::Readline(_)")
|
||||||
@@ -691,10 +691,8 @@ impl MachineState {
|
|||||||
} else if stream.past_end_of_stream() {
|
} 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 stream.options().eof_action() == EOFAction::Reset && !self.fail {
|
||||||
if self.fail == false {
|
return Ok(OnEOF::Continue);
|
||||||
return Ok(OnEOF::Continue);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -716,11 +714,7 @@ impl MachineState {
|
|||||||
)?;
|
)?;
|
||||||
|
|
||||||
if stream.past_end_of_stream() {
|
if stream.past_end_of_stream() {
|
||||||
if EOFAction::Reset != stream.options().eof_action() {
|
return Ok(());
|
||||||
return Ok(());
|
|
||||||
} else if self.fail {
|
|
||||||
return Ok(());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
@@ -970,6 +964,7 @@ impl MachineState {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::upper_case_acronyms)]
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub(crate) struct CWIL {
|
pub(crate) struct CWIL {
|
||||||
count: Integer,
|
count: Integer,
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ impl MachineState {
|
|||||||
TrailRef::BlackboardEntry(key_atom) => {
|
TrailRef::BlackboardEntry(key_atom) => {
|
||||||
self.trail.push(TrailEntry::build_with(
|
self.trail.push(TrailEntry::build_with(
|
||||||
TrailEntryTag::TrailedBlackboardEntry,
|
TrailEntryTag::TrailedBlackboardEntry,
|
||||||
key_atom.index as u64,
|
key_atom.index,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.tr += 1;
|
self.tr += 1;
|
||||||
@@ -157,7 +157,7 @@ impl MachineState {
|
|||||||
TrailRef::BlackboardOffset(key_atom, value_cell) => {
|
TrailRef::BlackboardOffset(key_atom, value_cell) => {
|
||||||
self.trail.push(TrailEntry::build_with(
|
self.trail.push(TrailEntry::build_with(
|
||||||
TrailEntryTag::TrailedBlackboardOffset,
|
TrailEntryTag::TrailedBlackboardOffset,
|
||||||
key_atom.index as u64,
|
key_atom.index,
|
||||||
));
|
));
|
||||||
|
|
||||||
self.trail
|
self.trail
|
||||||
@@ -432,8 +432,7 @@ impl MachineState {
|
|||||||
pub fn compare_term_test(&mut self, var_comparison: VarComparison) -> Option<Ordering> {
|
pub fn compare_term_test(&mut self, var_comparison: VarComparison) -> Option<Ordering> {
|
||||||
let mut tabu_list = IndexSet::new();
|
let mut tabu_list = IndexSet::new();
|
||||||
|
|
||||||
while !self.pdl.is_empty() {
|
while let Some(s1) = self.pdl.pop() {
|
||||||
let s1 = self.pdl.pop().unwrap();
|
|
||||||
let s1 = self.deref(s1);
|
let s1 = self.deref(s1);
|
||||||
|
|
||||||
let s2 = self.pdl.pop().unwrap();
|
let s2 = self.pdl.pop().unwrap();
|
||||||
@@ -896,7 +895,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let s = string.as_str();
|
let s = string.as_str();
|
||||||
|
|
||||||
match heap_pstr_iter.compare_pstr_to_string(&*s) {
|
match heap_pstr_iter.compare_pstr_to_string(&s) {
|
||||||
Some(PStrPrefixCmpResult {
|
Some(PStrPrefixCmpResult {
|
||||||
focus,
|
focus,
|
||||||
offset,
|
offset,
|
||||||
@@ -1142,7 +1141,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let cycle_found = {
|
let cycle_found = {
|
||||||
let mut iter = cycle_detecting_stackless_preorder_iter(&mut self.heap, h);
|
let mut iter = cycle_detecting_stackless_preorder_iter(&mut self.heap, h);
|
||||||
while let Some(_) = iter.next() {}
|
for _ in iter.by_ref() {}
|
||||||
iter.cycle_found()
|
iter.cycle_found()
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1376,7 +1375,7 @@ impl MachineState {
|
|||||||
|
|
||||||
let mut type_error = |arity| {
|
let mut type_error = |arity| {
|
||||||
let err = self.type_error(ValidType::Integer, arity);
|
let err = self.type_error(ValidType::Integer, arity);
|
||||||
return Err(self.error_form(err, stub_gen()));
|
Err(self.error_form(err, stub_gen()))
|
||||||
};
|
};
|
||||||
|
|
||||||
let arity = match Number::try_from(arity) {
|
let arity = match Number::try_from(arity) {
|
||||||
@@ -1573,7 +1572,7 @@ impl MachineState {
|
|||||||
) -> Result<Vec<HeapCellValue>, MachineStub> {
|
) -> Result<Vec<HeapCellValue>, MachineStub> {
|
||||||
let mut heap_pstr_iter = HeapPStrIter::new(&self.heap, h);
|
let mut heap_pstr_iter = HeapPStrIter::new(&self.heap, h);
|
||||||
|
|
||||||
while let Some(iteratee) = heap_pstr_iter.next() {
|
for iteratee in heap_pstr_iter.by_ref() {
|
||||||
match iteratee {
|
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) => {
|
PStrIteratee::PStrSegment(_, pstr_atom, n) => {
|
||||||
@@ -1644,10 +1643,11 @@ impl MachineState {
|
|||||||
let addr = self.store(self.deref(addr));
|
let addr = self.store(self.deref(addr));
|
||||||
|
|
||||||
match Number::try_from(addr) {
|
match Number::try_from(addr) {
|
||||||
Ok(Number::Fixnum(n)) => match u8::try_from(n.get_num()) {
|
Ok(Number::Fixnum(n)) => {
|
||||||
Ok(b) => bytes.push(b),
|
if let Ok(b) = u8::try_from(n.get_num()) {
|
||||||
Err(_) => {}
|
bytes.push(b)
|
||||||
},
|
}
|
||||||
|
}
|
||||||
Ok(Number::Integer(n)) => {
|
Ok(Number::Integer(n)) => {
|
||||||
let b: u8 = (&*n).try_into().unwrap();
|
let b: u8 = (&*n).try_into().unwrap();
|
||||||
|
|
||||||
|
|||||||
@@ -82,6 +82,12 @@ impl MockWAM {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl Default for MockWAM {
|
||||||
|
fn default() -> Self {
|
||||||
|
Self::new()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub struct TermCopyingMockWAM<'a> {
|
pub struct TermCopyingMockWAM<'a> {
|
||||||
pub wam: &'a mut MockWAM,
|
pub wam: &'a mut MockWAM,
|
||||||
@@ -109,14 +115,14 @@ impl<'a> Deref for TermCopyingMockWAM<'a> {
|
|||||||
type Target = MockWAM;
|
type Target = MockWAM;
|
||||||
|
|
||||||
fn deref(&self) -> &Self::Target {
|
fn deref(&self) -> &Self::Target {
|
||||||
&self.wam
|
self.wam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
impl<'a> DerefMut for TermCopyingMockWAM<'a> {
|
impl<'a> DerefMut for TermCopyingMockWAM<'a> {
|
||||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||||
&mut self.wam
|
self.wam
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -165,9 +171,8 @@ impl<'a> CopierTarget for TermCopyingMockWAM<'a> {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
pub fn all_cells_marked_and_unforwarded(heap: &[HeapCellValue]) {
|
pub fn all_cells_marked_and_unforwarded(heap: &[HeapCellValue]) {
|
||||||
for (idx, cell) in heap.iter().enumerate() {
|
for (idx, cell) in heap.iter().enumerate() {
|
||||||
assert_eq!(
|
assert!(
|
||||||
cell.get_mark_bit(),
|
cell.get_mark_bit(),
|
||||||
true,
|
|
||||||
"cell {:?} at index {} is not marked",
|
"cell {:?} at index {} is not marked",
|
||||||
cell,
|
cell,
|
||||||
idx
|
idx
|
||||||
@@ -230,20 +235,16 @@ impl Machine {
|
|||||||
&mut self.machine_st.arena,
|
&mut self.machine_st.arena,
|
||||||
);
|
);
|
||||||
|
|
||||||
self.load_file(file.into(), stream);
|
self.load_file(file, stream);
|
||||||
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn test_load_string(&mut self, code: &str) -> Vec<u8> {
|
pub fn test_load_string(&mut self, code: &str) -> Vec<u8> {
|
||||||
let stream = Stream::from_owned_string(
|
let stream = Stream::from_owned_string(code.to_owned(), &mut self.machine_st.arena);
|
||||||
code.to_owned(),
|
|
||||||
&mut self.machine_st.arena,
|
|
||||||
);
|
|
||||||
|
|
||||||
self.load_file("<stdin>".into(), stream);
|
self.load_file("<stdin>", stream);
|
||||||
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
self.user_output.bytes().map(|b| b.unwrap()).collect()
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
|
|||||||
@@ -53,6 +53,8 @@ use indexmap::IndexMap;
|
|||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
|
|
||||||
|
use rand::rngs::StdRng;
|
||||||
|
use rand::SeedableRng;
|
||||||
use std::cmp::Ordering;
|
use std::cmp::Ordering;
|
||||||
use std::env;
|
use std::env;
|
||||||
use std::io::Read;
|
use std::io::Read;
|
||||||
@@ -61,8 +63,6 @@ use std::sync::atomic::AtomicBool;
|
|||||||
|
|
||||||
use self::config::MachineConfig;
|
use self::config::MachineConfig;
|
||||||
use self::parsed_results::*;
|
use self::parsed_results::*;
|
||||||
use rand::rngs::StdRng;
|
|
||||||
use rand::SeedableRng;
|
|
||||||
|
|
||||||
lazy_static! {
|
lazy_static! {
|
||||||
pub static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
|
pub static ref INTERRUPT: AtomicBool = AtomicBool::new(false);
|
||||||
@@ -172,7 +172,7 @@ pub(crate) fn import_builtin_impls(code_dir: &CodeDir, builtins: &mut Module) {
|
|||||||
|
|
||||||
for key in keys {
|
for key in keys {
|
||||||
let idx = code_dir.get(&key).unwrap();
|
let idx = code_dir.get(&key).unwrap();
|
||||||
builtins.code_dir.insert(key, idx.clone());
|
builtins.code_dir.insert(key, *idx);
|
||||||
builtins
|
builtins
|
||||||
.module_decl
|
.module_decl
|
||||||
.exports
|
.exports
|
||||||
@@ -225,7 +225,7 @@ impl Machine {
|
|||||||
key: PredicateKey,
|
key: PredicateKey,
|
||||||
) -> std::process::ExitCode {
|
) -> std::process::ExitCode {
|
||||||
if let Some(module) = self.indices.modules.get(&module_name) {
|
if let Some(module) = self.indices.modules.get(&module_name) {
|
||||||
if let Some(ref code_index) = module.code_dir.get(&key) {
|
if let Some(code_index) = module.code_dir.get(&key) {
|
||||||
let p = code_index.local().unwrap();
|
let p = code_index.local().unwrap();
|
||||||
|
|
||||||
self.machine_st.cp = BREAK_FROM_DISPATCH_LOOP_LOC;
|
self.machine_st.cp = BREAK_FROM_DISPATCH_LOOP_LOC;
|
||||||
@@ -252,9 +252,7 @@ impl Machine {
|
|||||||
path_buf.push("src/toplevel.pl");
|
path_buf.push("src/toplevel.pl");
|
||||||
|
|
||||||
let path = path_buf.to_str().unwrap();
|
let path = path_buf.to_str().unwrap();
|
||||||
let toplevel_stream =
|
let toplevel_stream = Stream::from_static_string(program, &mut self.machine_st.arena);
|
||||||
Stream::from_static_string(program, &mut self.machine_st.arena);
|
|
||||||
|
|
||||||
|
|
||||||
self.load_file(path, toplevel_stream);
|
self.load_file(path, toplevel_stream);
|
||||||
|
|
||||||
@@ -300,7 +298,11 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn run_top_level(&mut self, module_name: Atom, key: PredicateKey) -> std::process::ExitCode {
|
pub fn run_top_level(
|
||||||
|
&mut self,
|
||||||
|
module_name: Atom,
|
||||||
|
key: PredicateKey,
|
||||||
|
) -> std::process::ExitCode {
|
||||||
let mut arg_pstrs = vec![];
|
let mut arg_pstrs = vec![];
|
||||||
|
|
||||||
for arg in env::args() {
|
for arg in env::args() {
|
||||||
@@ -400,57 +402,51 @@ impl Machine {
|
|||||||
pub(crate) fn add_impls_to_indices(&mut self) {
|
pub(crate) fn add_impls_to_indices(&mut self) {
|
||||||
let impls_offset = self.code.len() + 4;
|
let impls_offset = self.code.len() + 4;
|
||||||
|
|
||||||
self.code.extend(
|
self.code.extend(vec![
|
||||||
vec![
|
Instruction::BreakFromDispatchLoop,
|
||||||
Instruction::BreakFromDispatchLoop,
|
Instruction::InstallVerifyAttr,
|
||||||
Instruction::InstallVerifyAttr,
|
Instruction::VerifyAttrInterrupt,
|
||||||
Instruction::VerifyAttrInterrupt,
|
Instruction::BreakFromDispatchLoop, // the location of LIB_QUERY_SUCCESS
|
||||||
Instruction::BreakFromDispatchLoop, // the location of LIB_QUERY_SUCCESS
|
Instruction::ExecuteTermGreaterThan,
|
||||||
Instruction::ExecuteTermGreaterThan,
|
Instruction::ExecuteTermLessThan,
|
||||||
Instruction::ExecuteTermLessThan,
|
Instruction::ExecuteTermGreaterThanOrEqual,
|
||||||
Instruction::ExecuteTermGreaterThanOrEqual,
|
Instruction::ExecuteTermLessThanOrEqual,
|
||||||
Instruction::ExecuteTermLessThanOrEqual,
|
Instruction::ExecuteTermEqual,
|
||||||
Instruction::ExecuteTermEqual,
|
Instruction::ExecuteTermNotEqual,
|
||||||
Instruction::ExecuteTermNotEqual,
|
Instruction::ExecuteNumberGreaterThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
||||||
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::ExecuteNumberLessThan(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
Instruction::ExecuteNumberGreaterThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
||||||
Instruction::ExecuteNumberGreaterThanOrEqual(
|
Instruction::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
||||||
ar_reg!(temp_v!(1)),
|
Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
||||||
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::ExecuteNumberLessThanOrEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
Instruction::ExecuteAcyclicTerm,
|
||||||
Instruction::ExecuteNumberEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
Instruction::ExecuteArg,
|
||||||
Instruction::ExecuteNumberNotEqual(ar_reg!(temp_v!(1)), ar_reg!(temp_v!(2))),
|
Instruction::ExecuteCompare,
|
||||||
Instruction::ExecuteIs(temp_v!(1), ar_reg!(temp_v!(2))),
|
Instruction::ExecuteCopyTerm,
|
||||||
Instruction::ExecuteAcyclicTerm,
|
Instruction::ExecuteFunctor,
|
||||||
Instruction::ExecuteArg,
|
Instruction::ExecuteGround,
|
||||||
Instruction::ExecuteCompare,
|
Instruction::ExecuteKeySort,
|
||||||
Instruction::ExecuteCopyTerm,
|
Instruction::ExecuteSort,
|
||||||
Instruction::ExecuteFunctor,
|
Instruction::ExecuteN(1),
|
||||||
Instruction::ExecuteGround,
|
Instruction::ExecuteN(2),
|
||||||
Instruction::ExecuteKeySort,
|
Instruction::ExecuteN(3),
|
||||||
Instruction::ExecuteSort,
|
Instruction::ExecuteN(4),
|
||||||
Instruction::ExecuteN(1),
|
Instruction::ExecuteN(5),
|
||||||
Instruction::ExecuteN(2),
|
Instruction::ExecuteN(6),
|
||||||
Instruction::ExecuteN(3),
|
Instruction::ExecuteN(7),
|
||||||
Instruction::ExecuteN(4),
|
Instruction::ExecuteN(8),
|
||||||
Instruction::ExecuteN(5),
|
Instruction::ExecuteN(9),
|
||||||
Instruction::ExecuteN(6),
|
Instruction::ExecuteIsAtom(temp_v!(1)),
|
||||||
Instruction::ExecuteN(7),
|
Instruction::ExecuteIsAtomic(temp_v!(1)),
|
||||||
Instruction::ExecuteN(8),
|
Instruction::ExecuteIsCompound(temp_v!(1)),
|
||||||
Instruction::ExecuteN(9),
|
Instruction::ExecuteIsInteger(temp_v!(1)),
|
||||||
Instruction::ExecuteIsAtom(temp_v!(1)),
|
Instruction::ExecuteIsNumber(temp_v!(1)),
|
||||||
Instruction::ExecuteIsAtomic(temp_v!(1)),
|
Instruction::ExecuteIsRational(temp_v!(1)),
|
||||||
Instruction::ExecuteIsCompound(temp_v!(1)),
|
Instruction::ExecuteIsFloat(temp_v!(1)),
|
||||||
Instruction::ExecuteIsInteger(temp_v!(1)),
|
Instruction::ExecuteIsNonVar(temp_v!(1)),
|
||||||
Instruction::ExecuteIsNumber(temp_v!(1)),
|
Instruction::ExecuteIsVar(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();
|
let key = instr.to_name_and_arity();
|
||||||
@@ -464,6 +460,7 @@ impl Machine {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
pub fn new(config: MachineConfig) -> Self {
|
pub fn new(config: MachineConfig) -> Self {
|
||||||
use ref_thread_local::RefThreadLocal;
|
use ref_thread_local::RefThreadLocal;
|
||||||
|
|
||||||
@@ -1048,7 +1045,7 @@ impl Machine {
|
|||||||
self.reset_attr_var_state(or_frame.prelude.attr_var_queue_len);
|
self.reset_attr_var_state(or_frame.prelude.attr_var_queue_len);
|
||||||
|
|
||||||
self.machine_st.hb = target_h;
|
self.machine_st.hb = target_h;
|
||||||
self.machine_st.p = self.machine_st.p + offset;
|
self.machine_st.p += offset;
|
||||||
|
|
||||||
self.machine_st.stack.truncate(b);
|
self.machine_st.stack.truncate(b);
|
||||||
self.machine_st.heap.truncate(target_h);
|
self.machine_st.heap.truncate(target_h);
|
||||||
@@ -1174,21 +1171,23 @@ impl Machine {
|
|||||||
} else {
|
} else {
|
||||||
Err(self.machine_st.throw_undefined_error(name, arity))
|
Err(self.machine_st.throw_undefined_error(name, arity))
|
||||||
}
|
}
|
||||||
} else {
|
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
||||||
if let Some(module) = self.indices.modules.get(&module_name) {
|
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
||||||
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
self.try_call(name, arity, idx.get())
|
||||||
self.try_call(name, arity, idx.get())
|
|
||||||
} else {
|
|
||||||
self.undefined_procedure(name, arity)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let stub = functor_stub(name, arity);
|
self.undefined_procedure(name, arity)
|
||||||
let err = self
|
|
||||||
.machine_st
|
|
||||||
.existence_error(ExistenceError::QualifiedProcedure { module_name, name, arity });
|
|
||||||
|
|
||||||
Err(self.machine_st.error_form(err, stub))
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let stub = functor_stub(name, arity);
|
||||||
|
let err = self
|
||||||
|
.machine_st
|
||||||
|
.existence_error(ExistenceError::QualifiedProcedure {
|
||||||
|
module_name,
|
||||||
|
name,
|
||||||
|
arity,
|
||||||
|
});
|
||||||
|
|
||||||
|
Err(self.machine_st.error_form(err, stub))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1202,21 +1201,23 @@ impl Machine {
|
|||||||
} else {
|
} else {
|
||||||
self.undefined_procedure(name, arity)
|
self.undefined_procedure(name, arity)
|
||||||
}
|
}
|
||||||
} else {
|
} else if let Some(module) = self.indices.modules.get(&module_name) {
|
||||||
if let Some(module) = self.indices.modules.get(&module_name) {
|
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
||||||
if let Some(idx) = module.code_dir.get(&(name, arity)).cloned() {
|
self.try_execute(name, arity, idx.get())
|
||||||
self.try_execute(name, arity, idx.get())
|
|
||||||
} else {
|
|
||||||
self.undefined_procedure(name, arity)
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
let stub = functor_stub(name, arity);
|
self.undefined_procedure(name, arity)
|
||||||
let err = self
|
|
||||||
.machine_st
|
|
||||||
.existence_error(ExistenceError::QualifiedProcedure { module_name, name, arity });
|
|
||||||
|
|
||||||
Err(self.machine_st.error_form(err, stub))
|
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
let stub = functor_stub(name, arity);
|
||||||
|
let err = self
|
||||||
|
.machine_st
|
||||||
|
.existence_error(ExistenceError::QualifiedProcedure {
|
||||||
|
module_name,
|
||||||
|
name,
|
||||||
|
arity,
|
||||||
|
});
|
||||||
|
|
||||||
|
Err(self.machine_st.error_form(err, stub))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
use crate::atom_table::*;
|
use crate::atom_table::*;
|
||||||
use ordered_float::OrderedFloat;
|
|
||||||
use dashu::*;
|
use dashu::*;
|
||||||
|
use ordered_float::OrderedFloat;
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
|
|
||||||
@@ -67,13 +67,10 @@ impl From<Vec<QueryResolutionLine>> for QueryResolution {
|
|||||||
|
|
||||||
// If there is only one line, and it is an empty match, return true.
|
// If there is only one line, and it is an empty match, return true.
|
||||||
if query_result_lines.len() == 1 {
|
if query_result_lines.len() == 1 {
|
||||||
match query_result_lines[0].clone() {
|
if let QueryResolutionLine::Match(m) = query_result_lines[0].clone() {
|
||||||
QueryResolutionLine::Match(m) => {
|
if m.is_empty() {
|
||||||
if m.is_empty() {
|
return QueryResolution::True;
|
||||||
return QueryResolution::True;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -81,13 +78,9 @@ impl From<Vec<QueryResolutionLine>> for QueryResolution {
|
|||||||
if query_result_lines
|
if query_result_lines
|
||||||
.iter()
|
.iter()
|
||||||
.any(|l| l == &QueryResolutionLine::True)
|
.any(|l| l == &QueryResolutionLine::True)
|
||||||
&& !query_result_lines.iter().any(|l| {
|
&& !query_result_lines
|
||||||
if let &QueryResolutionLine::Match(_) = l {
|
.iter()
|
||||||
true
|
.any(|l| matches!(l, QueryResolutionLine::Match(_)))
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
{
|
{
|
||||||
return QueryResolution::True;
|
return QueryResolution::True;
|
||||||
}
|
}
|
||||||
@@ -95,13 +88,7 @@ impl From<Vec<QueryResolutionLine>> for QueryResolution {
|
|||||||
// If there is at least one match, return all matches.
|
// If there is at least one match, return all matches.
|
||||||
let all_matches = query_result_lines
|
let all_matches = query_result_lines
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.filter(|l| {
|
.filter(|l| matches!(l, QueryResolutionLine::Match(_)))
|
||||||
if let &QueryResolutionLine::Match(_) = l {
|
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.map(|l| match l {
|
.map(|l| match l {
|
||||||
QueryResolutionLine::Match(m) => QueryMatch::from(m),
|
QueryResolutionLine::Match(m) => QueryMatch::from(m),
|
||||||
_ => unreachable!(),
|
_ => unreachable!(),
|
||||||
@@ -132,7 +119,11 @@ fn split_response_string(input: &str) -> Vec<String> {
|
|||||||
')' => level_parenthesis -= 1,
|
')' => level_parenthesis -= 1,
|
||||||
'"' => in_double_quotes = !in_double_quotes,
|
'"' => in_double_quotes = !in_double_quotes,
|
||||||
'\'' => in_single_quotes = !in_single_quotes,
|
'\'' => in_single_quotes = !in_single_quotes,
|
||||||
',' if level_bracket == 0 && level_parenthesis == 0 && !in_double_quotes && !in_single_quotes => {
|
',' if level_bracket == 0
|
||||||
|
&& level_parenthesis == 0
|
||||||
|
&& !in_double_quotes
|
||||||
|
&& !in_single_quotes =>
|
||||||
|
{
|
||||||
result.push(input[start..i].trim().to_string());
|
result.push(input[start..i].trim().to_string());
|
||||||
start = i + 1;
|
start = i + 1;
|
||||||
}
|
}
|
||||||
@@ -167,13 +158,13 @@ fn parse_prolog_response(input: &str) -> HashMap<String, String> {
|
|||||||
let key = result.0;
|
let key = result.0;
|
||||||
let value = result.1;
|
let value = result.1;
|
||||||
// cut off at given characters/strings:
|
// cut off at given characters/strings:
|
||||||
let value = value.split("\n").next().unwrap().to_string();
|
let value = value.split('\n').next().unwrap().to_string();
|
||||||
let value = value.split(" ").next().unwrap().to_string();
|
let value = value.split(' ').next().unwrap().to_string();
|
||||||
let value = value.split("\t").next().unwrap().to_string();
|
let value = value.split('\t').next().unwrap().to_string();
|
||||||
let value = value.split("error").next().unwrap().to_string();
|
let value = value.split("error").next().unwrap().to_string();
|
||||||
map.insert(key, value);
|
map.insert(key, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
map
|
map
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -192,9 +183,8 @@ impl TryFrom<String> for QueryResolutionLine {
|
|||||||
Ok((key, Value::try_from(value)?))
|
Ok((key, Value::try_from(value)?))
|
||||||
})
|
})
|
||||||
.filter_map(Result::ok)
|
.filter_map(Result::ok)
|
||||||
.collect::<BTreeMap<_, _>>()
|
.collect::<BTreeMap<_, _>>(),
|
||||||
)
|
)),
|
||||||
),
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -229,25 +219,25 @@ impl TryFrom<String> for Value {
|
|||||||
Ok(Value::Float(OrderedFloat(float_value)))
|
Ok(Value::Float(OrderedFloat(float_value)))
|
||||||
} else if let Ok(int_value) = string.parse::<i128>() {
|
} else if let Ok(int_value) = string.parse::<i128>() {
|
||||||
Ok(Value::Integer(int_value.into()))
|
Ok(Value::Integer(int_value.into()))
|
||||||
} else if trimmed.starts_with("'") && trimmed.ends_with("'") {
|
} else if trimmed.starts_with('\'') && trimmed.ends_with('\'')
|
||||||
|
|| trimmed.starts_with('"') && trimmed.ends_with('"')
|
||||||
|
{
|
||||||
Ok(Value::String(trimmed[1..trimmed.len() - 1].into()))
|
Ok(Value::String(trimmed[1..trimmed.len() - 1].into()))
|
||||||
} else if trimmed.starts_with("\"") && trimmed.ends_with("\"") {
|
} else if trimmed.starts_with('[') && trimmed.ends_with(']') {
|
||||||
Ok(Value::String(trimmed[1..trimmed.len() - 1].into()))
|
|
||||||
} else if trimmed.starts_with("[") && trimmed.ends_with("]") {
|
|
||||||
let split = split_nested_list(&trimmed[1..trimmed.len() - 1]);
|
let split = split_nested_list(&trimmed[1..trimmed.len() - 1]);
|
||||||
|
|
||||||
let values = split
|
let values = split
|
||||||
.into_iter()
|
.into_iter()
|
||||||
.map(Value::try_from)
|
.map(Value::try_from)
|
||||||
.collect::<Result<Vec<_>, _>>()?;
|
.collect::<Result<Vec<_>, _>>()?;
|
||||||
|
|
||||||
Ok(Value::List(values))
|
Ok(Value::List(values))
|
||||||
} else if trimmed.starts_with("{") && trimmed.ends_with("}") {
|
} else if trimmed.starts_with('{') && trimmed.ends_with('}') {
|
||||||
let mut iter = trimmed[1..trimmed.len() - 1].split(",");
|
let iter = trimmed[1..trimmed.len() - 1].split(',');
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
for value in iter {
|
||||||
let items: Vec<_> = value.split(":").collect();
|
let items: Vec<_> = value.split(':').collect();
|
||||||
if items.len() == 2 {
|
if items.len() == 2 {
|
||||||
let _key = items[0].to_string();
|
let _key = items[0].to_string();
|
||||||
let value = items[1].to_string();
|
let value = items[1].to_string();
|
||||||
@@ -257,11 +247,11 @@ impl TryFrom<String> for Value {
|
|||||||
|
|
||||||
Ok(Value::Structure(atom!("{}"), values))
|
Ok(Value::Structure(atom!("{}"), values))
|
||||||
} else if trimmed.starts_with("<<") && trimmed.ends_with(">>") {
|
} else if trimmed.starts_with("<<") && trimmed.ends_with(">>") {
|
||||||
let mut iter = trimmed[2..trimmed.len() - 2].split(",");
|
let iter = trimmed[2..trimmed.len() - 2].split(',');
|
||||||
let mut values = vec![];
|
let mut values = vec![];
|
||||||
|
|
||||||
while let Some(value) = iter.next() {
|
for value in iter {
|
||||||
let items: Vec<_> = value.split(":").collect();
|
let items: Vec<_> = value.split(':').collect();
|
||||||
if items.len() == 2 {
|
if items.len() == 2 {
|
||||||
let _key = items[0].to_string();
|
let _key = items[0].to_string();
|
||||||
let value = items[1].to_string();
|
let value = items[1].to_string();
|
||||||
@@ -270,7 +260,7 @@ impl TryFrom<String> for Value {
|
|||||||
}
|
}
|
||||||
|
|
||||||
Ok(Value::Structure(atom!("<<>>"), values))
|
Ok(Value::Structure(atom!("<<>>"), values))
|
||||||
} else if !trimmed.contains(",") && !trimmed.contains("'") && !trimmed.contains("\"") {
|
} else if !trimmed.contains(',') && !trimmed.contains('\'') && !trimmed.contains('"') {
|
||||||
Ok(Value::String(trimmed.into()))
|
Ok(Value::String(trimmed.into()))
|
||||||
} else {
|
} else {
|
||||||
Err(())
|
Err(())
|
||||||
|
|||||||
@@ -34,10 +34,10 @@ impl From<Atom> for PartialString {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Into<Atom> for PartialString {
|
impl From<PartialString> for Atom {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn into(self: Self) -> Atom {
|
fn from(val: PartialString) -> Self {
|
||||||
self.0
|
val.0
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ impl PartialString {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn new<'a>(src: &'a str, atom_tbl: &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 terminator_idx = scan_for_terminator(src.chars());
|
||||||
let pstr = PartialString(AtomTable::build_with(&atom_tbl, &src[..terminator_idx]));
|
let pstr = PartialString(AtomTable::build_with(atom_tbl, &src[..terminator_idx]));
|
||||||
Some(if terminator_idx < src.as_bytes().len() {
|
Some(if terminator_idx < src.as_bytes().len() {
|
||||||
(pstr, &src[terminator_idx + 1..])
|
(pstr, &src[terminator_idx + 1..])
|
||||||
} else {
|
} else {
|
||||||
@@ -154,13 +154,13 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
let s = &s[result.prefix_len..];
|
let s = &s[result.prefix_len..];
|
||||||
|
|
||||||
if s.len() >= t.len() {
|
if s.len() >= t.len() {
|
||||||
if (&*s).starts_with(&*t) {
|
if s.starts_with(&*t) {
|
||||||
result.prefix_len += t.len();
|
result.prefix_len += t.len();
|
||||||
result.offset += t.len();
|
result.offset += t.len();
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
} else if t.starts_with(&s) {
|
} else if t.starts_with(s) {
|
||||||
result.prefix_len += s.len();
|
result.prefix_len += s.len();
|
||||||
result.offset += s.len();
|
result.offset += s.len();
|
||||||
|
|
||||||
@@ -218,10 +218,11 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
self.brent_st.hare = orig_hare;
|
self.brent_st.hare = orig_hare;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::inherent_to_string)]
|
||||||
pub fn to_string(&mut self) -> String {
|
pub fn to_string(&mut self) -> String {
|
||||||
let mut buf = String::with_capacity(32);
|
let mut buf = String::with_capacity(32);
|
||||||
|
|
||||||
while let Some(iteratee) = self.next() {
|
for iteratee in self.by_ref() {
|
||||||
match iteratee {
|
match iteratee {
|
||||||
PStrIteratee::Char(_, c) => {
|
PStrIteratee::Char(_, c) => {
|
||||||
buf.push(c);
|
buf.push(c);
|
||||||
@@ -334,14 +335,10 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
heap_bound_deref(self.heap, self.heap[h]),
|
heap_bound_deref(self.heap, self.heap[h]),
|
||||||
);
|
);
|
||||||
|
|
||||||
return if let Some(c) = value.as_char() {
|
return value.as_char().map(|c| PStrIterStep {
|
||||||
Some(PStrIterStep {
|
|
||||||
iteratee: PStrIteratee::Char(curr_hare, c),
|
iteratee: PStrIteratee::Char(curr_hare, c),
|
||||||
next_hare: h+1,
|
next_hare: h+1,
|
||||||
})
|
});
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Str, s) => {
|
(HeapCellValueTag::Str, s) => {
|
||||||
let (name, arity) = cell_as_atom_cell!(self.heap[s])
|
let (name, arity) = cell_as_atom_cell!(self.heap[s])
|
||||||
@@ -353,14 +350,10 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
heap_bound_deref(self.heap, self.heap[s+1]),
|
heap_bound_deref(self.heap, self.heap[s+1]),
|
||||||
);
|
);
|
||||||
|
|
||||||
if let Some(c) = value.as_char() {
|
value.as_char().map(|c| PStrIterStep {
|
||||||
Some(PStrIterStep {
|
|
||||||
iteratee: PStrIteratee::Char(curr_hare, c),
|
iteratee: PStrIteratee::Char(curr_hare, c),
|
||||||
next_hare: s+2,
|
next_hare: s+2,
|
||||||
})
|
})
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
};
|
};
|
||||||
@@ -405,10 +398,7 @@ impl<'a> HeapPStrIter<'a> {
|
|||||||
|
|
||||||
match self.brent_st.step(next_hare) {
|
match self.brent_st.step(next_hare) {
|
||||||
Some(cycle_result) => {
|
Some(cycle_result) => {
|
||||||
debug_assert!(match cycle_result {
|
debug_assert!(matches!(cycle_result, CycleSearchResult::Cyclic(..)));
|
||||||
CycleSearchResult::Cyclic(..) => true,
|
|
||||||
_ => false,
|
|
||||||
});
|
|
||||||
|
|
||||||
self.walk_hare_to_cycle_end();
|
self.walk_hare_to_cycle_end();
|
||||||
self.stepper = HeapPStrIter::post_cycle_discovery_stepper;
|
self.stepper = HeapPStrIter::post_cycle_discovery_stepper;
|
||||||
@@ -550,11 +540,7 @@ pub enum PStrCmpResult {
|
|||||||
impl PStrCmpResult {
|
impl PStrCmpResult {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_second_iter(&self) -> bool {
|
pub fn is_second_iter(&self) -> bool {
|
||||||
if let PStrCmpResult::SecondIterContinuable(_) = self {
|
matches!(self, PStrCmpResult::SecondIterContinuable(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -600,8 +586,8 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
return PStrCmpResult::Ordered(c1.cmp(&c2));
|
return PStrCmpResult::Ordered(c1.cmp(&c2));
|
||||||
}
|
}
|
||||||
|
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, step_2);
|
||||||
|
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
@@ -623,15 +609,15 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
if n1 < pstr_atom.len() {
|
if n1 < pstr_atom.len() {
|
||||||
step_2.iteratee = PStrIteratee::PStrSegment(f2, pstr_atom, n1);
|
step_2.iteratee = PStrIteratee::PStrSegment(f2, pstr_atom, n1);
|
||||||
|
|
||||||
let c1_result = cycle_detection_step(i1, i2, &step_1);
|
let c1_result = cycle_detection_step(i1, i2, step_1);
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
|
|
||||||
if !c1_result {
|
if !c1_result {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, step_2);
|
||||||
|
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
@@ -641,7 +627,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let c2_result = cycle_detection_step(i2, i1, &step_2);
|
let c2_result = cycle_detection_step(i2, i1, step_2);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
|
|
||||||
if !c2_result {
|
if !c2_result {
|
||||||
@@ -662,15 +648,15 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
if n1 < pstr_atom.len() {
|
if n1 < pstr_atom.len() {
|
||||||
step_1.iteratee = PStrIteratee::PStrSegment(f1, pstr_atom, n1);
|
step_1.iteratee = PStrIteratee::PStrSegment(f1, pstr_atom, n1);
|
||||||
|
|
||||||
let c2_result = cycle_detection_step(i2, i1, &step_2);
|
let c2_result = cycle_detection_step(i2, i1, step_2);
|
||||||
r2 = step(i2, step_2.next_hare);
|
r2 = step(i2, step_2.next_hare);
|
||||||
|
|
||||||
if !c2_result {
|
if !c2_result {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, step_2);
|
||||||
|
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
@@ -680,7 +666,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let c1_result = cycle_detection_step(i1, i2, &step_1);
|
let c1_result = cycle_detection_step(i1, i2, step_1);
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
|
|
||||||
if !c1_result {
|
if !c1_result {
|
||||||
@@ -693,8 +679,8 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
PStrIteratee::PStrSegment(f2, pstr2_atom, n2),
|
PStrIteratee::PStrSegment(f2, pstr2_atom, n2),
|
||||||
) => {
|
) => {
|
||||||
if pstr1_atom == pstr2_atom && n1 == n2 {
|
if pstr1_atom == pstr2_atom && n1 == n2 {
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, step_2);
|
||||||
|
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
@@ -713,9 +699,9 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
let str2 = pstr2.as_str_from(n2);
|
let str2 = pstr2.as_str_from(n2);
|
||||||
|
|
||||||
match str1.len().cmp(&str2.len()) {
|
match str1.len().cmp(&str2.len()) {
|
||||||
Ordering::Equal if &*str1 == &*str2 => {
|
Ordering::Equal if *str1 == *str2 => {
|
||||||
cycle_detection_step(i1, i2, &step_1);
|
cycle_detection_step(i1, i2, step_1);
|
||||||
let both_cyclic = cycle_detection_step(i2, i1, &step_2);
|
let both_cyclic = cycle_detection_step(i2, i1, step_2);
|
||||||
|
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
@@ -727,7 +713,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
Ordering::Less if str2.starts_with(&*str1) => {
|
Ordering::Less if str2.starts_with(&*str1) => {
|
||||||
step_2.iteratee =
|
step_2.iteratee =
|
||||||
PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
|
PStrIteratee::PStrSegment(f2, pstr2_atom, n2 + str1.len());
|
||||||
let c1_result = cycle_detection_step(i1, i2, &step_1);
|
let c1_result = cycle_detection_step(i1, i2, step_1);
|
||||||
r1 = step(i1, i1.brent_st.hare);
|
r1 = step(i1, i1.brent_st.hare);
|
||||||
|
|
||||||
if !c1_result {
|
if !c1_result {
|
||||||
@@ -737,7 +723,7 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
Ordering::Greater if str1.starts_with(&*str2) => {
|
Ordering::Greater if str1.starts_with(&*str2) => {
|
||||||
step_1.iteratee =
|
step_1.iteratee =
|
||||||
PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
|
PStrIteratee::PStrSegment(f1, pstr1_atom, n1 + str2.len());
|
||||||
let c2_result = cycle_detection_step(i2, i1, &step_2);
|
let c2_result = cycle_detection_step(i2, i1, step_2);
|
||||||
r2 = step(i2, i2.brent_st.hare);
|
r2 = step(i2, i2.brent_st.hare);
|
||||||
|
|
||||||
if !c2_result {
|
if !c2_result {
|
||||||
@@ -786,12 +772,10 @@ pub fn compare_pstr_prefixes<'a>(
|
|||||||
} else {
|
} else {
|
||||||
PStrCmpResult::FirstIterContinuable(r1.unwrap().iteratee)
|
PStrCmpResult::FirstIterContinuable(r1.unwrap().iteratee)
|
||||||
}
|
}
|
||||||
|
} else if i1.is_continuable() && i2.is_continuable() {
|
||||||
|
PStrCmpResult::Ordered(Ordering::Equal)
|
||||||
} else {
|
} else {
|
||||||
if i1.is_continuable() && i2.is_continuable() {
|
PStrCmpResult::Unordered
|
||||||
PStrCmpResult::Ordered(Ordering::Equal)
|
|
||||||
} else {
|
|
||||||
PStrCmpResult::Unordered
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -885,7 +869,7 @@ mod test {
|
|||||||
{
|
{
|
||||||
let mut iter = HeapPStrIter::new(&wam.machine_st.heap, 0);
|
let mut iter = HeapPStrIter::new(&wam.machine_st.heap, 0);
|
||||||
|
|
||||||
while let Some(_) = iter.next() {}
|
for _ in iter.by_ref() {}
|
||||||
|
|
||||||
assert!(!iter.at_string_terminator());
|
assert!(!iter.at_string_terminator());
|
||||||
}
|
}
|
||||||
@@ -1009,7 +993,7 @@ mod test {
|
|||||||
|
|
||||||
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.fail, false);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
|
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
|
||||||
|
|
||||||
@@ -1032,7 +1016,7 @@ mod test {
|
|||||||
|
|
||||||
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.fail, false);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
// test "abc" = [X,b,Z].
|
// test "abc" = [X,b,Z].
|
||||||
|
|
||||||
@@ -1054,7 +1038,7 @@ mod test {
|
|||||||
|
|
||||||
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
unify!(wam.machine_st, cstr_var_cell, heap_loc_as_cell!(1));
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.fail, false);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
|
assert_eq!(wam.machine_st.heap[2], char_as_cell!('a'),);
|
||||||
|
|
||||||
@@ -1075,7 +1059,7 @@ mod test {
|
|||||||
|
|
||||||
print_heap_terms(wam.machine_st.heap.iter(), 0);
|
print_heap_terms(wam.machine_st.heap.iter(), 0);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.fail, false);
|
assert!(!wam.machine_st.fail);
|
||||||
|
|
||||||
assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(5));
|
assert_eq!(wam.machine_st.heap[2], pstr_loc_as_cell!(5));
|
||||||
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(1));
|
assert_eq!(wam.machine_st.heap[3], pstr_loc_as_cell!(1));
|
||||||
@@ -1107,7 +1091,7 @@ mod test {
|
|||||||
|
|
||||||
// assert!(iter.next().is_none());
|
// assert!(iter.next().is_none());
|
||||||
|
|
||||||
while let Some(_) = iter.next() {}
|
for _ in iter {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -100,7 +100,7 @@ fn setup_module_export(
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn build_rule_body(vars: &[Term], body_term: Term) -> Term {
|
pub(crate) fn build_rule_body(vars: &[Term], body_term: Term) -> Term {
|
||||||
let head_term = Term::Clause(Cell::default(), atom!(""), vars.iter().cloned().collect());
|
let head_term = Term::Clause(Cell::default(), atom!(""), vars.to_vec());
|
||||||
let rule = vec![head_term, body_term];
|
let rule = vec![head_term, body_term];
|
||||||
|
|
||||||
Term::Clause(Cell::default(), atom!(":-"), rule)
|
Term::Clause(Cell::default(), atom!(":-"), rule)
|
||||||
@@ -238,7 +238,7 @@ fn setup_meta_predicate<'a, LS: LoadState<'a>>(
|
|||||||
) -> Result<(Atom, Vec<MetaSpec>), CompilationError> {
|
) -> Result<(Atom, Vec<MetaSpec>), CompilationError> {
|
||||||
let mut meta_specs = vec![];
|
let mut meta_specs = vec![];
|
||||||
|
|
||||||
for meta_spec in terms.into_iter() {
|
for meta_spec in terms.iter_mut() {
|
||||||
match meta_spec {
|
match meta_spec {
|
||||||
Term::Literal(_, Literal::Atom(meta_spec)) => {
|
Term::Literal(_, Literal::Atom(meta_spec)) => {
|
||||||
let meta_spec = match meta_spec {
|
let meta_spec = match meta_spec {
|
||||||
@@ -310,11 +310,11 @@ pub(super) fn setup_declaration<'a, LS: LoadState<'a>>(
|
|||||||
}
|
}
|
||||||
(atom!("module"), 2) => {
|
(atom!("module"), 2) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
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) => {
|
(atom!("op"), 3) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
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) => {
|
(atom!("non_counted_backtracking"), 1) => {
|
||||||
let (name, arity) = setup_predicate_indicator(&mut terms.pop().unwrap())?;
|
let (name, arity) = setup_predicate_indicator(&mut terms.pop().unwrap())?;
|
||||||
@@ -323,7 +323,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"), 1) => Ok(Declaration::UseModule(setup_use_module_decl(terms)?)),
|
||||||
(atom!("use_module"), 2) => {
|
(atom!("use_module"), 2) => {
|
||||||
let atom_tbl = &mut LS::machine_st(&mut loader.payload).atom_tbl;
|
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))
|
Ok(Declaration::UseQualifiedModule(name, exports))
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ impl Index<usize> for AndFrame {
|
|||||||
let index_offset = (index - 1) * mem::size_of::<HeapCellValue>();
|
let index_offset = (index - 1) * mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::transmute::<&AndFrame, *const u8>(self);
|
let ptr = self as *const crate::machine::stack::AndFrame as *const u8;
|
||||||
let ptr = ptr as usize + prelude_offset + index_offset;
|
let ptr = ptr as usize + prelude_offset + index_offset;
|
||||||
|
|
||||||
&*(ptr as *const HeapCellValue)
|
&*(ptr as *const HeapCellValue)
|
||||||
@@ -70,7 +70,7 @@ impl IndexMut<usize> for AndFrame {
|
|||||||
let index_offset = (index - 1) * mem::size_of::<HeapCellValue>();
|
let index_offset = (index - 1) * mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::transmute::<&mut AndFrame, *const u8>(self);
|
let ptr = self as *mut crate::machine::stack::AndFrame as *const u8;
|
||||||
let ptr = ptr as usize + prelude_offset + index_offset;
|
let ptr = ptr as usize + prelude_offset + index_offset;
|
||||||
|
|
||||||
&mut *(ptr as *mut HeapCellValue)
|
&mut *(ptr as *mut HeapCellValue)
|
||||||
@@ -129,7 +129,7 @@ impl Index<usize> for OrFrame {
|
|||||||
let index_offset = index * mem::size_of::<HeapCellValue>();
|
let index_offset = index * mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::transmute::<&OrFrame, *const u8>(self);
|
let ptr = self as *const crate::machine::stack::OrFrame as *const u8;
|
||||||
let ptr = ptr as usize + prelude_offset + index_offset;
|
let ptr = ptr as usize + prelude_offset + index_offset;
|
||||||
|
|
||||||
&*(ptr as *const HeapCellValue)
|
&*(ptr as *const HeapCellValue)
|
||||||
@@ -144,7 +144,7 @@ impl IndexMut<usize> for OrFrame {
|
|||||||
let index_offset = index * mem::size_of::<HeapCellValue>();
|
let index_offset = index * mem::size_of::<HeapCellValue>();
|
||||||
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let ptr = mem::transmute::<&mut OrFrame, *const u8>(self);
|
let ptr = self as *mut crate::machine::stack::OrFrame as *const u8;
|
||||||
let ptr = ptr as usize + prelude_offset + index_offset;
|
let ptr = ptr as usize + prelude_offset + index_offset;
|
||||||
|
|
||||||
&mut *(ptr as *mut HeapCellValue)
|
&mut *(ptr as *mut HeapCellValue)
|
||||||
|
|||||||
@@ -21,9 +21,9 @@ use std::fmt::Debug;
|
|||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
use std::hash::Hash;
|
use std::hash::Hash;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::io::{Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
|
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
use std::io::BufRead;
|
use std::io::BufRead;
|
||||||
|
use std::io::{Cursor, ErrorKind, Read, Seek, SeekFrom, Write};
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::net::{Shutdown, TcpStream};
|
use std::net::{Shutdown, TcpStream};
|
||||||
use std::ops::{Deref, DerefMut};
|
use std::ops::{Deref, DerefMut};
|
||||||
@@ -161,7 +161,7 @@ impl StreamLayout<CharReader<InputFileStream>> {
|
|||||||
// its pending buffer length from position.
|
// its pending buffer length from position.
|
||||||
self.get_mut()
|
self.get_mut()
|
||||||
.file
|
.file
|
||||||
.seek(SeekFrom::Current(0))
|
.stream_position()
|
||||||
.map(|pos| pos - self.stream.rem_buf_len() as u64)
|
.map(|pos| pos - self.stream.rem_buf_len() as u64)
|
||||||
.ok()
|
.ok()
|
||||||
}
|
}
|
||||||
@@ -317,33 +317,31 @@ impl Write for HttpWriteStream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
fn flush(&mut self) -> std::io::Result<()> {
|
fn flush(&mut self) -> std::io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
impl HttpWriteStream {
|
impl HttpWriteStream {
|
||||||
fn drop(&mut self) {
|
fn drop(&mut self) {
|
||||||
let headers = unsafe { mem::ManuallyDrop::take(&mut self.headers) };
|
let headers = unsafe { mem::ManuallyDrop::take(&mut self.headers) };
|
||||||
let buffer = unsafe { mem::ManuallyDrop::take(&mut self.buffer) };
|
let buffer = unsafe { mem::ManuallyDrop::take(&mut self.buffer) };
|
||||||
|
|
||||||
let (ready, response, cvar) = &**self.response;
|
|
||||||
|
|
||||||
let mut ready = ready.lock().unwrap();
|
let (ready, response, cvar) = &**self.response;
|
||||||
{
|
|
||||||
let mut response = response.lock().unwrap();
|
let mut ready = ready.lock().unwrap();
|
||||||
|
{
|
||||||
let mut response_ = warp::http::Response::builder()
|
let mut response = response.lock().unwrap();
|
||||||
.status(self.status_code);
|
|
||||||
*response_.headers_mut().unwrap() = headers;
|
let mut response_ = warp::http::Response::builder().status(self.status_code);
|
||||||
*response = Some(response_.body(warp::hyper::Body::from(buffer)).unwrap());
|
*response_.headers_mut().unwrap() = headers;
|
||||||
}
|
*response = Some(response_.body(warp::hyper::Body::from(buffer)).unwrap());
|
||||||
*ready = true;
|
}
|
||||||
cvar.notify_one();
|
*ready = true;
|
||||||
|
cvar.notify_one();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct StandardOutputStream {}
|
pub struct StandardOutputStream {}
|
||||||
|
|
||||||
@@ -389,7 +387,7 @@ impl StreamOptions {
|
|||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_alias(self) -> Option<Atom> {
|
pub fn get_alias(self) -> Option<Atom> {
|
||||||
if self.has_alias() {
|
if self.has_alias() {
|
||||||
Some(Atom::from((self.alias() as u64) << 3))
|
Some(Atom::from(self.alias() << 3))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
@@ -466,6 +464,7 @@ macro_rules! arena_allocated_impl_for_stream {
|
|||||||
mem::size_of::<StreamLayout<$stream_type>>()
|
mem::size_of::<StreamLayout<$stream_type>>()
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::not_unsafe_ptr_arg_deref)]
|
||||||
#[inline]
|
#[inline]
|
||||||
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
fn copy_to_arena(self, dst: *mut Self) -> Self::PtrToAllocated {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -585,29 +584,17 @@ impl Stream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_stderr(&self) -> bool {
|
pub fn is_stderr(&self) -> bool {
|
||||||
if let Stream::StandardError(_) = self {
|
matches!(self, Stream::StandardError(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_stdout(&self) -> bool {
|
pub fn is_stdout(&self) -> bool {
|
||||||
if let Stream::StandardOutput(_) = self {
|
matches!(self, Stream::StandardOutput(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_stdin(&self) -> bool {
|
pub fn is_stdin(&self) -> bool {
|
||||||
if let Stream::Readline(_) = self {
|
matches!(self, Stream::Readline(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn as_ptr(&self) -> *const ArenaHeader {
|
pub fn as_ptr(&self) -> *const ArenaHeader {
|
||||||
@@ -831,7 +818,7 @@ impl CharRead for Stream {
|
|||||||
impl Read for Stream {
|
impl Read for Stream {
|
||||||
#[inline]
|
#[inline]
|
||||||
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
fn read(&mut self, buf: &mut [u8]) -> std::io::Result<usize> {
|
||||||
let bytes_read = match self {
|
match self {
|
||||||
Stream::InputFile(file) => (*file).read(buf),
|
Stream::InputFile(file) => (*file).read(buf),
|
||||||
Stream::NamedTcp(tcp_stream) => (*tcp_stream).read(buf),
|
Stream::NamedTcp(tcp_stream) => (*tcp_stream).read(buf),
|
||||||
#[cfg(feature = "tls")]
|
#[cfg(feature = "tls")]
|
||||||
@@ -853,9 +840,7 @@ impl Read for Stream {
|
|||||||
ErrorKind::PermissionDenied,
|
ErrorKind::PermissionDenied,
|
||||||
StreamError::ReadFromOutputStream,
|
StreamError::ReadFromOutputStream,
|
||||||
)),
|
)),
|
||||||
};
|
}
|
||||||
|
|
||||||
bytes_read
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -984,18 +969,14 @@ fn cursor_position<T>(
|
|||||||
cursor: &Cursor<T>,
|
cursor: &Cursor<T>,
|
||||||
cursor_len: u64,
|
cursor_len: u64,
|
||||||
) -> AtEndOfStream {
|
) -> AtEndOfStream {
|
||||||
let position = cursor.position();
|
match cursor.position().cmp(&cursor_len) {
|
||||||
|
|
||||||
let at_end_of_stream = match position.cmp(&cursor_len) {
|
|
||||||
Ordering::Equal => AtEndOfStream::At,
|
Ordering::Equal => AtEndOfStream::At,
|
||||||
Ordering::Greater => {
|
Ordering::Greater => {
|
||||||
*past_end_of_stream = true;
|
*past_end_of_stream = true;
|
||||||
AtEndOfStream::Past
|
AtEndOfStream::Past
|
||||||
}
|
}
|
||||||
Ordering::Less => AtEndOfStream::Not,
|
Ordering::Less => AtEndOfStream::Not,
|
||||||
};
|
}
|
||||||
|
|
||||||
at_end_of_stream
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Stream {
|
impl Stream {
|
||||||
@@ -1021,26 +1002,23 @@ impl Stream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn set_position(&mut self, position: u64) {
|
pub(crate) fn set_position(&mut self, position: u64) {
|
||||||
match self {
|
if let Stream::InputFile(stream_layout) = self {
|
||||||
Stream::InputFile(stream_layout) => {
|
let StreamLayout {
|
||||||
let StreamLayout {
|
past_end_of_stream,
|
||||||
past_end_of_stream,
|
stream,
|
||||||
stream,
|
..
|
||||||
..
|
} = &mut **stream_layout;
|
||||||
} = &mut **stream_layout;
|
|
||||||
|
|
||||||
stream
|
stream
|
||||||
.get_mut()
|
.get_mut()
|
||||||
.file
|
.file
|
||||||
.seek(SeekFrom::Start(position))
|
.seek(SeekFrom::Start(position))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
stream.reset_buffer(); // flush the internal buffer.
|
stream.reset_buffer(); // flush the internal buffer.
|
||||||
|
|
||||||
if let Ok(metadata) = stream.get_ref().file.metadata() {
|
if let Ok(metadata) = stream.get_ref().file.metadata() {
|
||||||
*past_end_of_stream = position > metadata.len();
|
*past_end_of_stream = position > metadata.len();
|
||||||
}
|
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1257,15 +1235,15 @@ impl Stream {
|
|||||||
headers: hyper::HeaderMap,
|
headers: hyper::HeaderMap,
|
||||||
arena: &mut Arena,
|
arena: &mut Arena,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Stream::HttpWrite(arena_alloc!(
|
Stream::HttpWrite(arena_alloc!(
|
||||||
StreamLayout::new(CharReader::new(HttpWriteStream {
|
StreamLayout::new(CharReader::new(HttpWriteStream {
|
||||||
response,
|
response,
|
||||||
status_code,
|
status_code,
|
||||||
headers: mem::ManuallyDrop::new(headers),
|
headers: mem::ManuallyDrop::new(headers),
|
||||||
buffer: mem::ManuallyDrop::new(Vec::new()),
|
buffer: mem::ManuallyDrop::new(Vec::new()),
|
||||||
})),
|
})),
|
||||||
arena
|
arena
|
||||||
))
|
))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -1313,8 +1291,8 @@ impl Stream {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
#[cfg(feature = "http")]
|
#[cfg(feature = "http")]
|
||||||
Stream::HttpWrite(ref mut http_stream) => {
|
Stream::HttpWrite(ref mut http_stream) => {
|
||||||
http_stream.inner_mut().drop();
|
http_stream.inner_mut().drop();
|
||||||
unsafe {
|
unsafe {
|
||||||
http_stream.set_tag(ArenaHeaderTag::Dropped);
|
http_stream.set_tag(ArenaHeaderTag::Dropped);
|
||||||
std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _);
|
std::ptr::drop_in_place(&mut http_stream.inner_mut().buffer as *mut _);
|
||||||
@@ -1346,11 +1324,7 @@ impl Stream {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn is_null_stream(&self) -> bool {
|
pub(crate) fn is_null_stream(&self) -> bool {
|
||||||
if let Stream::Null(_) = self {
|
matches!(self, Stream::Null(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -1391,29 +1365,25 @@ impl Stream {
|
|||||||
self.set_lines_read(0);
|
self.set_lines_read(0);
|
||||||
self.set_past_end_of_stream(false);
|
self.set_past_end_of_stream(false);
|
||||||
|
|
||||||
loop {
|
match self {
|
||||||
match self {
|
Stream::Byte(ref mut cursor) => {
|
||||||
Stream::Byte(ref mut cursor) => {
|
cursor.stream.get_mut().0.set_position(0);
|
||||||
cursor.stream.get_mut().0.set_position(0);
|
true
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Stream::InputFile(ref mut file_stream) => {
|
|
||||||
file_stream
|
|
||||||
.stream
|
|
||||||
.get_mut()
|
|
||||||
.file
|
|
||||||
.seek(SeekFrom::Start(0))
|
|
||||||
.unwrap();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
Stream::Readline(ref mut readline_stream) => {
|
|
||||||
readline_stream.reset();
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
_ => {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
Stream::InputFile(ref mut file_stream) => {
|
||||||
|
file_stream
|
||||||
|
.stream
|
||||||
|
.get_mut()
|
||||||
|
.file
|
||||||
|
.seek(SeekFrom::Start(0))
|
||||||
|
.unwrap();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
Stream::Readline(ref mut readline_stream) => {
|
||||||
|
readline_stream.reset();
|
||||||
|
true
|
||||||
|
}
|
||||||
|
_ => false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1484,12 +1454,13 @@ impl MachineState {
|
|||||||
stream.set_past_end_of_stream(true);
|
stream.set_past_end_of_stream(true);
|
||||||
}
|
}
|
||||||
|
|
||||||
Ok(self.fail = stream.past_end_of_stream())
|
self.fail = stream.past_end_of_stream();
|
||||||
|
Ok(())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn to_stream_options(
|
pub(crate) fn get_stream_options(
|
||||||
&mut self,
|
&mut self,
|
||||||
alias: HeapCellValue,
|
alias: HeapCellValue,
|
||||||
eof_action: HeapCellValue,
|
eof_action: HeapCellValue,
|
||||||
@@ -1782,9 +1753,9 @@ impl MachineState {
|
|||||||
caller: Atom,
|
caller: Atom,
|
||||||
arity: usize,
|
arity: usize,
|
||||||
) -> CallResult {
|
) -> CallResult {
|
||||||
let opt_err = if input.is_some() && !stream.is_input_stream() {
|
let opt_err = if input.is_some() && !stream.is_input_stream()
|
||||||
Some(atom!("stream")) // 8.14.2.3 g)
|
|| input.is_none() && !stream.is_output_stream()
|
||||||
} else if input.is_none() && !stream.is_output_stream() {
|
{
|
||||||
Some(atom!("stream")) // 8.14.2.3 g)
|
Some(atom!("stream")) // 8.14.2.3 g)
|
||||||
} else if stream.options().stream_type() != expected_type {
|
} else if stream.options().stream_type() != expected_type {
|
||||||
Some(expected_type.other().as_atom()) // 8.14.2.3 h)
|
Some(expected_type.other().as_atom()) // 8.14.2.3 h)
|
||||||
|
|||||||
File diff suppressed because it is too large
Load Diff
@@ -1,6 +1,6 @@
|
|||||||
use crate::arena::*;
|
use crate::arena::*;
|
||||||
use crate::forms::*;
|
use crate::forms::*;
|
||||||
use crate::heap_iter::{NonListElider, stackful_preorder_iter};
|
use crate::heap_iter::{stackful_preorder_iter, NonListElider};
|
||||||
use crate::machine::machine_state::*;
|
use crate::machine::machine_state::*;
|
||||||
use crate::machine::partial_string::*;
|
use crate::machine::partial_string::*;
|
||||||
use crate::machine::*;
|
use crate::machine::*;
|
||||||
@@ -204,7 +204,7 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
|||||||
|
|
||||||
let mut focus = pstr_iter2.focus;
|
let mut focus = pstr_iter2.focus;
|
||||||
|
|
||||||
'outer: loop {
|
'outer: {
|
||||||
while let Some(c) = chars_iter.peek() {
|
while let Some(c) = chars_iter.peek() {
|
||||||
read_heap_cell!(focus,
|
read_heap_cell!(focus,
|
||||||
(HeapCellValueTag::Lis, l) => {
|
(HeapCellValueTag::Lis, l) => {
|
||||||
@@ -329,8 +329,6 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
|||||||
|
|
||||||
machine_st.pdl.push(focus);
|
machine_st.pdl.push(focus);
|
||||||
machine_st.pdl.push(chars_iter.iter.focus);
|
machine_st.pdl.push(chars_iter.iter.focus);
|
||||||
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
PStrCmpResult::Unordered => {
|
PStrCmpResult::Unordered => {
|
||||||
@@ -609,10 +607,8 @@ pub(crate) trait Unifier: DerefMut<Target = MachineState> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
(HeapCellValueTag::Lis, l1) => {
|
(HeapCellValueTag::Lis, l1) => {
|
||||||
if d2.is_ref() {
|
if d2.is_ref() && tabu_list.contains(&(d1, d2)) {
|
||||||
if tabu_list.contains(&(d1, d2)) {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Self::unify_list(self, l1, d2);
|
Self::unify_list(self, l1, d2);
|
||||||
@@ -720,7 +716,11 @@ fn bind_with_occurs_check<U: Unifier>(unifier: &mut U, r: Ref, value: HeapCellVa
|
|||||||
if !value.is_constant() {
|
if !value.is_constant() {
|
||||||
let machine_st: &mut MachineState = unifier.deref_mut();
|
let machine_st: &mut MachineState = unifier.deref_mut();
|
||||||
|
|
||||||
for cell in stackful_preorder_iter::<NonListElider>(&mut machine_st.heap, &mut machine_st.stack, value) {
|
for cell in stackful_preorder_iter::<NonListElider>(
|
||||||
|
&mut machine_st.heap,
|
||||||
|
&mut machine_st.stack,
|
||||||
|
value,
|
||||||
|
) {
|
||||||
let cell = unmark_cell_bits!(cell);
|
let cell = unmark_cell_bits!(cell);
|
||||||
|
|
||||||
if let Some(inner_r) = cell.as_var() {
|
if let Some(inner_r) = cell.as_var() {
|
||||||
@@ -738,7 +738,7 @@ fn bind_with_occurs_check<U: Unifier>(unifier: &mut U, r: Ref, value: HeapCellVa
|
|||||||
U::bind(unifier, r, value);
|
U::bind(unifier, r, value);
|
||||||
}
|
}
|
||||||
|
|
||||||
return occurs_triggered;
|
occurs_triggered
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Deref, DerefMut)]
|
#[derive(Deref, DerefMut)]
|
||||||
|
|||||||
@@ -247,11 +247,7 @@ impl GenContext {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_last(self) -> bool {
|
pub fn is_last(self) -> bool {
|
||||||
if let GenContext::Last(_) = self {
|
matches!(self, GenContext::Last(_))
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -303,24 +299,16 @@ impl OpDesc {
|
|||||||
// name and fixity -> operator type and precedence.
|
// name and fixity -> operator type and precedence.
|
||||||
pub type OpDir = IndexMap<(Atom, Fixity), OpDesc, FxBuildHasher>;
|
pub type OpDir = IndexMap<(Atom, Fixity), OpDesc, FxBuildHasher>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Default, Clone, Copy)]
|
||||||
pub struct MachineFlags {
|
pub struct MachineFlags {
|
||||||
pub double_quotes: DoubleQuotes,
|
pub double_quotes: DoubleQuotes,
|
||||||
pub unknown: Unknown,
|
pub unknown: Unknown,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for MachineFlags {
|
#[derive(Debug, Default, Clone, Copy, PartialEq)]
|
||||||
fn default() -> Self {
|
|
||||||
MachineFlags {
|
|
||||||
double_quotes: DoubleQuotes::default(),
|
|
||||||
unknown: Unknown::default(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy, PartialEq)]
|
|
||||||
pub enum DoubleQuotes {
|
pub enum DoubleQuotes {
|
||||||
Atom,
|
Atom,
|
||||||
|
#[default]
|
||||||
Chars,
|
Chars,
|
||||||
Codes,
|
Codes,
|
||||||
}
|
}
|
||||||
@@ -339,12 +327,6 @@ impl DoubleQuotes {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Default for DoubleQuotes {
|
|
||||||
fn default() -> Self {
|
|
||||||
DoubleQuotes::Chars
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub enum Unknown {
|
pub enum Unknown {
|
||||||
Error,
|
Error,
|
||||||
@@ -505,7 +487,7 @@ impl<'a, 'b> CompositeOpDir<'a, 'b> {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn get(&self, name: Atom, fixity: Fixity) -> Option<OpDesc> {
|
pub(crate) fn get(&self, name: Atom, fixity: Fixity) -> Option<OpDesc> {
|
||||||
let entry = if let Some(ref primary_op_dir) = &self.primary_op_dir {
|
let entry = if let Some(primary_op_dir) = &self.primary_op_dir {
|
||||||
primary_op_dir.get(&(name, fixity))
|
primary_op_dir.get(&(name, fixity))
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
@@ -567,7 +549,7 @@ impl Fixnum {
|
|||||||
const UPPER_BOUND: i64 = (1 << 55) - 1;
|
const UPPER_BOUND: i64 = (1 << 55) - 1;
|
||||||
const LOWER_BOUND: i64 = -(1 << 55);
|
const LOWER_BOUND: i64 = -(1 << 55);
|
||||||
|
|
||||||
if LOWER_BOUND <= num && num <= UPPER_BOUND {
|
if (LOWER_BOUND..=UPPER_BOUND).contains(&num) {
|
||||||
Ok(Fixnum::new()
|
Ok(Fixnum::new()
|
||||||
.with_m(false)
|
.with_m(false)
|
||||||
.with_f(false)
|
.with_f(false)
|
||||||
@@ -582,7 +564,7 @@ impl Fixnum {
|
|||||||
pub fn get_num(self) -> i64 {
|
pub fn get_num(self) -> i64 {
|
||||||
let n = self.num() as i64;
|
let n = self.num() as i64;
|
||||||
let (n, overflowed) = (n << 8).overflowing_shr(8);
|
let (n, overflowed) = (n << 8).overflowing_shr(8);
|
||||||
debug_assert_eq!(overflowed, false);
|
debug_assert!(!overflowed);
|
||||||
n
|
n
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -730,11 +712,12 @@ impl Var {
|
|||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn as_str(&self) -> Option<&str> {
|
pub fn as_str(&self) -> Option<&str> {
|
||||||
match self {
|
match self {
|
||||||
Var::Named(value) => Some(&value),
|
Var::Named(value) => Some(value),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::inherent_to_string)]
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
pub fn to_string(&self) -> String {
|
pub fn to_string(&self) -> String {
|
||||||
match self {
|
match self {
|
||||||
@@ -800,10 +783,8 @@ impl Term {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn source_arity(terms: &[Term]) -> usize {
|
pub fn source_arity(terms: &[Term]) -> usize {
|
||||||
if let Some(last_arg) = terms.last() {
|
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = terms.last() {
|
||||||
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
return terms.len() - 1;
|
||||||
return terms.len() - 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
terms.len()
|
terms.len()
|
||||||
@@ -811,10 +792,8 @@ pub fn source_arity(terms: &[Term]) -> usize {
|
|||||||
|
|
||||||
pub(crate) fn unfold_by_str_once(term: &mut Term, s: Atom) -> Option<(Term, Term)> {
|
pub(crate) fn unfold_by_str_once(term: &mut Term, s: Atom) -> Option<(Term, Term)> {
|
||||||
if let Term::Clause(_, ref name, ref mut subterms) = term {
|
if let Term::Clause(_, ref name, ref mut subterms) = term {
|
||||||
if let Some(last_arg) = subterms.last() {
|
if let Some(Term::Literal(_, Literal::CodeIndex(_))) = subterms.last() {
|
||||||
if let Term::Literal(_, Literal::CodeIndex(_)) = last_arg {
|
subterms.pop();
|
||||||
subterms.pop();
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if name == &s && subterms.len() == 2 {
|
if name == &s && subterms.len() == 2 {
|
||||||
|
|||||||
@@ -131,15 +131,9 @@ impl<R: Read> CharReader<R> {
|
|||||||
|
|
||||||
pub fn peek_byte(&mut self) -> Option<io::Result<u8>> {
|
pub fn peek_byte(&mut self) -> Option<io::Result<u8>> {
|
||||||
match self.refresh_buffer() {
|
match self.refresh_buffer() {
|
||||||
Ok(_buf) => {}
|
Ok(_buf) => _buf.first().cloned().map(Ok),
|
||||||
Err(e) => return Some(Err(e)),
|
Err(e) => Some(Err(e)),
|
||||||
}
|
}
|
||||||
|
|
||||||
return if let Some(b) = self.buf.get(0).cloned() {
|
|
||||||
Some(Ok(b))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -194,49 +188,47 @@ impl<R: Read> CharRead for CharReader<R> {
|
|||||||
io::ErrorKind::InvalidData,
|
io::ErrorKind::InvalidData,
|
||||||
BadUtf8Error { bytes: badbytes },
|
BadUtf8Error { bytes: badbytes },
|
||||||
)));
|
)));
|
||||||
|
} else if self.pos >= self.buf.len() {
|
||||||
|
return None;
|
||||||
|
} else if self.buf.len() - self.pos >= 4 {
|
||||||
|
return match str::from_utf8(&self.buf[self.pos..e.valid_up_to()]) {
|
||||||
|
Ok(s) => {
|
||||||
|
let mut chars = s.chars();
|
||||||
|
let c = chars.next().unwrap();
|
||||||
|
|
||||||
|
Some(Ok(c))
|
||||||
|
}
|
||||||
|
Err(e) => {
|
||||||
|
let badbytes = self.buf[self.pos..e.valid_up_to()].to_vec();
|
||||||
|
|
||||||
|
Some(Err(io::Error::new(
|
||||||
|
io::ErrorKind::InvalidData,
|
||||||
|
BadUtf8Error { bytes: badbytes },
|
||||||
|
)))
|
||||||
|
}
|
||||||
|
};
|
||||||
} else {
|
} else {
|
||||||
if self.pos >= self.buf.len() {
|
let buf_len = self.buf.len();
|
||||||
return None;
|
|
||||||
} else if self.buf.len() - self.pos >= 4 {
|
|
||||||
return match str::from_utf8(&self.buf[self.pos..e.valid_up_to()]) {
|
|
||||||
Ok(s) => {
|
|
||||||
let mut chars = s.chars();
|
|
||||||
let c = chars.next().unwrap();
|
|
||||||
|
|
||||||
Some(Ok(c))
|
for (c, idx) in (self.pos..buf_len).enumerate() {
|
||||||
}
|
self.buf[c] = self.buf[idx];
|
||||||
Err(e) => {
|
|
||||||
let badbytes = self.buf[self.pos..e.valid_up_to()].to_vec();
|
|
||||||
|
|
||||||
Some(Err(io::Error::new(
|
|
||||||
io::ErrorKind::InvalidData,
|
|
||||||
BadUtf8Error { bytes: badbytes },
|
|
||||||
)))
|
|
||||||
}
|
|
||||||
};
|
|
||||||
} else {
|
|
||||||
let buf_len = self.buf.len();
|
|
||||||
|
|
||||||
for (c, idx) in (self.pos..buf_len).enumerate() {
|
|
||||||
self.buf[c] = self.buf[idx];
|
|
||||||
}
|
|
||||||
|
|
||||||
self.buf.truncate(buf_len - self.pos);
|
|
||||||
|
|
||||||
let buf_len = self.buf.len();
|
|
||||||
|
|
||||||
let mut word = [0u8; 4];
|
|
||||||
let word_slice = &mut word[buf_len..4];
|
|
||||||
|
|
||||||
match self.inner.read(word_slice) {
|
|
||||||
Err(e) => return Some(Err(e)),
|
|
||||||
Ok(nread) => {
|
|
||||||
self.buf.extend_from_slice(&word_slice[0..nread]);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.pos = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
self.buf.truncate(buf_len - self.pos);
|
||||||
|
|
||||||
|
let buf_len = self.buf.len();
|
||||||
|
|
||||||
|
let mut word = [0u8; 4];
|
||||||
|
let word_slice = &mut word[buf_len..4];
|
||||||
|
|
||||||
|
match self.inner.read(word_slice) {
|
||||||
|
Err(e) => return Some(Err(e)),
|
||||||
|
Ok(nread) => {
|
||||||
|
self.buf.extend_from_slice(&word_slice[0..nread]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.pos = 0;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
|
|||||||
@@ -48,11 +48,7 @@ pub enum Token {
|
|||||||
impl Token {
|
impl Token {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(super) fn is_end(&self) -> bool {
|
pub(super) fn is_end(&self) -> bool {
|
||||||
if let Token::End = self {
|
matches!(self, Token::End)
|
||||||
true
|
|
||||||
} else {
|
|
||||||
false
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -604,10 +600,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else if cut_char!(c) {
|
} else if cut_char!(c) || semicolon_char!(c) {
|
||||||
self.skip_char(c);
|
|
||||||
token.push(c);
|
|
||||||
} else if semicolon_char!(c) {
|
|
||||||
self.skip_char(c);
|
self.skip_char(c);
|
||||||
token.push(c);
|
token.push(c);
|
||||||
} else if single_quote_char!(c) {
|
} else if single_quote_char!(c) {
|
||||||
@@ -690,7 +683,8 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
if self.reader.peek_char().is_none() {
|
if self.reader.peek_char().is_none() {
|
||||||
self.return_char('.');
|
self.return_char('.');
|
||||||
|
|
||||||
i64::from_str_radix(&token, 10)
|
token
|
||||||
|
.parse::<i64>()
|
||||||
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token
|
token
|
||||||
@@ -720,12 +714,12 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
token.push(c);
|
token.push(c);
|
||||||
|
|
||||||
let c = match self.lookahead_char() {
|
let c = match self.lookahead_char() {
|
||||||
Err(_) => return Ok(self.vacate_with_float(token)?),
|
Err(_) => return self.vacate_with_float(token),
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !sign_char!(c) && !decimal_digit_char!(c) {
|
if !sign_char!(c) && !decimal_digit_char!(c) {
|
||||||
return Ok(self.vacate_with_float(token)?);
|
return self.vacate_with_float(token);
|
||||||
}
|
}
|
||||||
|
|
||||||
if sign_char!(c) {
|
if sign_char!(c) {
|
||||||
@@ -735,14 +729,14 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
let c = match self.lookahead_char() {
|
let c = match self.lookahead_char() {
|
||||||
Err(_) => {
|
Err(_) => {
|
||||||
self.return_char(token.pop().unwrap());
|
self.return_char(token.pop().unwrap());
|
||||||
return Ok(self.vacate_with_float(token)?);
|
return self.vacate_with_float(token);
|
||||||
}
|
}
|
||||||
Ok(c) => c,
|
Ok(c) => c,
|
||||||
};
|
};
|
||||||
|
|
||||||
if !decimal_digit_char!(c) {
|
if !decimal_digit_char!(c) {
|
||||||
self.return_char(token.pop().unwrap());
|
self.return_char(token.pop().unwrap());
|
||||||
return Ok(self.vacate_with_float(token)?);
|
return self.vacate_with_float(token);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -769,7 +763,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
self.machine_st.arena
|
self.machine_st.arena
|
||||||
))))
|
))))
|
||||||
} else {
|
} else {
|
||||||
return Ok(self.vacate_with_float(token)?);
|
return self.vacate_with_float(token);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let n = parse_lossy::<f64, _>(token.as_bytes())?;
|
let n = parse_lossy::<f64, _>(token.as_bytes())?;
|
||||||
@@ -781,7 +775,147 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
} else {
|
} else {
|
||||||
self.return_char('.');
|
self.return_char('.');
|
||||||
|
|
||||||
i64::from_str_radix(&token, 10)
|
token
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
||||||
|
.or_else(|_| {
|
||||||
|
token
|
||||||
|
.parse::<Integer>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
|
n,
|
||||||
|
&mut self.machine_st.arena
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
|
})
|
||||||
|
}
|
||||||
|
} else if token.starts_with('0') && token.len() == 1 {
|
||||||
|
if c == 'x' {
|
||||||
|
self.hexadecimal_constant(c).or_else(|e| {
|
||||||
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
|
token
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
||||||
|
})
|
||||||
|
.or_else(|_| {
|
||||||
|
token
|
||||||
|
.parse::<Integer>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
|
n,
|
||||||
|
&mut self.machine_st.arena
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.map_err(|_| {
|
||||||
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if c == 'o' {
|
||||||
|
self.octal_constant(c).or_else(|e| {
|
||||||
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
|
token
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
||||||
|
})
|
||||||
|
.or_else(|_| {
|
||||||
|
token
|
||||||
|
.parse::<Integer>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
|
n,
|
||||||
|
&mut self.machine_st.arena
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.map_err(|_| {
|
||||||
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if c == 'b' {
|
||||||
|
self.binary_constant(c).or_else(|e| {
|
||||||
|
if let ParserError::ParseBigInt(..) = e {
|
||||||
|
token
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
||||||
|
})
|
||||||
|
.or_else(|_| {
|
||||||
|
token
|
||||||
|
.parse::<Integer>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
|
n,
|
||||||
|
&mut self.machine_st.arena
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.map_err(|_| {
|
||||||
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
Err(e)
|
||||||
|
}
|
||||||
|
})
|
||||||
|
} else if single_quote_char!(c) {
|
||||||
|
self.skip_char(c);
|
||||||
|
let c = self.lookahead_char()?;
|
||||||
|
|
||||||
|
if backslash_char!(c) {
|
||||||
|
self.skip_char(c);
|
||||||
|
let c = self.lookahead_char()?;
|
||||||
|
|
||||||
|
if new_line_char!(c) {
|
||||||
|
self.skip_char(c);
|
||||||
|
self.return_char('\'');
|
||||||
|
|
||||||
|
return Ok(Token::Literal(Literal::Fixnum(Fixnum::build_with(0))));
|
||||||
|
} else {
|
||||||
|
self.return_char('\\');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
self.get_single_quoted_char()
|
||||||
|
.map(|c| Token::Literal(Literal::Fixnum(Fixnum::build_with(c as i64))))
|
||||||
|
.or_else(|err| {
|
||||||
|
match err {
|
||||||
|
ParserError::UnexpectedChar('\'', ..) => {}
|
||||||
|
err => return Err(err),
|
||||||
|
}
|
||||||
|
|
||||||
|
self.return_char(c);
|
||||||
|
|
||||||
|
token
|
||||||
|
.parse::<i64>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
||||||
|
})
|
||||||
|
.or_else(|_| {
|
||||||
|
token
|
||||||
|
.parse::<Integer>()
|
||||||
|
.map(|n| {
|
||||||
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
|
n,
|
||||||
|
&mut self.machine_st.arena
|
||||||
|
)))
|
||||||
|
})
|
||||||
|
.map_err(|_| {
|
||||||
|
ParserError::ParseBigInt(self.line_num, self.col_num)
|
||||||
|
})
|
||||||
|
})
|
||||||
|
})
|
||||||
|
} else {
|
||||||
|
token
|
||||||
|
.parse::<i64>()
|
||||||
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
||||||
.or_else(|_| {
|
.or_else(|_| {
|
||||||
token
|
token
|
||||||
@@ -796,155 +930,20 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
if token.starts_with('0') && token.len() == 1 {
|
token
|
||||||
if c == 'x' {
|
.parse::<i64>()
|
||||||
self.hexadecimal_constant(c).or_else(|e| {
|
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
.or_else(|_| {
|
||||||
i64::from_str_radix(&token, 10)
|
token
|
||||||
.map(|n| {
|
.parse::<Integer>()
|
||||||
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
.map(|n| {
|
||||||
})
|
Token::Literal(Literal::Integer(arena_alloc!(
|
||||||
.or_else(|_| {
|
n,
|
||||||
token
|
&mut self.machine_st.arena
|
||||||
.parse::<Integer>()
|
)))
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| {
|
|
||||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if c == 'o' {
|
|
||||||
self.octal_constant(c).or_else(|e| {
|
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
|
||||||
i64::from_str_radix(&token, 10)
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
|
||||||
})
|
|
||||||
.or_else(|_| {
|
|
||||||
token
|
|
||||||
.parse::<Integer>()
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| {
|
|
||||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if c == 'b' {
|
|
||||||
self.binary_constant(c).or_else(|e| {
|
|
||||||
if let ParserError::ParseBigInt(..) = e {
|
|
||||||
i64::from_str_radix(&token, 10)
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
|
||||||
})
|
|
||||||
.or_else(|_| {
|
|
||||||
token
|
|
||||||
.parse::<Integer>()
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| {
|
|
||||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
} else {
|
|
||||||
Err(e)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
} else if single_quote_char!(c) {
|
|
||||||
self.skip_char(c);
|
|
||||||
let c = self.lookahead_char()?;
|
|
||||||
|
|
||||||
if backslash_char!(c) {
|
|
||||||
self.skip_char(c);
|
|
||||||
let c = self.lookahead_char()?;
|
|
||||||
|
|
||||||
if new_line_char!(c) {
|
|
||||||
self.skip_char(c);
|
|
||||||
self.return_char('\'');
|
|
||||||
|
|
||||||
return Ok(Token::Literal(Literal::Fixnum(Fixnum::build_with(0))));
|
|
||||||
} else {
|
|
||||||
self.return_char('\\');
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
self.get_single_quoted_char()
|
|
||||||
.map(|c| Token::Literal(Literal::Fixnum(Fixnum::build_with(c as i64))))
|
|
||||||
.or_else(|err| {
|
|
||||||
match err {
|
|
||||||
ParserError::UnexpectedChar('\'', ..) => {}
|
|
||||||
err => return Err(err),
|
|
||||||
}
|
|
||||||
|
|
||||||
self.return_char(c);
|
|
||||||
|
|
||||||
i64::from_str_radix(&token, 10)
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena))
|
|
||||||
})
|
|
||||||
.or_else(|_| {
|
|
||||||
token
|
|
||||||
.parse::<Integer>()
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| {
|
|
||||||
ParserError::ParseBigInt(self.line_num, self.col_num)
|
|
||||||
})
|
|
||||||
})
|
|
||||||
})
|
})
|
||||||
} else {
|
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
||||||
i64::from_str_radix(&token, 10)
|
})
|
||||||
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
|
||||||
.or_else(|_| {
|
|
||||||
token
|
|
||||||
.parse::<Integer>()
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
i64::from_str_radix(&token, 10)
|
|
||||||
.map(|n| Token::Literal(fixnum!(Literal, n, &mut self.machine_st.arena)))
|
|
||||||
.or_else(|_| {
|
|
||||||
token
|
|
||||||
.parse::<Integer>()
|
|
||||||
.map(|n| {
|
|
||||||
Token::Literal(Literal::Integer(arena_alloc!(
|
|
||||||
n,
|
|
||||||
&mut self.machine_st.arena
|
|
||||||
)))
|
|
||||||
})
|
|
||||||
.map_err(|_| ParserError::ParseBigInt(self.line_num, self.col_num))
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -953,6 +952,7 @@ impl<'a, R: CharRead> Lexer<'a, R> {
|
|||||||
c: Option<char>,
|
c: Option<char>,
|
||||||
layout_info: &mut LayoutInfo,
|
layout_info: &mut LayoutInfo,
|
||||||
) -> Result<(), ParserError> {
|
) -> Result<(), ParserError> {
|
||||||
|
#[allow(clippy::redundant_guards)]
|
||||||
match c {
|
match c {
|
||||||
Some(c) if layout_char!(c) => {
|
Some(c) if layout_char!(c) => {
|
||||||
self.skip_char(c);
|
self.skip_char(c);
|
||||||
|
|||||||
@@ -77,7 +77,7 @@ macro_rules! cut_char {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! decimal_digit_char {
|
macro_rules! decimal_digit_char {
|
||||||
($c: expr) => {
|
($c: expr) => {
|
||||||
('0'..='9').contains(&$c)
|
$c.is_ascii_digit()
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -125,7 +125,7 @@ macro_rules! graphic_token_char {
|
|||||||
#[macro_export]
|
#[macro_export]
|
||||||
macro_rules! hexadecimal_digit_char {
|
macro_rules! hexadecimal_digit_char {
|
||||||
($c: expr) => {
|
($c: expr) => {
|
||||||
('0'..='9').contains(&$c) || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c)
|
$c.is_ascii_digit() || ('A'..='F').contains(&$c) || ('a'..='f').contains(&$c)
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,4 +11,5 @@ pub mod ast;
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
pub mod macros;
|
pub mod macros;
|
||||||
pub mod lexer;
|
pub mod lexer;
|
||||||
|
#[allow(clippy::module_inception)]
|
||||||
pub mod parser;
|
pub mod parser;
|
||||||
|
|||||||
@@ -464,7 +464,12 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
Token::End => TokenType::End,
|
Token::End => TokenType::End,
|
||||||
};
|
};
|
||||||
|
|
||||||
self.stack.push(TokenDesc { tt, priority, spec, unfold_bounds: 0, });
|
self.stack.push(TokenDesc {
|
||||||
|
tt,
|
||||||
|
priority,
|
||||||
|
spec,
|
||||||
|
unfold_bounds: 0,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reduce_op(&mut self, priority: usize) {
|
fn reduce_op(&mut self, priority: usize) {
|
||||||
@@ -472,10 +477,9 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
if let Some(desc1) = self.stack.pop() {
|
if let Some(desc1) = self.stack.pop() {
|
||||||
if let Some(desc2) = self.stack.pop() {
|
if let Some(desc2) = self.stack.pop() {
|
||||||
if let Some(desc3) = self.stack.pop() {
|
if let Some(desc3) = self.stack.pop() {
|
||||||
if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1) {
|
if is_xfx!(desc2.spec) && affirm_xfx(priority, desc2, desc3, desc1)
|
||||||
self.push_binary_op(desc2, LTERM);
|
|| is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1)
|
||||||
continue;
|
{
|
||||||
} else if is_yfx!(desc2.spec) && affirm_yfx(priority, desc2, desc3, desc1) {
|
|
||||||
self.push_binary_op(desc2, LTERM);
|
self.push_binary_op(desc2, LTERM);
|
||||||
continue;
|
continue;
|
||||||
} else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) {
|
} else if is_xfy!(desc2.spec) && affirm_xfy(priority, desc2, desc3, desc1) {
|
||||||
@@ -555,10 +559,12 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
if self.stack.len() > 2 * arity {
|
if self.stack.len() > 2 * arity {
|
||||||
let idx = self.stack.len() - 2 * arity - 1;
|
let idx = self.stack.len() - 2 * arity - 1;
|
||||||
|
|
||||||
if is_infix!(self.stack[idx].spec) && idx > 0 {
|
if is_infix!(self.stack[idx].spec)
|
||||||
if !is_op!(self.stack[idx - 1].spec) && !self.stack[idx - 1].tt.is_sep() {
|
&& idx > 0
|
||||||
return false;
|
&& !is_op!(self.stack[idx - 1].spec)
|
||||||
}
|
&& !self.stack[idx - 1].tt.is_sep()
|
||||||
|
{
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
return false;
|
return false;
|
||||||
@@ -571,59 +577,57 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
let stack_len = self.stack.len() - 2 * arity - 1;
|
let stack_len = self.stack.len() - 2 * arity - 1;
|
||||||
let idx = self.terms.len() - arity;
|
let idx = self.terms.len() - arity;
|
||||||
|
|
||||||
if TokenType::Term == self.stack[stack_len].tt {
|
if TokenType::Term == self.stack[stack_len].tt
|
||||||
if atomize_term(&self.lexer.machine_st.atom_tbl, &self.terms[idx - 1]).is_some() {
|
&& atomize_term(&self.lexer.machine_st.atom_tbl, &self.terms[idx - 1]).is_some()
|
||||||
self.stack.truncate(stack_len + 1);
|
{
|
||||||
|
self.stack.truncate(stack_len + 1);
|
||||||
|
|
||||||
let mut subterms: Vec<_> = self.terms.drain(idx..).collect();
|
let mut subterms: Vec<_> = self.terms.drain(idx..).collect();
|
||||||
|
|
||||||
if let Some(name) = self
|
if let Some(name) = self
|
||||||
.terms
|
.terms
|
||||||
.pop()
|
.pop()
|
||||||
.and_then(|t| atomize_term(&self.lexer.machine_st.atom_tbl, &t))
|
.and_then(|t| atomize_term(&self.lexer.machine_st.atom_tbl, &t))
|
||||||
{
|
{
|
||||||
// reduce the '.' functor to a cons cell if it applies.
|
// reduce the '.' functor to a cons cell if it applies.
|
||||||
if name == atom!(".") && subterms.len() == 2 {
|
if name == atom!(".") && subterms.len() == 2 {
|
||||||
let tail = subterms.pop().unwrap();
|
let tail = subterms.pop().unwrap();
|
||||||
let head = subterms.pop().unwrap();
|
let head = subterms.pop().unwrap();
|
||||||
|
|
||||||
self.terms.push(match as_partial_string(head, tail) {
|
self.terms.push(match as_partial_string(head, tail) {
|
||||||
Ok((string_buf, Some(tail))) => {
|
Ok((string_buf, Some(tail))) => {
|
||||||
Term::PartialString(Cell::default(), string_buf, tail)
|
Term::PartialString(Cell::default(), string_buf, tail)
|
||||||
}
|
|
||||||
Ok((string_buf, None)) => {
|
|
||||||
let atom = AtomTable::build_with(
|
|
||||||
&self.lexer.machine_st.atom_tbl,
|
|
||||||
&string_buf,
|
|
||||||
);
|
|
||||||
Term::CompleteString(Cell::default(), atom)
|
|
||||||
}
|
|
||||||
Err(term) => term,
|
|
||||||
});
|
|
||||||
} else {
|
|
||||||
self.terms
|
|
||||||
.push(Term::Clause(Cell::default(), name, subterms));
|
|
||||||
}
|
|
||||||
|
|
||||||
if let Some(&mut TokenDesc {
|
|
||||||
ref mut tt,
|
|
||||||
ref mut priority,
|
|
||||||
ref mut spec,
|
|
||||||
ref mut unfold_bounds,
|
|
||||||
}) = self.stack.last_mut()
|
|
||||||
{
|
|
||||||
if *spec == BTERM {
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
Ok((string_buf, None)) => {
|
||||||
|
let atom =
|
||||||
|
AtomTable::build_with(&self.lexer.machine_st.atom_tbl, &string_buf);
|
||||||
|
Term::CompleteString(Cell::default(), atom)
|
||||||
|
}
|
||||||
|
Err(term) => term,
|
||||||
|
});
|
||||||
|
} else {
|
||||||
|
self.terms
|
||||||
|
.push(Term::Clause(Cell::default(), name, subterms));
|
||||||
|
}
|
||||||
|
|
||||||
*tt = TokenType::Term;
|
if let Some(&mut TokenDesc {
|
||||||
*priority = 0;
|
ref mut tt,
|
||||||
*spec = TERM;
|
ref mut priority,
|
||||||
*unfold_bounds = 0;
|
ref mut spec,
|
||||||
|
ref mut unfold_bounds,
|
||||||
|
}) = self.stack.last_mut()
|
||||||
|
{
|
||||||
|
if *spec == BTERM {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
*tt = TokenType::Term;
|
||||||
|
*priority = 0;
|
||||||
|
*spec = TERM;
|
||||||
|
*unfold_bounds = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -642,34 +646,31 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
/* '|' is a head-tail separator here, not
|
/* '|' is a head-tail separator here, not
|
||||||
* an operator, so expand the
|
* an operator, so expand the
|
||||||
* terms it compacted out again. */
|
* terms it compacted out again. */
|
||||||
match (term.name(), term.arity()) {
|
if let (Some(atom!(",")), 2) = (term.name(), term.arity()) {
|
||||||
(Some(name), 2) if name == atom!(",") => {
|
let terms = if op_desc.unfold_bounds == 0 {
|
||||||
let terms = if op_desc.unfold_bounds == 0 {
|
unfold_by_str(term, atom!(","))
|
||||||
unfold_by_str(term, atom!(","))
|
} else {
|
||||||
} else {
|
let mut terms = vec![];
|
||||||
let mut terms = vec![];
|
|
||||||
|
|
||||||
while let Some((fst, snd)) = unfold_by_str_once(&mut term, atom!(",")) {
|
while let Some((fst, snd)) = unfold_by_str_once(&mut term, atom!(",")) {
|
||||||
terms.push(fst);
|
terms.push(fst);
|
||||||
term = snd;
|
term = snd;
|
||||||
|
|
||||||
op_desc.unfold_bounds -= 2;
|
op_desc.unfold_bounds -= 2;
|
||||||
|
|
||||||
if op_desc.unfold_bounds == 0 {
|
if op_desc.unfold_bounds == 0 {
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
terms.push(term);
|
terms.push(term);
|
||||||
terms
|
terms
|
||||||
};
|
};
|
||||||
|
|
||||||
let arity = terms.len() - 1;
|
let arity = terms.len() - 1;
|
||||||
|
|
||||||
self.terms.extend(terms.into_iter());
|
self.terms.extend(terms);
|
||||||
return arity;
|
return arity;
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -692,18 +693,15 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
} else {
|
} else {
|
||||||
return None;
|
return None;
|
||||||
}
|
}
|
||||||
} else {
|
} else if desc.tt == TokenType::HeadTailSeparator {
|
||||||
if desc.tt == TokenType::HeadTailSeparator {
|
if arity == 1 {
|
||||||
if arity == 1 {
|
continue;
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
return None;
|
|
||||||
} else if desc.tt == TokenType::OpenList {
|
|
||||||
return Some(arity);
|
|
||||||
} else if desc.tt != TokenType::Comma {
|
|
||||||
return None;
|
|
||||||
}
|
}
|
||||||
|
return None;
|
||||||
|
} else if desc.tt == TokenType::OpenList {
|
||||||
|
return Some(arity);
|
||||||
|
} else if desc.tt != TokenType::Comma {
|
||||||
|
return None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -882,7 +880,11 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
.push(Term::Literal(Cell::default(), Literal::Atom(atom)));
|
.push(Term::Literal(Cell::default(), Literal::Atom(atom)));
|
||||||
}
|
}
|
||||||
|
|
||||||
self.stack[idx].spec = if self.stack[idx].priority > 0 { TERM } else { BTERM };
|
self.stack[idx].spec = if self.stack[idx].priority > 0 {
|
||||||
|
TERM
|
||||||
|
} else {
|
||||||
|
BTERM
|
||||||
|
};
|
||||||
self.stack[idx].tt = TokenType::Term;
|
self.stack[idx].tt = TokenType::Term;
|
||||||
self.stack[idx].priority = 0;
|
self.stack[idx].priority = 0;
|
||||||
|
|
||||||
@@ -1018,13 +1020,11 @@ impl<'a, R: CharRead> Parser<'a, R> {
|
|||||||
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
Token::Open => self.shift(Token::Open, 1300, DELIMITER),
|
||||||
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
Token::OpenCT => self.shift(Token::OpenCT, 1300, DELIMITER),
|
||||||
Token::Close => {
|
Token::Close => {
|
||||||
if !self.reduce_term() {
|
if !self.reduce_term() && !self.reduce_brackets() {
|
||||||
if !self.reduce_brackets() {
|
return Err(ParserError::IncompleteReduction(
|
||||||
return Err(ParserError::IncompleteReduction(
|
self.lexer.line_num,
|
||||||
self.lexer.line_num,
|
self.lexer.col_num,
|
||||||
self.lexer.col_num,
|
));
|
||||||
));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
Token::OpenList => self.shift(Token::OpenList, 1300, DELIMITER),
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::new_without_default)]
|
||||||
pub fn new() -> Self {
|
pub fn new() -> Self {
|
||||||
let mut block = Self::empty_block();
|
let mut block = Self::empty_block();
|
||||||
|
|
||||||
@@ -71,7 +72,7 @@ impl<T: RawBlockTraits> RawBlock<T> {
|
|||||||
} else {
|
} else {
|
||||||
let allocated = (*self.ptr.get()) as usize - self.base as usize;
|
let allocated = (*self.ptr.get()) as usize - self.base as usize;
|
||||||
self.base.copy_to(new_block.base.cast_mut(), allocated);
|
self.base.copy_to(new_block.base.cast_mut(), allocated);
|
||||||
*new_block.ptr.get_mut() = new_block.base.offset(allocated as isize).cast_mut();
|
*new_block.ptr.get_mut() = new_block.base.add(allocated).cast_mut();
|
||||||
Some(new_block)
|
Some(new_block)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,7 +6,7 @@ use std::{
|
|||||||
ptr::NonNull,
|
ptr::NonNull,
|
||||||
sync::{
|
sync::{
|
||||||
atomic::{AtomicPtr, AtomicU8},
|
atomic::{AtomicPtr, AtomicU8},
|
||||||
Arc, Weak, RwLock
|
Arc, RwLock, Weak,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -52,7 +52,7 @@ impl<T> Rcu<T> {
|
|||||||
// register the current threads epoch counter on init
|
// register the current threads epoch counter on init
|
||||||
EPOCH_COUNTERS
|
EPOCH_COUNTERS
|
||||||
.write()
|
.write()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
.push(Arc::downgrade(&epoch_counter));
|
.push(Arc::downgrade(&epoch_counter));
|
||||||
epoch_counter
|
epoch_counter
|
||||||
});
|
});
|
||||||
|
|||||||
30
src/read.rs
30
src/read.rs
@@ -31,8 +31,8 @@ use std::sync::Arc;
|
|||||||
|
|
||||||
type SubtermDeque = VecDeque<(usize, usize)>;
|
type SubtermDeque = VecDeque<(usize, usize)>;
|
||||||
|
|
||||||
pub(crate) fn devour_whitespace<'a, R: CharRead>(
|
pub(crate) fn devour_whitespace<R: CharRead>(
|
||||||
parser: &mut Parser<'a, R>,
|
parser: &mut Parser<'_, R>,
|
||||||
) -> Result<bool, ParserError> {
|
) -> Result<bool, ParserError> {
|
||||||
match parser.lexer.scan_for_layout() {
|
match parser.lexer.scan_for_layout() {
|
||||||
Err(e) if e.is_unexpected_eof() => Ok(true),
|
Err(e) if e.is_unexpected_eof() => Ok(true),
|
||||||
@@ -86,7 +86,7 @@ impl MachineState {
|
|||||||
|
|
||||||
static mut PROMPT: bool = false;
|
static mut PROMPT: bool = false;
|
||||||
#[cfg(feature = "repl")]
|
#[cfg(feature = "repl")]
|
||||||
const HISTORY_FILE: &'static str = ".scryer_history";
|
const HISTORY_FILE: &str = ".scryer_history";
|
||||||
|
|
||||||
pub(crate) fn set_prompt(value: bool) {
|
pub(crate) fn set_prompt(value: bool) {
|
||||||
unsafe {
|
unsafe {
|
||||||
@@ -137,7 +137,7 @@ impl ReadlineStream {
|
|||||||
ReadlineStream {
|
ReadlineStream {
|
||||||
rl,
|
rl,
|
||||||
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
||||||
add_history: add_history,
|
add_history,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +145,7 @@ impl ReadlineStream {
|
|||||||
{
|
{
|
||||||
ReadlineStream {
|
ReadlineStream {
|
||||||
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
pending_input: CharReader::new(Cursor::new(pending_input.to_owned())),
|
||||||
add_history: add_history,
|
add_history,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -187,7 +187,7 @@ impl ReadlineStream {
|
|||||||
PROMPT = false;
|
PROMPT = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.pending_input.get_ref().get_ref().chars().last() != Some('\n') {
|
if !self.pending_input.get_ref().get_ref().ends_with('\n') {
|
||||||
*self.pending_input.get_mut().get_mut() += "\n";
|
*self.pending_input.get_mut().get_mut() += "\n";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -292,9 +292,9 @@ impl CharRead for ReadlineStream {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn write_term_to_heap<'a, 'b>(
|
pub(crate) fn write_term_to_heap(
|
||||||
term: &'a Term,
|
term: &Term,
|
||||||
heap: &'b mut Heap,
|
heap: &mut Heap,
|
||||||
atom_tbl: &AtomTable,
|
atom_tbl: &AtomTable,
|
||||||
) -> Result<TermWriteResult, CompilationError> {
|
) -> Result<TermWriteResult, CompilationError> {
|
||||||
let term_writer = TermWriter::new(heap, atom_tbl);
|
let term_writer = TermWriter::new(heap, atom_tbl);
|
||||||
@@ -347,7 +347,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
match term {
|
match term {
|
||||||
&TermRef::Cons(..) => list_loc_as_cell!(h),
|
&TermRef::Cons(..) => list_loc_as_cell!(h),
|
||||||
&TermRef::AnonVar(_) | &TermRef::Var(..) => heap_loc_as_cell!(h),
|
&TermRef::AnonVar(_) | &TermRef::Var(..) => heap_loc_as_cell!(h),
|
||||||
&TermRef::CompleteString(_, _, ref src) => {
|
TermRef::CompleteString(_, _, src) => {
|
||||||
if src.as_str().is_empty() {
|
if src.as_str().is_empty() {
|
||||||
empty_list_as_cell!()
|
empty_list_as_cell!()
|
||||||
} else if self.heap[h].get_tag() == HeapCellValueTag::CStr {
|
} else if self.heap[h].get_tag() == HeapCellValueTag::CStr {
|
||||||
@@ -358,7 +358,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
}
|
}
|
||||||
&TermRef::PartialString(..) => pstr_loc_as_cell!(h),
|
&TermRef::PartialString(..) => pstr_loc_as_cell!(h),
|
||||||
&TermRef::Literal(_, _, literal) => HeapCellValue::from(*literal),
|
&TermRef::Literal(_, _, literal) => HeapCellValue::from(*literal),
|
||||||
&TermRef::Clause(_, _, _, subterms) if subterms.len() == 0 => heap_loc_as_cell!(h),
|
&TermRef::Clause(_, _, _, subterms) if subterms.is_empty() => heap_loc_as_cell!(h),
|
||||||
&TermRef::Clause(..) => str_loc_as_cell!(h),
|
&TermRef::Clause(..) => str_loc_as_cell!(h),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -390,7 +390,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
return Err(CompilationError::ExceededMaxArity);
|
return Err(CompilationError::ExceededMaxArity);
|
||||||
}
|
}
|
||||||
|
|
||||||
self.heap.push(if subterms.len() == 0 {
|
self.heap.push(if subterms.is_empty() {
|
||||||
heap_loc_as_cell!(heap_loc + 1)
|
heap_loc_as_cell!(heap_loc + 1)
|
||||||
} else {
|
} else {
|
||||||
str_loc_as_cell!(heap_loc + 1)
|
str_loc_as_cell!(heap_loc + 1)
|
||||||
@@ -438,11 +438,11 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
|
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
&TermRef::CompleteString(_, _, ref src) => {
|
TermRef::CompleteString(_, _, src) => {
|
||||||
let src = src.as_str().to_owned();
|
let src = src.as_str().to_owned();
|
||||||
put_complete_string(self.heap, &src, self.atom_tbl);
|
put_complete_string(self.heap, &src, self.atom_tbl);
|
||||||
}
|
}
|
||||||
&TermRef::PartialString(lvl, _, ref src, _) => {
|
&TermRef::PartialString(lvl, _, src, _) => {
|
||||||
if let Level::Root = lvl {
|
if let Level::Root = lvl {
|
||||||
// Var tags can't refer directly to partial strings,
|
// Var tags can't refer directly to partial strings,
|
||||||
// so a PStrLoc cell must be pushed.
|
// so a PStrLoc cell must be pushed.
|
||||||
@@ -458,7 +458,7 @@ impl<'a, 'b> TermWriter<'a, 'b> {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
&TermRef::Var(.., ref var) => {
|
TermRef::Var(.., var) => {
|
||||||
if let Some((arity, site_h)) = self.queue.pop_front() {
|
if let Some((arity, site_h)) = self.queue.pop_front() {
|
||||||
let var_key = VarKey::VarPtr(var.clone());
|
let var_key = VarKey::VarPtr(var.clone());
|
||||||
|
|
||||||
|
|||||||
@@ -64,10 +64,7 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_void_instr(instr: &Instruction) -> bool {
|
fn is_void_instr(instr: &Instruction) -> bool {
|
||||||
match instr {
|
matches!(instr, &Instruction::UnifyVoid(_))
|
||||||
&Instruction::UnifyVoid(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
fn to_pstr(lvl: Level, string: Atom, r: RegType, has_tail: bool) -> Instruction {
|
||||||
@@ -75,9 +72,8 @@ impl<'a> CompilationTarget<'a> for FactInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn incr_void_instr(instr: &mut Instruction) {
|
fn incr_void_instr(instr: &mut Instruction) {
|
||||||
match instr {
|
if let &mut Instruction::UnifyVoid(ref mut incr) = instr {
|
||||||
&mut Instruction::UnifyVoid(ref mut incr) => *incr += 1,
|
*incr += 1
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,16 +142,12 @@ impl<'a> CompilationTarget<'a> for QueryInstruction {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn is_void_instr(instr: &Instruction) -> bool {
|
fn is_void_instr(instr: &Instruction) -> bool {
|
||||||
match instr {
|
matches!(instr, &Instruction::SetVoid(_))
|
||||||
&Instruction::SetVoid(_) => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn incr_void_instr(instr: &mut Instruction) {
|
fn incr_void_instr(instr: &mut Instruction) {
|
||||||
match instr {
|
if let &mut Instruction::SetVoid(ref mut incr) = instr {
|
||||||
&mut Instruction::SetVoid(ref mut incr) => *incr += 1,
|
*incr += 1
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
30
src/types.rs
30
src/types.rs
@@ -194,6 +194,7 @@ pub enum TrailRef {
|
|||||||
BlackboardOffset(Atom, HeapCellValue), // key atom, key value
|
BlackboardOffset(Atom, HeapCellValue), // key atom, key value
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[allow(clippy::enum_variant_names)]
|
||||||
#[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
#[derive(BitfieldSpecifier, Copy, Clone, Debug, PartialEq, Eq, PartialOrd, Ord)]
|
||||||
#[bits = 6]
|
#[bits = 6]
|
||||||
pub(crate) enum TrailEntryTag {
|
pub(crate) enum TrailEntryTag {
|
||||||
@@ -331,7 +332,7 @@ impl From<ConsPtr> for HeapCellValue {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<'a> From<(Number, &mut Arena)> for HeapCellValue {
|
impl From<(Number, &mut Arena)> for HeapCellValue {
|
||||||
#[inline(always)]
|
#[inline(always)]
|
||||||
fn from((n, arena): (Number, &mut Arena)) -> HeapCellValue {
|
fn from((n, arena): (Number, &mut Arena)) -> HeapCellValue {
|
||||||
use ordered_float::OrderedFloat;
|
use ordered_float::OrderedFloat;
|
||||||
@@ -393,16 +394,16 @@ impl HeapCellValue {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn is_ref(self) -> bool {
|
pub fn is_ref(self) -> bool {
|
||||||
match self.get_tag() {
|
matches!(
|
||||||
|
self.get_tag(),
|
||||||
HeapCellValueTag::Str
|
HeapCellValueTag::Str
|
||||||
| HeapCellValueTag::Lis
|
| HeapCellValueTag::Lis
|
||||||
| HeapCellValueTag::Var
|
| HeapCellValueTag::Var
|
||||||
| HeapCellValueTag::StackVar
|
| HeapCellValueTag::StackVar
|
||||||
| HeapCellValueTag::AttrVar
|
| HeapCellValueTag::AttrVar
|
||||||
| HeapCellValueTag::PStrLoc
|
| HeapCellValueTag::PStrLoc
|
||||||
| HeapCellValueTag::PStrOffset => true,
|
| HeapCellValueTag::PStrOffset
|
||||||
_ => false,
|
)
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -491,7 +492,7 @@ impl HeapCellValue {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn get_value(self) -> u64 {
|
pub fn get_value(self) -> u64 {
|
||||||
self.val() as u64
|
self.val()
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -739,10 +740,7 @@ impl UntypedArenaPtr {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub fn payload_offset(self) -> *const u8 {
|
pub fn payload_offset(self) -> *const u8 {
|
||||||
unsafe {
|
unsafe { self.get_ptr().add(mem::size_of::<ArenaHeader>()) }
|
||||||
self.get_ptr()
|
|
||||||
.offset(mem::size_of::<ArenaHeader>() as isize)
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
@@ -806,7 +804,7 @@ impl Sub<i64> for HeapCellValue {
|
|||||||
| tag @ HeapCellValueTag::PStrLoc
|
| tag @ HeapCellValueTag::PStrLoc
|
||||||
| tag @ HeapCellValueTag::Var
|
| tag @ HeapCellValueTag::Var
|
||||||
| tag @ HeapCellValueTag::AttrVar => {
|
| tag @ HeapCellValueTag::AttrVar => {
|
||||||
HeapCellValue::build_with(tag, self.get_value() + rhs.abs() as u64)
|
HeapCellValue::build_with(tag, self.get_value() + rhs.unsigned_abs())
|
||||||
}
|
}
|
||||||
_ => self,
|
_ => self,
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -74,10 +74,7 @@ impl PermVarAllocation {
|
|||||||
|
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn pending(&self) -> bool {
|
pub(crate) fn pending(&self) -> bool {
|
||||||
match self {
|
matches!(self, &PermVarAllocation::Pending)
|
||||||
&PermVarAllocation::Pending => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -96,9 +93,9 @@ pub enum VarAlloc {
|
|||||||
impl VarAlloc {
|
impl VarAlloc {
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn as_reg_type(&self) -> RegType {
|
pub(crate) fn as_reg_type(&self) -> RegType {
|
||||||
match self {
|
match *self {
|
||||||
&VarAlloc::Temp { temp_reg, .. } => RegType::Temp(temp_reg),
|
VarAlloc::Temp { temp_reg, .. } => RegType::Temp(temp_reg),
|
||||||
&VarAlloc::Perm(r, _) => RegType::Perm(r),
|
VarAlloc::Perm(r, _) => RegType::Perm(r),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -129,7 +126,7 @@ impl TempVarData {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
false
|
||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn populate_conflict_set(&mut self) {
|
pub(crate) fn populate_conflict_set(&mut self) {
|
||||||
@@ -201,16 +198,13 @@ impl VariableRecords {
|
|||||||
IndexMap::new();
|
IndexMap::new();
|
||||||
|
|
||||||
for (var_gen_index, record) in self.0.iter_mut().enumerate() {
|
for (var_gen_index, record) in self.0.iter_mut().enumerate() {
|
||||||
match &mut record.allocation {
|
if let VarAlloc::Temp { temp_var_data, .. } = &mut record.allocation {
|
||||||
VarAlloc::Temp { temp_var_data, .. } => {
|
let use_set = std::mem::replace(
|
||||||
let use_set = std::mem::replace(
|
&mut temp_var_data.use_set,
|
||||||
&mut temp_var_data.use_set,
|
IndexSet::with_hasher(FxBuildHasher::default()),
|
||||||
IndexSet::with_hasher(FxBuildHasher::default()),
|
);
|
||||||
);
|
|
||||||
|
|
||||||
use_sets.insert(var_gen_index, use_set);
|
use_sets.insert(var_gen_index, use_set);
|
||||||
}
|
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -219,19 +213,18 @@ impl VariableRecords {
|
|||||||
for &(term_loc, reg) in &use_set {
|
for &(term_loc, reg) in &use_set {
|
||||||
if let GenContext::Last(cn_u) = term_loc {
|
if let GenContext::Last(cn_u) = term_loc {
|
||||||
for (var_gen_index, record) in self.0.iter_mut().enumerate() {
|
for (var_gen_index, record) in self.0.iter_mut().enumerate() {
|
||||||
match &mut record.allocation {
|
if let VarAlloc::Temp {
|
||||||
VarAlloc::Temp {
|
term_loc,
|
||||||
term_loc,
|
temp_var_data,
|
||||||
temp_var_data,
|
..
|
||||||
..
|
} = &mut record.allocation
|
||||||
} => {
|
{
|
||||||
if cn_u == term_loc.chunk_num() && u != var_gen_index {
|
if cn_u == term_loc.chunk_num()
|
||||||
if !temp_var_data.uses_reg(reg) {
|
&& u != var_gen_index
|
||||||
temp_var_data.no_use_set.insert(reg);
|
&& !temp_var_data.uses_reg(reg)
|
||||||
}
|
{
|
||||||
}
|
temp_var_data.no_use_set.insert(reg);
|
||||||
}
|
}
|
||||||
_ => {}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -69,7 +69,7 @@ fn handle_residual_goal() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn occurs_check_flag() {
|
fn occurs_check_flag() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["tests-pl/issue841-occurs-check.pl"],
|
["tests-pl/issue841-occurs-check.pl"],
|
||||||
"\
|
"\
|
||||||
f(X, X).\n\
|
f(X, X).\n\
|
||||||
halt.\n\
|
halt.\n\
|
||||||
@@ -102,14 +102,14 @@ fn occurs_check_flag2() {
|
|||||||
// issue #839
|
// issue #839
|
||||||
#[test]
|
#[test]
|
||||||
fn op3() {
|
fn op3() {
|
||||||
run_top_level_test_with_args(&["tests-pl/issue839-op3.pl", "-g", "halt"], "", "")
|
run_top_level_test_with_args(["tests-pl/issue839-op3.pl", "-g", "halt"], "", "")
|
||||||
}
|
}
|
||||||
|
|
||||||
// issue #820
|
// issue #820
|
||||||
#[test]
|
#[test]
|
||||||
fn multiple_goals() {
|
fn multiple_goals() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["-g", "test", "-g", "halt", "tests-pl/issue820-goals.pl"],
|
["-g", "test", "-g", "halt", "tests-pl/issue820-goals.pl"],
|
||||||
"",
|
"",
|
||||||
"helloworld\n",
|
"helloworld\n",
|
||||||
);
|
);
|
||||||
@@ -119,7 +119,7 @@ fn multiple_goals() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn compound_goal() {
|
fn compound_goal() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["-g", "test,halt", "tests-pl/issue820-goals.pl"],
|
["-g", "test,halt", "tests-pl/issue820-goals.pl"],
|
||||||
"",
|
"",
|
||||||
"helloworld\n",
|
"helloworld\n",
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ fn setup_call_cleanup_load() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn setup_call_cleanup_process() {
|
fn setup_call_cleanup_process() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["src/tests/setup_call_cleanup.pl", "-f", "-g", "halt"],
|
["src/tests/setup_call_cleanup.pl", "-f", "-g", "halt"],
|
||||||
"",
|
"",
|
||||||
"1+21+31+2>A+B1+G1+2>41+2>B1+2>31+2>31+2>4ba",
|
"1+21+31+2>A+B1+G1+2>41+2>B1+2>31+2>31+2>4ba",
|
||||||
);
|
);
|
||||||
@@ -79,7 +79,7 @@ fn iso_conformity_tests() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn dif_tests() {
|
fn dif_tests() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["src/tests/dif.pl", "-f", "-g", "main_quiet"],
|
["src/tests/dif.pl", "-f", "-g", "main_quiet"],
|
||||||
"",
|
"",
|
||||||
"All tests passed",
|
"All tests passed",
|
||||||
);
|
);
|
||||||
@@ -88,7 +88,7 @@ fn dif_tests() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn ground_tests() {
|
fn ground_tests() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["src/tests/ground.pl", "-f", "-g", "main_quiet"],
|
["src/tests/ground.pl", "-f", "-g", "main_quiet"],
|
||||||
"",
|
"",
|
||||||
"All tests passed",
|
"All tests passed",
|
||||||
);
|
);
|
||||||
@@ -97,7 +97,7 @@ fn ground_tests() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn term_variables_tests() {
|
fn term_variables_tests() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["src/tests/term_variables.pl", "-f", "-g", "main_quiet"],
|
["src/tests/term_variables.pl", "-f", "-g", "main_quiet"],
|
||||||
"",
|
"",
|
||||||
"All tests passed",
|
"All tests passed",
|
||||||
);
|
);
|
||||||
@@ -106,7 +106,7 @@ fn term_variables_tests() {
|
|||||||
#[test]
|
#[test]
|
||||||
fn acyclic_term_tests() {
|
fn acyclic_term_tests() {
|
||||||
run_top_level_test_with_args(
|
run_top_level_test_with_args(
|
||||||
&["src/tests/acyclic_term.pl", "-f", "-g", "main_quiet"],
|
["src/tests/acyclic_term.pl", "-f", "-g", "main_quiet"],
|
||||||
"",
|
"",
|
||||||
"All tests passed",
|
"All tests passed",
|
||||||
);
|
);
|
||||||
|
|||||||
Reference in New Issue
Block a user